Gps ublox NEO 6m:UBX命令健全性检查(使用Fletcher校验和!)
因此,我已经用头敲击键盘好几天了,因为我不知道如何让我的新GPS护罩与我的Teensy 3.1(Arduino兼容)微控制器配合使用 有问题的GPS屏蔽是由 使用TinyGPS Arduino库解析Teensy UART引脚上NEO 6 gps模块的输入数据,并将纬度和经度输出到Arduino IDE中的串行监视器,我没有遇到任何问题 当我试图向NEO 6发出NMEA命令或UBX命令时,问题就出现了。这是实际控制模块的唯一方法,而不是让它每秒发出相同的6条NMEA消息。(例如,如果不发出UBX RXM-PMREQ命令,则无法将模块设置为节能模式) 我一开始是基于,但没能让它起作用。因此,我制作了一个简单的小程序,它基本上完成以下功能:Gps ublox NEO 6m:UBX命令健全性检查(使用Fletcher校验和!),gps,arduino,checksum,nmea,Gps,Arduino,Checksum,Nmea,因此,我已经用头敲击键盘好几天了,因为我不知道如何让我的新GPS护罩与我的Teensy 3.1(Arduino兼容)微控制器配合使用 有问题的GPS屏蔽是由 使用TinyGPS Arduino库解析Teensy UART引脚上NEO 6 gps模块的输入数据,并将纬度和经度输出到Arduino IDE中的串行监视器,我没有遇到任何问题 当我试图向NEO 6发出NMEA命令或UBX命令时,问题就出现了。这是实际控制模块的唯一方法,而不是让它每秒发出相同的6条NMEA消息。(例如,如果不发出UBX
#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-------------------
我可以告诉你,disableGLL数据包是格式良好的。我正在发送准确的数据包,我收到了您期望的ACK数据包 因为您正在接收NMEA消息ok,我们可以排除RS232设置问题(波特率等) 我建议不要交错
序列。用GPS打印
语句。打印
和GPS。阅读
语句。如果有很多字符排队等待输出,则调用Serial.print
将被阻止,直到有更多的字符。当Serial.print
正在等待时,GPS模块仍会输入字符。最终,输入缓冲区将溢出。当Serial.print
返回时,您可能丢失了一些要读取的字符
从来自Arduino串行监视器的字节来看,似乎有8个字节被删除。请注意,预期的0x38是在初始0xB5之后的八个字节
尝试以下操作:在sendUBX
中,将的最后一个循环拆分为两个循环:
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(", ");
}
Serial.println();
Serial.flush(); // and wait until all debug messages have been sent
for(int i=0; i<(len+4); i++) {
GPS.write(fullPacket[i]);//Send a byte of the UBX data packet to the GPS unit
}
GPS.flush(); // wait until the packet has been sent
然后你就会知道你是否真的在0xB5之后得到了0x38。当然,逻辑分析仪、串行嗅探器,甚至示波器都可以告诉你线路上到底发生了什么
debug语句更改程序计时的情况并不少见,可能足以以意外的方式中断程序。在本例中,输入缓冲区溢出并丢弃字符。我对该代码也有同样的问题。我使用了Habduino代码,这与MAX8 GPS模块的代码差不多,但不同。必须检查Ublox NEO-6M的所有命令,看起来是一样的。但和你一样的问题
我通过打开uCenter解决了这个问题。而不是消息视图(F9),禁用所有NMEA和UBX(子)消息。我的默认设置是启用UBX-POSLLH消息。选择UBX-CFG-CFG,然后选择“发送”,将设置保存在UBX-CFG-CFG下
我不知道那个“硬件系列”图书馆;我把GPS挂在Arduino的硬件UART上(引脚0和1)。这意味着无需监控串行数据,但因此我使用了以下非常有用的技巧:
如果有人知道如何禁用NEO-6M的UBX消息,请告诉我。文件对我来说并不清楚。
谢谢 您的校验和计算有问题。校验和变量声明为uint32\u t,它们应声明为uint8\u t。或者,应在每次添加后对其进行遮盖,如下所示:
//Calculate checksum
for(int i=0; i<len; i++){
CK_A = CK_A + MSG[i];
CK_A &= 0xFF;
CK_B = CK_B + CK_A;
CK_B &= 0xFF;
Serial.println("CK_A= " + String(CK_A));
Serial.println("CK_B= " + String(CK_B));
}
//计算校验和
对于(int i=0;i@Justin),CS计算没有问题。请查看他提供的数据包,因为它们格式正确
使用32位CS变量可能是浪费,但它不会生成错误的校验和。他在计算结束时屏蔽了它们,在这两种情况下(发送和接收)
我已经用同一台ublox Neo-6M设备验证了这一点。我是(目前)可用的最快和最小的NMEA+UBX解析器的作者。我还在等待答案……有人有什么想法吗?你有没有想过?我也有同样的问题。。。
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(", ");
}
Serial.println();
Serial.flush(); // and wait until all debug messages have been sent
for(int i=0; i<(len+4); i++) {
GPS.write(fullPacket[i]);//Send a byte of the UBX data packet to the GPS unit
}
GPS.flush(); // wait until the packet has been sent
// Check that bytes arrive in sequence as per expected ACK packet
if (b == ackPacket[ackByteID]) {
ackByteID++;
Serial.print(b); // just output the bad byte
// Serial.print(b, HEX);
// Serial.print(", ");
// Check if message was not acknowledged
//Calculate checksum
for(int i=0; i<len; i++){
CK_A = CK_A + MSG[i];
CK_A &= 0xFF;
CK_B = CK_B + CK_A;
CK_B &= 0xFF;
Serial.println("CK_A= " + String(CK_A));
Serial.println("CK_B= " + String(CK_B));
}