So, I'm trying to read my TESEO LIV3FL GNSS module using I2C communication and STM32 Nucleo-WL55JC1. I can print the sensor log to my serial monitor perfectly. Here's the screenshot
$GNGSA,A,1,,,,,,,,,,,,,99.0,99.0,99.0*1E
$GPGLL,0745.76471,S,11023.30874,E,040509.000,V,N*58
$PSTMCPU,27.96,-1,98*49
$GPRMC,040510.000,V,0745.76471,S,11023.30874,E,,,061222,,,N*62
$GPGGA,040510.000,0745.76471,S,11023.30874,E,0,00,99.0,175.23,M,0.0,M,,*7E
$GPVTG,,T,,M,,N,,K,N*2C
$GNGSA,A,1,,,,,,,,,,,,,99.0,99.0,99.0*1E
$GNGSA,A,1,,,,,,,,,,,,,99.0,99.0,99.0*1E
$GPGLL,0745.76471,S,11023.30874,E,040510.000,V,N*50
$PSTMCPU,15.14,-1,98*42
.76471,S,11023.30874,E,,,061222,,,N*6A
$GPGGA,040509.000,0745.76471,S,11023.30874,E,0,00,99.0,175.23,M,0.0,M,,*76
$GPVTG,,T,,M,,N,,K,N*2C
$GNGSA,A,1,,,,,,,,,,,,,99.0,99.0,99.0*1E
$GNGSA,A,1,,,,,,,,,,,,,99.0,99.0,99.0*1E
$GPGLL,0745.76471,S,11023.30874,E,040509.000,V,N*58
$PSTMCPU,27.96,-1,98*49
$GPRMC,040510.000,V,0745.76471,S,11023.30874,E,,,061222,,,N*62
$GPGGA,040510.000,0745.76471,S,11023.30874,E,0,00,99.0,175.23,M,0.0,M,,*7E
$GPVTG,,T,,M,,N,,K,N*2C
$GNGSA,A,1,,,,,,,,,,,,,99.0,99.0,99.0*1E
$GNGSA,A,1,,,,,,,,,,,,,99.0,99.0,99.0*1E
$GPGLL,0745.76471,S,11023.30874,E,040510.000,V,N*50
However, when I tried to filter only GPGGA message only it filtered the wrong message. Here's the serial monitor output
$GNGSA,A,1,,,,,,,,,,,,,9GPGGA,040509.000,0745.76471,S,11023.30874,E,0,00,99.0,175.0,99.0,99.0*1E6
$GNGSA,A,1,,,,,,,,,,,,,9GPGGA,040509.000,0745.76471,S,11023.30874,E,0,00,99.0,175.0,99.0,99.0*1E6
Where it should be
GPGGA,040509.000,0745.76471,S,11023.30874,E,0,00,99.0,175.0,99.0,99.0*1E6
GPGGA,040509.000,0745.76471,S,11023.30874,E,0,00,99.0,175.0,99.0,99.0*1E6
Here's my variable declaration
uint8_t receivedData[1000];
uint8_t filteredMessage[1000];
char buff[1000];
char *ptr;
const char desiredNMEA[] = "$GPGGA";
And my infinite loop
while (1)
{
// Start reading data
ret = HAL_I2C_IsDeviceReady(&hi2c1, TESEO_LIV3FL_ADDRESS, 2, 10);
if (ret != HAL_OK) {
sprintf((char*)buff, "Device is not ready \r\n");
} else {
ret = HAL_I2C_Master_Receive(&hi2c1, TESEO_LIV3FL_ADDRESS, receivedData, sizeof(receivedData), HAL_MAX_DELAY);
if (ret != HAL_OK) {
sprintf((char*)buff, "Error Rx \r\n");
}
}
ptr = strstr((char*)receivedData, desiredNMEA);
if(ptr) {
int position = ptr - (char*)receivedData;
while((char*)receivedData[position] != '\n') {
filteredMessage[position] = filteredMessage[position];
position ;
}
filteredMessage[position] = '\0';
HAL_UART_Transmit(&huart2, filteredMessage, strlen((char*)filteredMessage), HAL_MAX_DELAY);
HAL_Delay(500);
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
Edit #2
Implemented Flexz's solution. The data still corrupted and truncated but we're getting somewhere
⸮⸮榦x>ZGPGGA,055223.070,0745.75895,S,11GPGGA,055232.000,0745.75895,S,11GPGGA,055237.000,0745.75895,S,11023.30466,E,0,00,99.0,167.95,M,0.0,M,,*7C
'⸮⸮<⸮
⸮b⸮
CodePudding user response:
Stm32 has nothing to do here, it's a bug in your code.
while((char*)receivedData[position] != '\n') {
filteredMessage[position] = filteredMessage[position];
position ;
}
Assigning the unassigned variable to itself? Of course it doesn't work.
And HAL_UART_Transmit
is a blocking call, there is no reason to insert a delay after it.
CodePudding user response:
The next problem is that you insert the part you want into the output buffer at the same position that it was at in the unfiltered buffer. You need to insert it into the output buffer starting at zero.