Page 1 of 1

scanf() don't work in idf monitor

Posted: Thu Aug 26, 2021 9:08 pm
by axel_hpplt
Hello,

I am a new user on esp-idf. I have done some tests after following the "Getting Started" section, including this one:
  1. #include <stdio.h>
  2.  
  3. void app_main(void)
  4. {
  5.     char chr;
  6.     printf("Enter Data : ");
  7.     scanf("%c", &chr);
  8.     printf("Data entered : %c.", chr);
  9. }
Everything goes well, I start the monitor with the command "idf.py -p COM3 monitor". It is displayed : "Enter Data : " but I can't write anything, as if the keyboard was not working. However the CTRL-C (keyboard interrupt) command works. Do you know why I can't write anything in this monitor ?

Thank you in advance for your help,

AH.

Re: scanf() don't work in idf monitor

Posted: Fri Aug 27, 2021 10:17 am
by ESP_Minatel
Hi,

You need to use the console approach. See this example:

https://github.com/espressif/esp-idf/tr ... sole/basic

Re: scanf() don't work in idf monitor

Posted: Fri Aug 27, 2021 2:26 pm
by axel_hpplt
ESP_Minatel wrote:
Fri Aug 27, 2021 10:17 am
Hi,

You need to use the console approach. See this example:

https://github.com/espressif/esp-idf/tr ... sole/basic
First of all, thank you so much for your response! I looked at what you sent me, I may be blind but I don't really see how it helps me with my problem. It did help me start to understand the "console" approach but I don't see how I can "replace" my lines of code.

Re: scanf() don't work in idf monitor

Posted: Fri Aug 27, 2021 3:14 pm
by ESP_Minatel
Are you trying to do something similar to this thread?

Reading character input from the serial port

See also the UART Select Example.

Re: scanf() don't work in idf monitor

Posted: Fri Aug 27, 2021 10:29 pm
by axel_hpplt
ESP_Minatel wrote:
Fri Aug 27, 2021 3:14 pm
Are you trying to do something similar to this thread?

Reading character input from the serial port

See also the UART Select Example.
I found a solution that seems to fit:
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "esp_system.h"
  4. #include "esp_console.h"
  5. #include "esp_vfs_dev.h"
  6. #include "esp_vfs_fat.h"
  7. #include "driver/uart.h"
  8.  
  9. void app_main(void)
  10. {  
  11.     setvbuf(stdin, NULL, _IONBF, 0);
  12.     setvbuf(stdout, NULL, _IONBF, 0);
  13.     ESP_ERROR_CHECK(uart_driver_install(CONFIG_ESP_CONSOLE_UART_NUM, 256, 0, 0, NULL, 0));
  14.     esp_vfs_dev_uart_use_driver(CONFIG_ESP_CONSOLE_UART_NUM);
  15.     esp_vfs_dev_uart_port_set_rx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CR);
  16.     esp_vfs_dev_uart_port_set_tx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CRLF);
  17.     char chr[10];
  18.     while(1){
  19.         printf("Enter Data : ");
  20.         scanf("%9s\n", chr);
  21.         printf("\nData entered : %s.\n", chr);
  22.     }
  23. }
The above program works well, I enter a string in the console (10 maximum), and when I press "Enter" the code displays the previously entered string. However, some problem persists:
- Sometimes there is a bug that appears randomly:

Image

I think it's a display bug but I'm not sure.

- The characters are not displayed as I type them on the keyboard. They only appear once I press "Enter".
- Last problem, once I type the string and press "Enter" the string does not appear. It only appears once I start writing the new string.

I would like to know if there are any solutions to solve these problems.

Re: scanf() don't work in idf monitor

Posted: Tue Nov 16, 2021 5:39 pm
by ekawahyu
@axel_hpplt Thank you for posting this solution, and I got a fix for you. Instead of using

Code: Select all

scanf("%9s\n", chr);
, remove the trailing

Code: Select all

scanf("%9s", chr);
and you should be good to go.

Re: scanf() don't work in idf monitor

Posted: Thu Sep 01, 2022 7:59 pm
by EnthusiastGuy
Thank you very much for this!

I am able to confirm that this program works excellent with ESP-IDF 4.4 in order to take commands from the PC by means of Serial communication with the ESP32 board (in my case):

Code: Select all

#include <stdio.h>
#include <string.h>
#include "esp_system.h"
#include "esp_console.h"
#include "esp_vfs_dev.h"
#include "esp_vfs_fat.h"
#include "driver/uart.h"
 
void app_main(void)
{  
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL[Codebox][/Codebox], _IONBF, 0);
    ESP_ERROR_CHECK(uart_driver_install(CONFIG_ESP_CONSOLE_UART_NUM, 256, 0, 0, NULL, 0));
    esp_vfs_dev_uart_use_driver(CONFIG_ESP_CONSOLE_UART_NUM);
    esp_vfs_dev_uart_port_set_rx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CR);
    esp_vfs_dev_uart_port_set_tx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CRLF);
    char chr[10];
    while(1){
        printf("Enter Data : ");
        scanf("%9s", chr);	// thanks ekawahyu!
        printf("\nData entered : %s.\n", chr);
    }
}
I have one question. Since the scanf waits for the input, is there any alternative that would instead not interrupt execution and only come into function if actual content comes from the uart? My first guess is that I'd have to check for data first and if it exists, then do the scanf, but I am unfamiliar with the API and I'm actually not sure whether I'd run into an exhaust state or race condition there.

Thanks!

Re: scanf() don't work in idf monitor

Posted: Fri Sep 02, 2022 12:50 am
by ESP_Sprite
You'd need to collect the characters from the UART into a string yourself, and when you get a newline, you can run sscanf() on that.