Home > database >  STM32 message filtering didn't work as expected
STM32 message filtering didn't work as expected

Time:12-06

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 */
  }

Here's for the enter image description here

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.

  • Related