@@ -158,6 +158,15 @@ boolean SFE_UBLOX_GPS::checkUbloxSerial()
158
158
// Take a given byte and file it into the proper array
159
159
void SFE_UBLOX_GPS::process (uint8_t incoming)
160
160
{
161
+
162
+ #ifdef DEBUG
163
+ // if (currentSentence == NONE && incoming == 0xB5) //UBX binary frames start with 0xB5, aka μ
164
+ // debug.println(); //Show new packet start
165
+
166
+ // debug.print(" ");
167
+ // debug.print(incoming, HEX);
168
+ #endif
169
+
161
170
if (currentSentence == NONE || currentSentence == NMEA)
162
171
{
163
172
if (incoming == 0xB5 ) // UBX binary frames start with 0xB5, aka μ
@@ -196,26 +205,23 @@ void SFE_UBLOX_GPS::process(uint8_t incoming)
196
205
currentSentence = NONE; // Something went wrong. Reset.
197
206
else if (ubxFrameCounter == 2 ) // Class
198
207
{
208
+ packetAck.counter = 0 ;
209
+ packetAck.valid = false ;
210
+ packetCfg.counter = 0 ;
211
+ packetCfg.valid = false ;
212
+
199
213
// We can now identify the type of response
200
214
if (incoming == UBX_CLASS_ACK)
201
- {
202
215
ubxFrameClass = CLASS_ACK;
203
- packetAck.counter = 0 ;
204
- packetAck.valid = false ;
205
- }
206
216
else
207
- {
208
217
ubxFrameClass = CLASS_NOT_AN_ACK;
209
- packetCfg.counter = 0 ;
210
- packetCfg.valid = false ;
211
- }
212
218
}
213
219
214
220
ubxFrameCounter++;
215
221
216
222
// Depending on this frame's class, pass different structs and payload arrays
217
223
if (ubxFrameClass == CLASS_ACK)
218
- processUBX (incoming, &packetAck);
224
+ processUBX (incoming, &packetAck);
219
225
else if (ubxFrameClass == CLASS_NOT_AN_ACK)
220
226
processUBX (incoming, &packetCfg);
221
227
}
@@ -343,8 +349,8 @@ void SFE_UBLOX_GPS::processUBX(uint8_t incoming, ubxPacket *incomingUBX)
343
349
if (incomingUBX->checksumA == rollingChecksumA && incomingUBX->checksumB == rollingChecksumB)
344
350
{
345
351
#ifdef DEBUG
346
- debug.println ( " Checksum/Frame Good " );
347
- // printFrame (incomingUBX);
352
+ debug.print ( " Received: " );
353
+ printPacket (incomingUBX);
348
354
#endif
349
355
incomingUBX->valid = true ;
350
356
processUBXpacket (incomingUBX); // We've got a valid packet, now do something with it
@@ -404,6 +410,11 @@ boolean SFE_UBLOX_GPS::sendCommand(ubxPacket outgoingUBX, uint16_t maxWait)
404
410
405
411
calcChecksum (&outgoingUBX); // Sets checksum A and B bytes of the packet
406
412
413
+ #ifdef DEBUG
414
+ debug.print (" Sending: " );
415
+ printPacket (&outgoingUBX);
416
+ #endif
417
+
407
418
// Point at 0xFF data register
408
419
_i2cPort->beginTransmission ((uint8_t )_gpsI2Caddress); // There is no register to write to, we just begin writing data bytes
409
420
_i2cPort->write (0xFF );
@@ -508,8 +519,32 @@ void SFE_UBLOX_GPS::addToChecksum(uint8_t incoming)
508
519
rollingChecksumB += rollingChecksumA;
509
520
}
510
521
522
+ // Pretty prints the current ubxPacket
523
+ void SFE_UBLOX_GPS::printPacket (ubxPacket *packet)
524
+ {
525
+ debug.print (" CLS:" );
526
+ debug.print (packet->cls , HEX);
527
+
528
+ debug.print (" ID:" );
529
+ debug.print (packet->id , HEX);
530
+
531
+ // debug.print(" Len: 0x");
532
+ // debug.print(packet->len, HEX);
533
+
534
+ debug.print (" Payload:" );
535
+
536
+ for (int x = 0 ; x < packet->len ; x++)
537
+ {
538
+ debug.print (" " );
539
+ debug.print (packet->payload [x], HEX);
540
+ }
541
+ debug.println ();
542
+ }
543
+
544
+
545
+ // =-=-=-=-=-=-=-= Specific commands =-=-=-=-=-=-=-==-=-=-=-=-=-=-=
546
+ // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
511
547
512
- // =-=-=-=-=-=-=-= Specific commands =-=-=-=-=-=-=-=
513
548
514
549
// Poll the module until and ack is received
515
550
boolean SFE_UBLOX_GPS::waitForResponse (uint16_t maxTime)
@@ -522,10 +557,8 @@ boolean SFE_UBLOX_GPS::waitForResponse(uint16_t maxTime)
522
557
{
523
558
checkUblox (); // See if new data is available. Process bytes as they come in.
524
559
525
- // If the packet we just sent was a CFG packet then we'll get an ACK
526
- // If the packet we just sent was a NAV packet then we'll just get data back
527
- if (commandAck == true ) return (true );
528
- if (packetCfg.valid == true ) return (true );
560
+ if (commandAck == true ) return (true ); // If the packet we just sent was a CFG packet then we'll get an ACK
561
+ if (packetCfg.valid == true ) return (true ); // If the packet we just sent was a NAV packet then we'll just get data back
529
562
}
530
563
531
564
#ifdef DEBUG
@@ -535,6 +568,48 @@ boolean SFE_UBLOX_GPS::waitForResponse(uint16_t maxTime)
535
568
return (false );
536
569
}
537
570
571
+ // Given a key, return its value
572
+ // This is how the new Ublox modules are communicating, ie protocol v27 and above found on ZED-F9P
573
+ uint8_t SFE_UBLOX_GPS::getVal (uint16_t group, uint16_t id, uint8_t size, uint8_t layer, uint16_t maxWait)
574
+ {
575
+ packetCfg.cls = UBX_CLASS_CFG;
576
+ packetCfg.id = UBX_CFG_VALGET;
577
+ packetCfg.len = 4 + 4 *1 ; // Only one key at a time
578
+ packetCfg.startingSpot = 0 ;
579
+
580
+ // Clear packet payload
581
+ for (uint8_t x = 0 ; x < packetCfg.len ; x++)
582
+ packetCfg.payload [x] = 0 ;
583
+
584
+ payloadCfg[0 ] = 0 ; // Message Version - set to 0
585
+ payloadCfg[1 ] = layer;
586
+
587
+ // Create key
588
+ uint32_t key = 0 ;
589
+ key |= (uint32_t )id;
590
+ key |= (uint32_t )group << 16 ;
591
+ key |= (uint32_t )size << 28 ;
592
+
593
+ #ifdef DEBUG
594
+ Serial.print (" key: 0x" );
595
+ Serial.print (key, HEX);
596
+ Serial.println ();
597
+ #endif
598
+
599
+ // Load key into outgoing payload
600
+ payloadCfg[4 ] = key >> 8 *0 ; // Key LSB
601
+ payloadCfg[5 ] = key >> 8 *1 ;
602
+ payloadCfg[6 ] = key >> 8 *2 ;
603
+ payloadCfg[7 ] = key >> 8 *3 ;
604
+
605
+ // Send VALGET command with this key
606
+ if (sendCommand (packetCfg, maxWait) == false )
607
+ return (false ); // If command send fails then bail
608
+
609
+ // Pull the requested value from the response
610
+ return (extractByte (8 )); // Look for our response value at location 4+4*N
611
+ }
612
+
538
613
// Get the current TimeMode3 settings - these contain survey in statuses
539
614
boolean SFE_UBLOX_GPS::getSurveyMode (uint16_t maxWait)
540
615
{
@@ -672,7 +747,8 @@ boolean SFE_UBLOX_GPS::getPortSettings(uint8_t portID, uint16_t maxWait)
672
747
boolean SFE_UBLOX_GPS::setPortOutput (uint8_t portID, uint8_t outStreamSettings, uint16_t maxWait)
673
748
{
674
749
// Get the current config values for this port ID
675
- getPortSettings (portID); // This will load the payloadCfg array with current port settings
750
+ if (getPortSettings (portID) == false )
751
+ return (false ); // Something went wrong. Bail.
676
752
677
753
// Yes, this is the depreciated way to do it but it's still supported on v27 so it
678
754
// covers both ZED-F9P (v27) and SAM-M8Q (v18)
@@ -694,7 +770,9 @@ boolean SFE_UBLOX_GPS::setPortOutput(uint8_t portID, uint8_t outStreamSettings,
694
770
boolean SFE_UBLOX_GPS::setPortInput (uint8_t portID, uint8_t inStreamSettings, uint16_t maxWait)
695
771
{
696
772
// Get the current config values for this port ID
697
- getPortSettings (portID); // This will load the payloadCfg array with current port settings
773
+ // This will load the payloadCfg array with current port settings
774
+ if (getPortSettings (portID) == false )
775
+ return (false ); // Something went wrong. Bail.
698
776
699
777
packetCfg.cls = UBX_CLASS_CFG;
700
778
packetCfg.id = UBX_CFG_PRT;
@@ -745,6 +823,9 @@ boolean SFE_UBLOX_GPS::setNavigationFrequency(uint8_t navFreq, uint16_t maxWait)
745
823
if (sendCommand (packetCfg, maxWait) == false ) // This will load the payloadCfg array with current settings of the given register
746
824
return (false ); // If command send fails then bail
747
825
826
+ Serial.print (" Len: " );
827
+ Serial.print (packetCfg.len );
828
+
748
829
uint16_t measurementRate = 1000 / navFreq ;
749
830
750
831
// payloadCfg is now loaded with current bytes. Change only the ones we need to
@@ -754,6 +835,27 @@ boolean SFE_UBLOX_GPS::setNavigationFrequency(uint8_t navFreq, uint16_t maxWait)
754
835
return ( sendCommand (packetCfg, maxWait) );
755
836
}
756
837
838
+ // Get the rate at which the module is outputting nav solutions
839
+ uint8_t SFE_UBLOX_GPS::getNavigationFrequency (uint16_t maxWait)
840
+ {
841
+ // Query the module for the latest lat/long
842
+ packetCfg.cls = UBX_CLASS_CFG;
843
+ packetCfg.id = UBX_CFG_RATE;
844
+ packetCfg.len = 0 ;
845
+ packetCfg.startingSpot = 0 ;
846
+
847
+ if (sendCommand (packetCfg, maxWait) == false ) // This will load the payloadCfg array with current settings of the given register
848
+ return (0 ); // If command send fails then bail
849
+
850
+ uint16_t measurementRate = 0 ;
851
+
852
+ // payloadCfg is now loaded with current bytes. Get what we need
853
+ measurementRate = extractInt (0 ); // Pull from payloadCfg at measRate LSB
854
+
855
+ measurementRate = 1000 / measurementRate; // This may return an int when it's a float, but I'd rather not return 4 bytes
856
+ return (measurementRate);
857
+ }
858
+
757
859
// Given a spot in the payload array, extract four bytes and build a long
758
860
uint32_t SFE_UBLOX_GPS::extractLong (uint8_t spotToStart)
759
861
{
0 commit comments