I am trying to use an STM32 microcontroller (STM32L010C6T6 to be exact) to parse NMEA sentences from a GPS module over UART. I receive the messages fine, but run into issues when I look for specific strings within the messages.
I read in 700 characters from the GPS module over UART and store them in a buffer. I want to find a "GNGLL" sentence within the buffer. I use the C function strstr()
to search my buffer for the string "GNGLL" but the function never finds the string, even when it should be there. I print my buffer contents over a different UART to a serial terminal on my PC, and I've even used the "live expressions" debug feature of the STM32cubeide to verify that the string is there. Here is the relevant code.
#include "main.h"
#include <stdio.h>
#include <inttypes.h>
#include <string.h>
#include <math.h>
uint8_t gps_uartbuf[700] = {0};
char gps_uartbuf_char[700] = {'A'};
void getlatlon(char latlon[]){
char *mylat = NULL;
const char gps_gngll[5] = {'G','N','G','L','L'};
__HAL_UART_CLEAR_IT(&huart2, UART_CLEAR_NEF|UART_CLEAR_OREF);
HAL_UART_Receive(&huart2, gps_uartbuf, (uint16_t)700, 1000);
int x = 0;
for(x=0; x<700; x++){
gps_uartbuf_char[x] = (char)gps_uartbuf[x];
}
gps_uartbuf_char[699] = '0円';
mylat = strstr(gps_uartbuf_char, gps_gngll);
if(mylat == NULL){
//DID NOT FIND GPGLL
return;
}else{
//do stuff
}
}
Why is the strstr()
never finding the string?
-
\$\begingroup\$ I think this question should be migrated to Stack Overflow as it's only really related to programming, not electronics \$\endgroup\$ScottishTapWater– ScottishTapWater2022年07月18日 09:14:33 +00:00Commented Jul 18, 2022 at 9:14
-
2\$\begingroup\$ @ScottishTapWater - Hi, There is overlap between what is on-topic here and at SO. Firmware programming is on-topic here too. So while this could have been asked originally on SO, it is not off-topic here. As it has been answered here, and migration to SO is often unsuccessful (e.g. someone will find a dup on SO and reject the migration) I'm not going to migrate this one, on this occasion, but thanks for the comment. \$\endgroup\$SamGibson– SamGibson ♦2022年07月18日 09:25:05 +00:00Commented Jul 18, 2022 at 9:25
1 Answer 1
strstr
expects two zero-terminated strings as arguments, which isn't the case for the string containing the sequence of characters to match.
This string starts with a "GNGLL", but is followed by a number of unspecified characters. It's only terminated when a (virtually) random '0円' appears in this sequence.
Change your code as follows:
const char gps_gngll[] = {'G','N','G','L','L','0円'};
Or better yet:
const char gps_gngll[] = "GNGLL";
-
1\$\begingroup\$ That was it. As soon as I added the '0円' termination character it started working. \$\endgroup\$Nick– Nick2022年07月16日 19:13:59 +00:00Commented Jul 16, 2022 at 19:13
-
2\$\begingroup\$ @Nick: Just to restate the obvious, any null bytes in your buffer content can also cause
strstr
to fail (by stopping the search too early). If you may need to deal with those, you'll have to write your own search function (see e.g. this question on Stack Overflow) or use some nonstandard extension likememmem
from GCC. \$\endgroup\$Ilmari Karonen– Ilmari Karonen2022年07月17日 23:36:27 +00:00Commented Jul 17, 2022 at 23:36 -
1\$\begingroup\$ This is somewhat relevant - stackoverflow.com/a/1992271/1730895
memmem()
\$\endgroup\$Kingsley– Kingsley2022年07月18日 00:21:10 +00:00Commented Jul 18, 2022 at 0:21 -
\$\begingroup\$ @IlmariKaronen you make a very good point, but the specific case of GNSS is a (almost) human readable string, which should not contain any null character except for its own termination. I do see op initializing the buffer with a bunch of 'A' which is a bit confusing in my opinion. \$\endgroup\$Vladimir Cravero– Vladimir Cravero2022年07月18日 09:04:43 +00:00Commented Jul 18, 2022 at 9:04
Explore related questions
See similar questions with these tags.