How to use scanf with USART

I’ve already posted how to use printf (send data to stream) on STM32Fxxx devices. Recently, I received a comment, how to use scanf function to read strings and convert them from USART. Here is a little bit more to do before it will work correct.

When you call scanf function, it calls subfunction fgetc, where you return a character. This function is called until it does not return EOF (-1). And it is called very fast. If you check in this function, if character is received from USART, then you return it, but because function is called faster than your USART data will be received, you will return EOF next time it is called and scanf function will detect we are done from receiving string, let’s convert string to desired formats. Technically, you will receive only one character maximum at a time to scanf function which is not correct.

To make it properly, you should write all characters received from USART to some temporary buffer (I suggest cyclic buffer) and when you call scanf, first check in function fgetc if there is end of string in your buffer. If it is, return the first character from buffer and do that until string delimiter is detected. When you detect string delimiter, return EOF.

scanf function will now wait for string delimiter received in buffer. When it will be received, entire string will be passed to scanf and converting will be successfully done if needed.

I hope you understand what I mean here.

tilz0R

Owner of this site. Also electronic enthusiasts, web developer, 3D printer fan, handball player and more. Big fan of STM32F4 devices. In anticipation of the new Discovery board for STM32F7 lines.

You may also like...

Read before commenting!

Before you make a new comment, make sure you agree with things listed below:

  • - Read post to make sure if it is already posted what you are asking for,
  • - Make sure you have the latest version of libraries used in your project,
  • - Make a clean and grammatically correct written message,
  • - Report as many details as possible, including what have you done so far,
  • - Do NOT post any code here. Use Pastebin,
  • - Do NOT post any error codes here. Use Pastebin,
  • - Specify STM32Fxxx family and used Discovery/EVAL/Nucleo or custom made board,
  • - Make sure your clock is set correct for PLL,
  • - If you are using my HAL drivers, please check this post how to start.
Comment will be deleted on breaking these rules without notification!
  • Saman

    Thank you so much Majerle 🙂
    I can not use it right now, but i understand what you said and i will try it

  • Maz

    Hi Majerle,

    I’ve actually gotten fgetc() to work from your suggestions above. I was wondering if you could post this on your blog as an example:

    int fgetc(FILE *f)
    {
    int c;

    while (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE) == RESET);

    c = LL_USART_ReceiveData8(huart1.Instance);

    return fputc(c, f);
    }

    Thanks,