Skip to main content
Associate II
February 26, 2025
Question

Extra character in UART RX buffer

  • February 26, 2025
  • 3 replies
  • 1808 views

I'm trying to receive data through USART1 using STM32F407. I decided to not use HAL api's to achieve that, so I'm receiving character by character and storing them in an array. Every character I send is received correctly but apart from the actual data I'm receiving an extra character in the first position of the buffer. It sometimes is a 'p' , sometimes a '\n' . I'm attaching some debug screenshots and a code snippet.

 

I enable the RX DR not empty interrupt:

 

 

__HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE);

 

 

 

My interrupt handler:

 

 

uint8_t group_input_str[250];
volatile uint32_t idx = 0;
void USART1_IRQHandler(void)
{
 /* USER CODE BEGIN USART1_IRQn 0 */
	if(__HAL_UART_GET_IT_SOURCE(&huart1,UART_IT_RXNE))
	{
			group_input_str[idx++] = huart1.Instance->DR;	
	}
	if(idx>=250) // prevent overflow
		idx=249;
 /* USER CODE END USART1_IRQn 0 */
 HAL_UART_IRQHandler(&huart1);
 /* USER CODE BEGIN USART1_IRQn 1 */
 /* USER CODE END USART1_IRQn 1 */
}

 

 

I sent a buffer containing help from the very begining, from another board(STM32F103),and the logic analiser caught :

BentoCopi_0-1740567758992.png

But on the debugger I got:

BentoCopi_1-1740567790782.png

UART configurations in both boards: 115200,8,N,1

I lowered down the baud rate, switched from HSE(8 MHz) to HSI, lowered down SYSCLK from 100MHz to 16MHz, but no success. What could be wrong?

3 replies

Andrew Neil
Super User
February 26, 2025

@BentoCopi wrote:

I send a buffer containing help from the very beginning, from another board (STM32F103)


That introduces a level of uncertainty.

So start by just sending individual characters from a terminal.

Examine your group_input_str RX buffer before you send the first character.

Examine it again after sending each character.

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
BentoCopiAuthor
Associate II
February 26, 2025

Strings sent from the terminal are received correctly, by the way. 

Andrew Neil
Super User
February 26, 2025

Which suggests that there's something wrong in your "other board", and/or the way you're using it.

How do you ensure that the receiving board is synchronised to the transmission?

Your LA trace suggests that the "other board" is actually sending a load of NULs - is that right?

If so, how many?

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
TDK
Super User
February 27, 2025

The bug is likely in a piece of code we're not seeing here.

The extra character is "p". Are you sending "help" somewhere in the code, perhaps during startup? If you change the message from "help..." to something else, does the extra character at the start remain a "p"?

If you are lost, you could put a hardware watchpoint on the first byte to see when it's changed.

Verify on your starting call to HAL_UART_Receive_IT that the buffer is empty.

"If you feel a post has answered your question, please click ""Accept as Solution""."
urbito
Senior II
February 27, 2025

Seeing his buffer, i remember having this kind of issues where the sender is just putting information non-stop in the buffer.

 

What i suggest is to create a "protocol" in top of UART, so when you get the IT, you see if the character you get is an 'h' and then you continue receiving it all.

 

Hope it helps.

Andrew Neil
Super User
February 27, 2025

@urbito wrote:

Seeing his buffer, i remember having this kind of issues where the sender is just putting information non-stop in the buffer..


Yes - exactly!

@BentoCopi this is what I'm talking about with synchronisation.

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Lead II
February 27, 2025

There several ways to achieve synchronization:

  1. Timing based. Bytes within a packet have a maximum allowed delay between them and packets have a minimum required delay between them. By using a receive timeout function you can detect if a packet is received. Most MCUs have some type of interrupt for this. Can be combined with DMA to write it to a buffer. You can use a circular buffer to constantly receive data.
  2. Software flow control or delimiter based. Use some type of delimiter character. If this character is in the data it needs to be escaped. If the escape character is in the data it needs to be escaped too. Receiving requires a finite state machine to detect start and end of messages. Can be combined with DMA to write it to a buffer. You can use a circular buffer to constantly receive data.
  3. Hardware flow control using extra datalines. RS232 has signals for this (CTS/RTS). I never used this.

It is also recommended to use some type of crc to check the integrity of the packet.

"Kudo posts if you have the same problem and kudo replies if the solution works.Click ""Accept as Solution"" if a reply solved your problem. If no solution was posted please answer with your own."
Andrew Neil
Super User
February 27, 2025

@unsigned_char_array wrote:

There several ways to achieve synchronization:


Indeed.

@BentoCopi  For a simple test case, it can just be done manually - as I've described - but you must have some way to ensure that your receiver & transmitter are "in-sync".

Otherwise, you will find that your receiver will start picking up at some random point within the message.

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.