@@ -158,6 +158,15 @@ boolean SFE_UBLOX_GPS::checkUbloxSerial()
158158// Take a given byte and file it into the proper array
159159void SFE_UBLOX_GPS::process (uint8_t incoming)
160160{
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+
161170 if (currentSentence == NONE || currentSentence == NMEA)
162171 {
163172 if (incoming == 0xB5 ) // UBX binary frames start with 0xB5, aka μ
@@ -196,26 +205,23 @@ void SFE_UBLOX_GPS::process(uint8_t incoming)
196205 currentSentence = NONE; // Something went wrong. Reset.
197206 else if (ubxFrameCounter == 2 ) // Class
198207 {
208+ packetAck.counter = 0 ;
209+ packetAck.valid = false ;
210+ packetCfg.counter = 0 ;
211+ packetCfg.valid = false ;
212+
199213 // We can now identify the type of response
200214 if (incoming == UBX_CLASS_ACK)
201- {
202215 ubxFrameClass = CLASS_ACK;
203- packetAck.counter = 0 ;
204- packetAck.valid = false ;
205- }
206216 else
207- {
208217 ubxFrameClass = CLASS_NOT_AN_ACK;
209- packetCfg.counter = 0 ;
210- packetCfg.valid = false ;
211- }
212218 }
213219
214220 ubxFrameCounter++;
215221
216222 // Depending on this frame's class, pass different structs and payload arrays
217223 if (ubxFrameClass == CLASS_ACK)
218- processUBX (incoming, &packetAck);
224+ processUBX (incoming, &packetAck);
219225 else if (ubxFrameClass == CLASS_NOT_AN_ACK)
220226 processUBX (incoming, &packetCfg);
221227 }
@@ -343,8 +349,8 @@ void SFE_UBLOX_GPS::processUBX(uint8_t incoming, ubxPacket *incomingUBX)
343349 if (incomingUBX->checksumA == rollingChecksumA && incomingUBX->checksumB == rollingChecksumB)
344350 {
345351#ifdef DEBUG
346- debug.println ( " Checksum/Frame Good " );
347- // printFrame (incomingUBX);
352+ debug.print ( " Received: " );
353+ printPacket (incomingUBX);
348354#endif
349355 incomingUBX->valid = true ;
350356 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)
404410
405411 calcChecksum (&outgoingUBX); // Sets checksum A and B bytes of the packet
406412
413+ #ifdef DEBUG
414+ debug.print (" Sending: " );
415+ printPacket (&outgoingUBX);
416+ #endif
417+
407418 // Point at 0xFF data register
408419 _i2cPort->beginTransmission ((uint8_t )_gpsI2Caddress); // There is no register to write to, we just begin writing data bytes
409420 _i2cPort->write (0xFF );
@@ -508,8 +519,32 @@ void SFE_UBLOX_GPS::addToChecksum(uint8_t incoming)
508519 rollingChecksumB += rollingChecksumA;
509520}
510521
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+ // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
511547
512- // =-=-=-=-=-=-=-= Specific commands =-=-=-=-=-=-=-=
513548
514549// Poll the module until and ack is received
515550boolean SFE_UBLOX_GPS::waitForResponse (uint16_t maxTime)
@@ -522,10 +557,8 @@ boolean SFE_UBLOX_GPS::waitForResponse(uint16_t maxTime)
522557 {
523558 checkUblox (); // See if new data is available. Process bytes as they come in.
524559
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
529562 }
530563
531564#ifdef DEBUG
@@ -535,6 +568,48 @@ boolean SFE_UBLOX_GPS::waitForResponse(uint16_t maxTime)
535568 return (false );
536569}
537570
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+
538613// Get the current TimeMode3 settings - these contain survey in statuses
539614boolean SFE_UBLOX_GPS::getSurveyMode (uint16_t maxWait)
540615{
@@ -672,7 +747,8 @@ boolean SFE_UBLOX_GPS::getPortSettings(uint8_t portID, uint16_t maxWait)
672747boolean SFE_UBLOX_GPS::setPortOutput (uint8_t portID, uint8_t outStreamSettings, uint16_t maxWait)
673748{
674749 // 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.
676752
677753 // Yes, this is the depreciated way to do it but it's still supported on v27 so it
678754 // covers both ZED-F9P (v27) and SAM-M8Q (v18)
@@ -694,7 +770,9 @@ boolean SFE_UBLOX_GPS::setPortOutput(uint8_t portID, uint8_t outStreamSettings,
694770boolean SFE_UBLOX_GPS::setPortInput (uint8_t portID, uint8_t inStreamSettings, uint16_t maxWait)
695771{
696772 // 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.
698776
699777 packetCfg.cls = UBX_CLASS_CFG;
700778 packetCfg.id = UBX_CFG_PRT;
@@ -745,6 +823,9 @@ boolean SFE_UBLOX_GPS::setNavigationFrequency(uint8_t navFreq, uint16_t maxWait)
745823 if (sendCommand (packetCfg, maxWait) == false ) // This will load the payloadCfg array with current settings of the given register
746824 return (false ); // If command send fails then bail
747825
826+ Serial.print (" Len: " );
827+ Serial.print (packetCfg.len );
828+
748829 uint16_t measurementRate = 1000 / navFreq ;
749830
750831 // 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)
754835 return ( sendCommand (packetCfg, maxWait) );
755836}
756837
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+
757859// Given a spot in the payload array, extract four bytes and build a long
758860uint32_t SFE_UBLOX_GPS::extractLong (uint8_t spotToStart)
759861{
0 commit comments