Skip to main content
Dandrews
Associate
August 25, 2021
Solved

Having issues reading a UART string into a buffer, getting garbage data.

  • August 25, 2021
  • 6 replies
  • 1772 views

I am attempting to read a NEMA message from a GPS over UART.

Im expecting the message to be about 75 chars/bytes long.

Heres a sample of the data I'm seeing when using an ardunio for testing the GPS data out over UART.

$GNGGA,011112.00,3214.62073,N,05800.07397,W,2,12,1.14,22.0,M,-33.2,M,,0000*45

However when I use the code below I get a ton of junk data mixed in with good data.

HAL_UART_Receive_DMA(&huart1, &rxByte, 1);
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
 if(rxByte == 0x6e && rx_buff[rxIdx--] == 0x5c || rxIdx >= 73) {
 rx_buff[rxIdx] = rxByte;
 sprintf(statusBuf, "%s", rx_buff);
 CDC_Transmit_FS((uint8_t *) statusBuf, strlen(statusBuf));
 memset(statusBuf, 0, 128);
 rxFlag = 1;
 rxIdx = 0;
 }
 else {
 rx_buff[rxIdx] = rxByte;
 rxIdx++;
 }
 HAL_UART_Receive_DMA(&huart1, &rxByte, 1);
}

Example of the junk data being printed out

µb\ÿê®Õmˆ.òâÿÿ°dZ$GNGGA,023050.00,3214.87989,N,05800.08063,W,2,12,1.03,25.8,M,-3 0*49
µb\W,2,12,1.03,25.8,M,-33.2,M,,0000*4C
µb\œâÿÿ[d52.00,3214.87990,N,05800.08064,W,2,12,1.03,25.7,M,-33.2,M,,0000* ˜}ýå57%¦25.6,M,-33.2,M,,0000*47
µb\7993,N,05800.08056,W,2,12,0.98,25.4,M,-33.2,M,,0000*4F
µb\%,M,,0000*47
µb\.08061,W,2,12,0.98,25.3,M,-33.2,M,,0000*48
µb\®Õzˆ.“àÿÿQbGA,023057.00,3214.87996,N,05800.08062,W,2,12,0.98,25.2,M,-33.2,M 
µb\2,1.38,25.1,M,-33.2,M,,0000*4A
µb\Âa,3214.87994,N,05800.08062,W,2,12,1.32,25.0,M,-33.2,M,,0000*47
µ M,-33.2,M,,0000*46

Ideally I would like to read into the buffer until I see a \r\n and have a clean string I could split and parse.

I've tried using UART_IT, with a similar buffer method and ran into similar issues. Same with polling. However the data is clean and works great with other micros.

Im using an stm32f303c8t6.

This topic has been closed for replies.
Best answer by Tesla DeLorean

Should probably make sure rx_buff is properly NUL terminated before using string functions on it.

Also,you should resync the line at the '$', as you look to be getting uBlox UBX packets intermixed with your NMEA sentences.

rxByte >= 73 ?

6 replies

TDK
August 25, 2021

CDC_Transmit_FS doesn't always succeed. You need to ensure the USB is free.

CDC_Transmit_FS works in the background. You need to ensure the buffer is valid for as long as it takes. In your code, you immediately clear it.

A better method would be to set up a circular buffer and pop chars out of it as they come in via polling in the main loop. This method requires the micro to process a char and call HAL_UART_Receive_DMA before the start of the next character, which may not always happen.

"If you feel a post has answered your question, please click ""Accept as Solution""."
Dandrews
DandrewsAuthor
Associate
August 25, 2021

Good to know about CDC_Transmit_FS. I was unaware it was back-grounded, and thought I was clearing it after it had been sent off.

I'll give the circular buffer idea a try and see if I can not get more consistent data. Thanks!

Tesla DeLorean
Tesla DeLoreanBest answer
Guru
August 25, 2021

Should probably make sure rx_buff is properly NUL terminated before using string functions on it.

Also,you should resync the line at the '$', as you look to be getting uBlox UBX packets intermixed with your NMEA sentences.

rxByte >= 73 ?

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Dandrews
DandrewsAuthor
Associate
August 25, 2021

I have the rx_buff being set with a memset before my apps main while loop. And the rxByte >= 73 was a copy/paste mistake. I've edited that to have my current check for 5c 6e, or \n. The index >=73 was from an observation made on my known good data, every msg was exactly 73 chars. Tho I do know that will change some depending on message content.

Tesla DeLorean
Guru
August 25, 2021

Given the line lengths change the input code should put the NUL terminations on before sprintf() ing it.

Better yet just dispense with the sprintf(), and copy the buffer whose length you already know.

The receiver isn't sending the \r\n characters literally, it is sending them as 0x0D and 0x0A bytes, like $ is 0x24

0693W00000DqI9RQAV.jpg

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..