Skip to main content
Jakub B
Associate II
Oct 5, 2017 11:39 AM UTC
Solved

How to speed up usart communication?

Posted on October 05, 2017 at 13:39

The original post was too long to process during our migration. Please click on the attachment to read the original post.
    This topic has been closed for replies.
    Jakub B
    Jakub BBest answer
    Associate II
    Oct 6, 2017 1:09 PM UTC
    Posted on October 06, 2017 at 15:09

    After 3 days i found a solution (or walkabout) for future reference.

    /* Infinite loop */

      /* USER CODE BEGIN WHILE */

      while (1)

      {

            HAL_UART_Receive_DMA(&huart1, Received, 8); //start of listening

    HAL_Delay(1);

       

            if (ramka==1){

                //przekierowanie rozkazu do funkcji

                switch(bufor[1]){

                    case 4:{

                    stany(); break;

                    }

            }

        }

        ramka=0;

      /* USER CODE END WHILE */

    i found out that when i send every 1 second order by hand it sometimes miss one or more answers, but if i send it quicker for example 5 times a sec it works perfectly. I figured that maybe there is some problem with time of creating answer so if i put a delay just outside of interrupt it might work..

    And it did

    8 replies

    Tesla DeLorean
    Guru
    Oct 5, 2017 11:59 AM UTC
    Posted on October 05, 2017 at 13:59

    Wouldn't call HAL_UART_Receive_DMA() blindly in a tight loop

    ramka should be a volatile variable, also you don't clear it in the loop after processing the packet

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    AvaTar
    Senior III
    Oct 5, 2017 12:02 PM UTC
    Posted on October 05, 2017 at 14:02

    I would use a less EMI-prone standard, like RS485 or RS422.

    Your communication is package/message based, isn't it ?

    Why do you call the CRC2 function on every byte, from an interrupt context ?

    I have my problems understanding polish comments, though ...

    Jakub B
    Jakub BAuthor
    Associate II
    Oct 5, 2017 12:12 PM UTC
    Posted on October 05, 2017 at 14:12

    1. ramka is cleared in mail loop after checking packet. so i wait for order, check its crc if i should process it farther, then checking what it wants me to do and then clear.

    2. crc is calculated on 15/17 of final answer. last 2/17 are crc. I calculate it before sending answer in 2 parts. i copy part1 and move it to copy part2. Should i make a function for it outside of interrupt?

    Tesla DeLorean
    Guru
    Oct 5, 2017 4:44 PM UTC
    Posted on October 05, 2017 at 16:44

    >>ramka is cleared in mail loop after checking packet

    The placement seems to create a race condition, variable should be volatile.

    Enabling of DMA also seems problematic, and prone to synchronization issues.

    Try implementing with a simple USART IRQ method.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    Jakub B
    Jakub BAuthor
    Associate II
    Oct 6, 2017 8:08 AM UTC
    Posted on October 06, 2017 at 08:08

    >>The placement seems to create a race condition, variable should be volatile

    i'll try it

    >>Enabling of DMA also seems problematic, and prone to synchronization issues.

    with DMA i'm missing less  then without it, but issue is probably something else. I'll try changing it

    Jakub B
    Jakub BAuthor
    Associate II
    Oct 5, 2017 12:29 PM UTC
    Posted on October 05, 2017 at 14:29

    Can you tell me how to clear buffer with this:

    void

    TM_USART_ClearBuffer

    (

    USART_TypeDef

    *

    USARTx

    )

    ;

    maybe if i clear it after each recieve it will be enough?

    Jakub B
    Jakub BAuthorBest answer
    Associate II
    Oct 6, 2017 1:09 PM UTC
    Posted on October 06, 2017 at 15:09

    After 3 days i found a solution (or walkabout) for future reference.

    /* Infinite loop */

      /* USER CODE BEGIN WHILE */

      while (1)

      {

            HAL_UART_Receive_DMA(&huart1, Received, 8); //start of listening

    HAL_Delay(1);

       

            if (ramka==1){

                //przekierowanie rozkazu do funkcji

                switch(bufor[1]){

                    case 4:{

                    stany(); break;

                    }

            }

        }

        ramka=0;

      /* USER CODE END WHILE */

    i found out that when i send every 1 second order by hand it sometimes miss one or more answers, but if i send it quicker for example 5 times a sec it works perfectly. I figured that maybe there is some problem with time of creating answer so if i put a delay just outside of interrupt it might work..

    And it did

    AvaTar
    Senior III
    Oct 6, 2017 3:38 PM UTC
    Posted on October 06, 2017 at 15:38

    Polling with delay is possibly a workaround for Cube/HAL code, but still a bad solution.

    I would drop the Cube straitjacket alltogether and go for a clear interrupt-based solution, but it's not my project.

    I stopped commenting on Cube code a while ago ...