cancel
Showing results for 
Search instead for 
Did you mean: 

Receive data with unknown length via UART

Emm1592
Associate II

Hello, I'm using the STM32L476RG and trying to receive data via UART.

When I use the following code:

int main(void){

...

HAL_UART_Receive_IT(&huart4, data_RX,20);

....

}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){

printf("\nMessage received is: %s",data_RX);

}

This works just fine if ONLY the message received is 20 characters long.

But not if the message is for example 15. I know that when my data_Rx is full, it then will be printed.

I was wondering if anyone came across this problem and was successful implementing a solution. I tried some of the codes I found on the internet, but lot of them where really confusing.

Sorry if this topic was already discuss.

Any help would be awesome!

Thank you.

1 ACCEPTED SOLUTION

Accepted Solutions

Yes, sort of thing you can manage in a simple state machine in the interrupt handler as each character arrives.

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

View solution in original post

14 REPLIES 14
S.Ma
Principal

Well, you've got to use this function with 1 byte transfer which will push upper SW layer to handle the variable message length. I've used LL for USART and HAL for SPI (master/slave).

If I use the function with 1 byte:

int main(void){

...

HAL_UART_Receive_IT(&huart4, data_RX,1);

....

}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){

printf("\nMessage received is: %s",data_RX);

HAL_UART_Receive_IT(&huart4, data_RX,1);

}

The problem is that I'm getting random characters. I think that the process is so fast that it couldn't handle lot of bytes.

Can you show me some example code where you used LL with UART?

Sorry if I quite don't understand this yet. I'm trying hehe.

Thanks.

S.Ma
Principal

I have shared a code extract for USART + FIFO to plumb interrupt RX/TX with main loop or other peripheral interrupts. Have a look. The FIFO runs in the background: You don't have to "wait" the job is done, and the Interrupt is turned off when the FIFO is empty, turned on when no longer empty, to have a elegant consise source code. You'll be able to do your console or variable length decoding in the main loop by reading the fifo byte by byte, or even push USART data to SPI or other USART at different pace.

How do you handle the data? Can you determine the length by reviewing the data/packet structure, or do you need to see a gap in the data arrival?

The HAL implementation is a bit heavy handed, a cleaner approach is possible

https://community.st.com/s/feed/0D50X00009XkVxKSAV

Also be aware that with the HAL_UART_Receive_IT method will get an interrupt for each byte in the background, so you can do work in the IRQHandler, while the HAL callback to you only fires when the byte count is hit.

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

Hello,

The idea is to receive data of different lengths. For example, I get 20 bytes and then after an hour (or more) I get a message with 35 bytes and so on. Messages whose length varies.

I need to save that message in an array so that it can then be processed to perform corresponding actions with that information obtained.

I'm trying working with DMA but again I'm not getting the result I wanted.

It's a bit hard to be honest work with serial.

Thank you for your response Clive.

But does the data content infer the length, ie a packet header, or terminating <CR><LF> marker?

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

The message I receive is of the following style:

+ RCV = Transmitter_ID, Data_Length, Data, Received Signal Strength Indicator, Signal-to-noise ratio

Example:

+ RCV = 12.4, Hello,-67,45

at the end of the message +RCV.... it includes the terminating <CR> (0x0D) and <LF> (0x0A).

Maybe I need to design some kind of protocol to read and stock until CR+LF is reached?

Yes, sort of thing you can manage in a simple state machine in the interrupt handler as each character arrives.

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

I was able to implement a simple state machine, obtaining byte by byte. Later if anyone wants the code I will share it.

Regards.