cancel
Showing results for 
Search instead for 
Did you mean: 

Transmitted UART message mixed with other message

AFidi.1
Associate II

I'm trying to filter bunch of NMEA message

$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

The filter is kinda works since it only shows GPGGA message, but it corrupted and mixed with other message

⸮⸮榦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⸮

I was thinking this is because my transmitted buffer is mixed with the previous unfiltered buffer. If this is the case how can I clear my output buffer or insert my filtered buffer at the right (zero) position.

My variable declaration

uint8_t receivedData[1000];
uint8_t filteredMessage[1000];
 
char buff[1000];
char *ptr;
 
const char desiredNMEA[] = "GPGGA";
 
HAL_StatusTypeDef ret;

And here's 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");
		  }
	  }
 
//	  HAL_UART_Transmit(&huart2, receivedData, strlen((char*)receivedData), HAL_MAX_DELAY);
 
	  ptr = strstr((char*)receivedData, desiredNMEA);
 
	  if(ptr) {
		  int position = ptr - (char*)receivedData;
 
		  while((char*)receivedData[position] != '\n') {
			  filteredMessage[position] = receivedData[position];
			  position++;
		  }
 
		  filteredMessage[position] = '\0';
 
		  HAL_UART_Transmit(&huart2, filteredMessage, strlen((char*)filteredMessage), HAL_MAX_DELAY);
	  }
 
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  }

4 REPLIES 4
S.Ma
Principal

And is it a certainty that no incoming data when transmitting out? No buffer overflow on both parts?

I think there's an incoming data when transmitting out from the I2C since I use I2C to fetch the sensor data. How do I check for buffer overflow for the both parts?

S.Ma
Principal

There should be an overrun flag in usart hw register. Usually uart rx should be done with interrupts and run in the background so that when your sw grows, it won't start to misbehave much. It is a pity there is no provided fully functional uart example of console with interrupt and sw fifo.... pretty much covering large need spectrum. Use LL vs HAL for uart because console by definition uses variable length strings, which the HAL didn't foresee well.

This is my first time using STM32 so I'm kinda lost about this HAL and LL things. I tried this tutorial that I could find in the internet, but my DMA settings is different with the tutorial (in the tutorial it shows DMA stream but mine is DMA channel so I can't use the LL_DMA_EnableStream and LL_DMA_DisableStream

0693W00000WKP4uQAH.png

Edit 1

Used LL_USART_TransmitData8(USART2, receivedData); but now I only got bunch of H's :\

0693W00000WKPEfQAP.png