Closed brightproject closed 4 months ago
Better to ask a question in the comments of the video. I had this problem occasionally, I think it was because I had not disabled other messages. The code in my video only expects to receive one type of message.
etter to ask a question in the comments of the video.
There I asked the question first, but there were fears that the material was old and the question would get lost. Yes, and I have a lot of messages, in addition to the one I want to parse.
I'll try to turn off other messages and look at the parsing speed.
You could make a repository of your examples from YouTube
on Github
.
YouTube is still not exactly a platform for discussing code.
I modified the code in order not to spawn functions.
It displays two messages, but very, very slowly.
At the same time, the NEO-6M
module produces data with a frequency of 10Hz
.
#define SERIAL_BAUD 115200
#define GNSS_BAUD 9600
// #define POSLLH
#define VELNED
HardwareSerial Serial2(USART2); // PA2(TX2), PA3(RX2)
const unsigned char UBX_HEADER[] = {0xB5, 0x62};
struct NAV_POSLLH {
unsigned char cls;
unsigned char id;
unsigned short len;
unsigned long iTOW;
long lon;
long lat;
long height;
long hMSL;
unsigned long hAcc;
unsigned long vAcc;
} posllh;
struct NAV_VELNED {
unsigned char cls;
unsigned char id;
unsigned short len;
unsigned long iTOW; // U4
long velN; // I4
long velE;
long velD;
unsigned long speed;
unsigned long gSpeed;
long heading;
unsigned long sAcc;
unsigned long cAcc;
} velned;
void setup()
{
Serial.begin(SERIAL_BAUD);
Serial2.begin(GNSS_BAUD);
}
void loop() {
#ifdef POSLLH
bool GPS_POSLLH = processGPSData(sizeof(NAV_POSLLH), UBX_HEADER, &posllh);
if ( GPS_POSLLH ) {
Serial.print("iTOW:"); Serial.print(posllh.iTOW);
Serial.print(" lat/lon: "); Serial.print(posllh.lat/10000000.0f);
Serial.print(",");
Serial.print(posllh.lon/10000000.0f);
Serial.print(" height: "); Serial.print(posllh.height/1000.0f);
Serial.print(" hMSL: "); Serial.print(posllh.hMSL/1000.0f);
Serial.print(" hAcc: "); Serial.print(posllh.hAcc/1000.0f);
Serial.print(" vAcc: "); Serial.print(posllh.vAcc/1000.0f);
Serial.println();
}
#endif
#ifdef VELNED
bool GPS_VELNED = processGPSData(sizeof(NAV_VELNED), UBX_HEADER, &velned);
if ( GPS_VELNED ) {
Serial.print("iTOW: "); Serial.print(velned.iTOW); // GPS Millisecond Time of Week
Serial.print(" velN: "); Serial.print(velned.velN * 1e-2f); // m/s
Serial.print(" velE: "); Serial.print(velned.velE * 1e-2f); // m/s
Serial.print(" velD: "); Serial.print(velned.velD * 1e-2f); // m/s
Serial.print(" Spd (3D): "); Serial.print(velned.speed * 1e-2f); // m/s
Serial.print(" GndSpd (2D): "); Serial.print(velned.gSpeed * 1e-2f); // m/s
Serial.print(" Hdg (2D): "); Serial.print(velned.heading * 1e-5f); // same that divide on 100000.0f
Serial.print(" Spd Acc: "); Serial.print(velned.sAcc * 1e-2f);
Serial.print(" Crs/Hdg Acc: "); Serial.print(velned.cAcc/100000.0f);
Serial.println();
}
#endif
}
void calcChecksum(unsigned char* CK, const void* INIT, size_t size) {
memset(CK, 0, 2);
const unsigned char* data = (const unsigned char*)INIT;
for (size_t i = 0; i < size; i++) {
CK[0] += data[i];
CK[1] += CK[0];
}
}
bool processGPSData(const int payloadSize, const unsigned char* header, void* dataStruct) {
static int fpos = 0;
static unsigned char checksum[2];
while (Serial2.available() > 0) {
byte c = Serial2.read();
if (fpos < 2) {
if (c == header[fpos])
fpos++;
else
fpos = 0;
} else {
if ((fpos - 2) < payloadSize)
((unsigned char*)dataStruct)[fpos - 2] = c;
fpos++;
if (fpos == (payloadSize + 2)) {
calcChecksum(checksum, dataStruct, payloadSize);
} else if (fpos == (payloadSize + 3)) {
if (c != checksum[0])
fpos = 0;
} else if (fpos == (payloadSize + 4)) {
fpos = 0;
if (c == checksum[1]) {
return true;
}
} else if (fpos > (payloadSize + 4)) {
fpos = 0;
}
}
}
return false;
}
If compile code with
#define POSLLH
// #define VELNED
Output to serial is fast
iTOW:58672700 lat/lon: 49.51,8.76 height: 188.51 hMSL: 175.28 hAcc: 2.30 vAcc: 1.94
iTOW:58672800 lat/lon: 49.51,8.76 height: 188.51 hMSL: 175.29 hAcc: 2.30 vAcc: 1.94
iTOW:58672900 lat/lon: 49.51,8.76 height: 188.52 hMSL: 175.30 hAcc: 2.30 vAcc: 1.94
iTOW:58673000 lat/lon: 49.51,8.76 height: 188.54 hMSL: 175.31 hAcc: 2.30 vAcc: 1.94
If compile code with
// #define POSLLH
#define VELNED
Output to serial is very very slow
iTOW: 58712700 velN: 0.02 velE: -0.04 velD: -0.04 Spd (3D): 0.06 GndSpd (2D): 0.04 Hdg (2D): 133.72 Spd Acc: 0.26 Crs/Hdg Acc: 46.51
iTOW: 58729900 velN: 0.07 velE: -0.28 velD: -0.04 Spd (3D): 0.29 GndSpd (2D): 0.29 Hdg (2D): 281.74 Spd Acc: 0.46 Crs/Hdg Acc: 41.36
iTOW: 58751300 velN: 0.00 velE: 0.07 velD: -0.01 Spd (3D): 0.07 GndSpd (2D): 0.07 Hdg (2D): 99.11 Spd Acc: 0.32 Crs/Hdg Acc: 41.25
Output is spontaneous, once every 5 - 30 seconds.
As I said, the code in my video only expects to receive one type of message.
If the GPS module is outputting other messages, my code will start reading bytes in expecting them to be for the one message it knows about. This will result in the CRC check not matching, and the algorithm resets to waiting for the next 'µb' header marker. Depending on the length of your desired packet and the unrecognized ones, and how many unrecognized packet types are being output, most of the time that header marker will be for some other packet, and so the process repeats over and over. Once in a while, you get lucky and the packet you want will be detected.
I made a follow-up video where I showed how you could detect and use more than one type of packet: https://youtu.be/ylxwOg2pXrc?t=377
Hello @iforce2d I apologize in advance for disturbing you and for posting this
issue
off-topic, but I couldn’t find another way to contact you. I was interested in the parser from the video. I ran the example code on myGPS
receiverNEO-6M
with MCUstm32f411
. I was not able to set the frequency to10 Hz
, so I am content with the output once every1000 ms
(1 Hz). Data was sent to theserial
port, but the question immediately arose - why sometimes strange time with zerolat/lon
?Is this problem possible due to the low frequency of information output via
UART
from the module? I found information that seems to explain the problem, but I'm not sure. https://github.com/sparkfun/OpenLog_Artemis/issues/53 Regarding the issue of parsingVELNED
, I have much greater difficulties.Parsing code, based on your example below:
This code produces a result...but it happens once every
4 minutes
. You can look at the time difference between theiTOW
.Could you please clarify some of the issues I encountered? Sincerely!