Skip to main content
Visitor II
January 19, 2019
Solved

Receive data with unknown length via UART

  • January 19, 2019
  • 4 replies
  • 8942 views

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.

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

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

    4 replies

    Visitor II
    January 19, 2019

    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).

    Emm1592Author
    Visitor II
    January 19, 2019

    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.

    Visitor II
    January 19, 2019

    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.

    Graduate II
    January 19, 2019

    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.

    Emm1592Author
    Visitor II
    January 19, 2019

    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.

    Graduate II
    January 19, 2019

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

    March 6, 2021

    @Emm1592​ could I get your code too,please? I am facing the same problem.