ublox NEO-6m: UBX-Befehl sanity-check (mit Fletcher-Prüfsumme!)
So, ich habe schlug meinen Kopf gegen meine Tastatur für ein paar Tage, weil ich kann nicht herausfinden, wie man meine neue GPS-shield zu spielen schön mit meinem Teensy 3.1 (Arduino-kompatiblen) microcontroller.
Dem GPS-shield in Frage iteaduino basiert, und kann hier eingesehen werden.
Ich habe keine Probleme mit der TinyGPS Arduino-Bibliothek zum Parsen von eingehenden Daten von dem NEO-6 gps-Modul auf der Teensy die UART-pins und Ausgabe von Längen-und Breitengrad an meinen seriellen monitor in der Arduino-IDE.
Entsteht das problem, wenn ich versuche die Ausgabe eines NMEA-Befehl oder eine UBX-Befehl, um die NEO-6. Dies ist der einzige Weg, um zu Steuern, das Modul, anstatt nur lassen es Brummen aus den gleichen 6 NMEA-Nachrichten pro Sekunde. (zum Beispiel, können Sie nicht setzen Sie das Modul in den power-save-Modus ohne Ausgabe eines UBX RXM-PMREQ Befehl).
Begann ich auf der Grundlage meiner-code auf der Beispiel bereitgestellt von ukhas, konnte Sie aber nicht bekommen, um zu arbeiten. Also habe ich ein einfaches kleines Programm, dass im Grunde genommen die folgenden:
- Legt die serielle Kommunikation zu NEO-6 Modul auf 9600 baud
- Sendet das GPS-Modul ein 11-byte-Daten-Paket folgt, dass UBX-Protokoll, sagen Sie zu stoppen senden von NMEA-lat/lon-Nachrichten
- Analysiert ankommende Datenpakete vom GPS-Modul auf der Suche nach einem ACK (Bestätigung) - Nachricht
Keine Bestätigung-Meldung kommt immer! Was mache ich falsch?!
Hier ist mein code:
#include <HardwareSerial.h>
#include <string.h>
#include <TinyGPS.h>
void gpsdump(TinyGPS &gps);
void printFloat(double f, int digits = 2);
HardwareSerial2 GPS= HardwareSerial2(); //Initialize harware serial object for the GPS unit
TinyGPS gps;
byte gps_set_sucess = 0 ;
//Pin Definitions
int GPS_RxPin= 9;
int GPS_TxPin=10;
//I/O variables
int GPSbaud = 9600;
int Serialbaud=19200;
int byteCount;
//----------------------------------GPS unit functions------------------------------------------------
//Send a byte array of UBX protocol to the GPS
void sendUBX(uint8_t *MSG, uint32_t len, long timeout=3000) {
uint32_t CK_A = 0, CK_B = 0;
uint8_t sum1=0x00, sum2=0x00;
uint8_t fullPacket[len+4];
for(int i=0; i<len; i++) {
fullPacket[i+2]=MSG[i];
}
Serial.println();
fullPacket[0]=0xB5;
fullPacket[1]= 0x62;
//Calculate checksum
for(int i=0; i<len; i++){
CK_A = CK_A + MSG[i];
CK_B = CK_B + CK_A;
Serial.println("CK_A= " + String(CK_A));
Serial.println("CK_B= " + String(CK_B));
}
sum1 = CK_A &0xff;//Mask the checksums to be one byte
sum2= CK_B &0xff;
fullPacket[len+2]=sum1; //Add the checksums to the end of the UBX packet
fullPacket[len+3]=sum2;
Serial.print("Checksum 1 premask= ");
Serial.println(CK_A,HEX);
Serial.print("Checksum 1 postmask= ");
Serial.println(sum1, HEX);
Serial.print("Checksum 2 premask= ");
Serial.println(CK_B,HEX);
Serial.print("Checksum 2 postmask= ");
Serial.println(sum2, HEX);
Serial.println("fullPacket is:");
for(int i=0; i<(len+4); i++) {
Serial.print(fullPacket[i],HEX);//Print out a byt of the UBX data packet to the serial monitor
Serial.print(", ");
GPS.write(fullPacket[i]);//Send a byte of the UBX data packet to the GPS unit
}
GPS.clear();
Serial.println();
}//end function
//Calculate expected UBX ACK packet and parse UBX response from GPS--------------------------
boolean getUBX_ACK(uint8_t *MSG, uint32_t len) {
uint8_t b;
uint8_t ackByteID = 0;
uint8_t ackPacket[10];
unsigned long startTime = millis();
uint32_t CK_A=0, CK_B=0;
boolean notAcknowledged=false;
Serial.print(" * Reading ACK response: ");
//Construct the expected ACK packet
ackPacket[0] = 0xB5; //header
ackPacket[1] = 0x62; //header
ackPacket[2] = 0x05; //class
ackPacket[3] = 0x01; //id
ackPacket[4] = 0x02; //length
ackPacket[5] = 0x00;
ackPacket[6] = MSG[0]; //MGS class
ackPacket[7] = MSG[1]; //MSG id
ackPacket[8] = 0; //CK_A
ackPacket[9] = 0; //CK_B
//Calculate the checksums
for (uint8_t i=2; i<8; i++) {
CK_A = CK_A + ackPacket[i];
CK_B= CK_B + CK_A;
}
ackPacket[8]= CK_A &0xff;//Mask the checksums to be one byte
ackPacket[9]= CK_B &0xff;
Serial.println("Searching for UBX ACK response:");
Serial.print("Target data packet: ");
for(int i =0; i<10; i++) {
Serial.print(ackPacket[i], HEX);
Serial.print(", ");
}
Serial.println();
Serial.print("Candidate packet: ");
while (1) {
//Test for success
if (ackByteID > 9) {
//All packets in order!
Serial.println(" (Response received from GPS unit:)");
if(notAcknowledged){
Serial.println("ACK-NAK!");
}
else{
Serial.println("ACK-ACK!");
return true;
}
}
//Timeout if no valid response in 5 seconds
if (millis() - startTime > 5000) {
Serial.println("<<<Response timed out!>>>");
return false;
}
//Make sure data is available to read
if (GPS.available()) {
b = GPS.read();
//Check that bytes arrive in sequence as per expected ACK packet
if (b == ackPacket[ackByteID]) {
ackByteID++;
Serial.print(b, HEX);
Serial.print(", ");
//Check if message was not acknowledged
if (ackByteID==3){
b=GPS.read();
if (b==0x00){
notAcknowledged=true;
ackByteID++;
}
}
}
else if(ackByteID>0){
ackByteID = 0; //Reset and look again, invalid order
Serial.print(b,HEX);
Serial.println(" -->NOPE!");
Serial.print("Candidate packet: ");
}
}
}//end while
}//end function
//--------SETUP------------------
void setup()
{
boolean gps_get_success=false;
delay(5000);//Give yourself time to open up the serial monitor
pinMode(GPS_TxPin,OUTPUT); //Define the UART transmission pin for ommunication with the GPS unit
pinMode(GPS_RxPin,INPUT); //Define the UART read pin for communication with the GPS unit
Serial.begin(Serialbaud); //Begin serial ommunication with Serial Monitor
Serial.println("Serial monitor operational");
GPS.begin(GPSbaud); //Begin serial communication with GPS unit
//Compile a UBX data packet to send to GPS - turn off GLL reporting
uint8_t disableGLL[] = {0x06, 0x01, 0x03, 0x00, 0xF0, 0x01, 0x00};
uint32_t len= sizeof(disableGLL)/sizeof(uint8_t);
Serial.println("Attempting to send UBX command to turn of GLL reporting");
Serial.println("Original message is " + String(len) + " bytes:");
for(int i=0; i<len; i++) {
Serial.print(disableGLL[i]);
Serial.print(", ");
}
Serial.println();
//Clear the communication buffer
while ( GPS.available())
{
char c = GPS.read();
}
sendUBX(disableGLL, len);
getUBX_ACK(disableGLL, len);
}
//--------MAIN LOOP-------MAIN LOOP-------MAIN LOOP-------MAIN LOOP-------MAIN LOOP-------MAIN LOOP--
void loop()
{
while ( GPS.available())
{
char c = GPS.read();
if(c==0xb5){Serial.println();}
Serial.print(c, HEX); //uncomment this line if you want to see the GPS data flowing
Serial.print(", ");
}
}//END LOOP-------------------
Ich bin mir nicht wirklich sicher, warum das GPS-Modul nicht reagiert auf meinen Befehl. Es beginnt zu scheinen unverschämt. Hier ist der serielle monitor-Ausgang:
Serial monitor operational
Attempting to send UBX command to turn of GLL reporting
Original message is 7 bytes:
6, 1, 3, 0, 240, 1, 0,
CK_A= 6
CK_B= 6
CK_A= 7
CK_B= 13
CK_A= 10
CK_B= 23
CK_A= 10
CK_B= 33
CK_A= 250
CK_B= 283
CK_A= 251
CK_B= 534
CK_A= 251
CK_B= 785
Checksum 1 premask= FB
Checksum 1 postmask= FB
Checksum 2 premask= 311
Checksum 2 postmask= 11
fullPacket is:
B5, 62, 6, 1, 3, 0, F0, 1, 0, FB, 11,
* Reading ACK response: Searching for UBX ACK response:
Target data packet: B5, 62, 5, 1, 2, 0, 6, 1, F, 38,
Candidate packet: B5, 38 -->NOPE!
Candidate packet: B5, CC -->NOPE!
Candidate packet: B5, 38 -->NOPE!
Candidate packet: <<<Response timed out!>>>
Und hier ist ein Beispiel für die raw-Bytes kommen über die UART (diese wurden an den arduino serial monitor)
B5, 38, 35, FC, 10, 40, A1, 59, 3C, 10, 1D, 3C, 30, 11, BD, 19, 90, 18, 10, 48, BD, 51, 39, 1C, 3C, 10, 39, 5D, BC, 91, 91, 59, 3D, B9, B1, B1, 10, D5, 3C, B0, 59, 3D, 3C, 10, 91, 3D, B8, BC, 90, 19, 38, BC, 10, 48, BD, 11, 1D, 1C, 38, 50, 39, 11, 1D, 18, 3C, 11, B9, 1D, 3D, 1, 17, 11, 59, BC, 3C, 10, 5D, 18, B8, 50, 9D, 31, AC, 42, 1D, 5C, 71, 98, B1, 3C, B, 99, 59, 8A, 39, 1, CD, 19, 59, A, BC, 18, 31, 9D, 9D, BC, 31, A5, 86, 94, 32, B1, 0, 85, 25, B1, A5, 1C, 8A, 30, 1, 10, 19, 59, 99, 1D, 38, 31, 63, 84, B, B8, 19, BD,
Haben Sie jemals herausfinden? Ich habe das gleiche problem...
InformationsquelleAutor macdonaldtomw | 2014-04-13
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gibt es ein problem mit der checksum Berechnung. Die Prüfsumme vars deklariert als uint32_t und Sie sollen erklärt werden als uint8_t. Alternativ sollten diese auch lieber abgeklebt werden, nach jeder Zugabe, wie folgt:
InformationsquelleAutor Justin
Ich kann Ihnen sagen, dass die disableGLL Paket ist gut gebildet. Ich schicke das genaue Paket, und ich bekomme Ihre erwartete ACK-Paket.
Weil Sie den Empfang der NMEA-Nachrichten ok, wir können Regel eine RS232-Einstellung problem (baud-rate, et al.).
Ich würde vorschlagen, nicht interleaving
Serial.print
Aussagen mitGPS.print
undGPS.read
Aussagen. Wenn viele Charaktere wurden in der Warteschlange für die Ausgabe aufrufenSerial.print
blockiert, bis das Zimmer mehr Zeichen. WährendSerial.print
wartet, werden die Zeichen kommen immer noch welche vom GPS-Modul. Schließlich, Ihre input-Puffer-überlauf. Durch die Zeit, dieSerial.print
zurückgibt, die Sie verloren haben können, einige der Zeichen zu Lesen.Aus den bytes aus dem Arduino Serial Monitor, es sieht aus wie acht bytes, die gelöscht wurden. Beachten Sie, wie die erwarteten 0x38 ist acht bytes, die nach dem ersten 0xB5.
Versuchen Sie dies: In
sendUBX
split der letztenfor
- loop in zwei Schleifen:Dann kommentieren Sie alle
Serial.print
Linien ingetUBX_ACK
. Sie könnten in der Lage sein zu lassenSerial.print
in:Dann wirst du wissen, wenn du wirklich eine 0x38 nach der 0xB5. Natürlich, ein Logik-Analyzer, Serial sniffer, oder sogar ein Oszilloskop könnte Ihnen sagen, was wirklich passiert auf der Leitung.
Es ist nicht ungewöhnlich für debug-Anweisungen zum ändern des timing des Programms, vielleicht genug, um es zu brechen in einer unerwarteten Art und Weise. In diesem Fall wird der Eingabe-Puffer-überläufe und Zeichen.
InformationsquelleAutor slash-dev
Ich hatte das gleiche problem mit dem code. Ich benutzte die Habduino-code, die Art der gleiche, aber als für die MAX8 GPS-Modul. Musste prüfen Sie alle Befehle für die Ublox NEO-6M, schien das gleiche zu sein. Aber das gleiche problem wie du hatte.
Ich löste es, indem das öffnen uCenter. Als message-Ansicht (F9), deaktivieren Sie alle NMEA und UBX (Kinder -) Nachrichten. Mir hatte eine UBX-POSLLH Nachricht aktivieren Sie als Standard. Speichern Sie die Einstellungen unter UBX-CFG-CFG, indem Sie UBX-CFG-CFG, und als Sie auf 'senden'.
Ich weiß nicht, ob 'HardwareSerial' library; hakte ich mein GPS auf dem hardware-UART vom Arduino-pins (0 und 1). Das bedeutet, dass keine Seriennummer zu überwachen, aber deshalb habe ich diesen sehr nützlichen trick:
http://ava.upuaut.net/?p=757
Wenn jemand weiß, eine Möglichkeit zum deaktivieren der UBX-Meldungen aus dem NEO-6M ist, lassen Sie es mich bitte wissen. Die Dokumentation ist nicht klar für mich.
Danke!
InformationsquelleAutor Tmatz
@Justin, es ist kein problem mit der CS-Berechnung. Bitte überprüfen Sie die Pakete, die er zur Verfügung gestellt, wie Sie wohlgeformt sind.
Verwendung von 32-bit-Variablen CS ist vielleicht verschwenderisch, aber es nicht erzeugen falsche Prüfsummen. Er Masken, die Sie am Ende der Berechnung in beiden Fällen (senden und empfangen).
Ich habe überprüft dies mit der gleichen ublox Neo-6M-Gerät. Ich bin der Autor von den (derzeit) Schnellste und kleinste NMEA+UBX-parser verfügbar ist, NeoGPS.
InformationsquelleAutor slash-dev