UART Write-Read data implementation. Can't read response


Good day!
I want to implement simple exchange protocol between esp32(master) - arduino nano(slave).
I send request message to slave, and after try to read response, but it doesn’t recieve.

a part of example code:

struct mbuf inputBuffer;

void uart_read_recieved_data_cb(int uart_no, void *arg)
    size_t resp_size = mgos_uart_read_avail(2);
    LOG(LL_INFO, ("Response message size: %d", resp_size));
    if (resp_size)
        mgos_uart_read_mbuf(2, &inputBuffer, resp_size);

void get_data_from_device_cb(void *arg)
    const char identification_msg[] = { 0x55, 0x01, 0xFE, 0x00, 0x00, 0x00, 0xAB };
    mgos_uart_set_dispatcher(2, uart_read_recieved_data_cb, NULL);
    mgos_uart_write(2, &identification_msg, sizeof(identefication_msg));

enum mgos_app_init_result mgos_app_init(void)
    struct mgos_uart_config ucfg;
    mgos_uart_config_set_defaults(2, &ucfg);
    ucfg->baud_rate = 9600;
    ucfg->num_data_bits = 8;
    ucfg->stop_bits = MGOS_UART_STOP_BITS_1;
    ucfg->parity = MGOS_UART_PARITY_NONE;

    if (!mgos_uart_configure(2, &ucfg)
        LOG(LL_ERROR, ("Failed to configure UART%d", 2));
        return MGOS_APP_INIT_ERROR;

    mgos_set_timer(5000, MGOS_TIMER_REPEAT, get_data_from_device_cb, NULL);

In debug terminal I can always see a lot of these messages for one request

Response message size: 0
Response message size: 0
Response message size: 0
Response message size: 0
Response message size: 0

Why there is no bytes in rx buffer?
Or is there other way to implement write-read functions with uart?

P.S. I can get response message from slave using PC terminal.
P.P.S. I listened to the line master-slave with Advanced Serial Port Monitor - all is ok! I can see request and response


i shouldn’t be checking your code. I don’t know what you want to do and might be talking nonsense.
If I was to check for the number of bytes that have just been received I wouldn’t call the function to check how many bytes I can write.


Oh, sorry. I made a mistake when I adapted the code for the example!

in original code:
resp_size = mgos_uart_read_avail(2);


Ok. If I want to get response after request, should I use mgos_uart_set_dispatcher() and handler (*mgos_uart_dispatcher_t)()??
Or there is another way?


AFAIK, no.
You also need to enable rx.

Have a look at the uart example.

1 Like

Thanks, enable rx helps me to read data!
But now handler for response data called more then one time!
I added counter for handler calling and see, that handler called about 40-50 times after one request, and data reading performed in two stages.

Why handler called a lot of times after 1 request??? And, may be you know, how can I solve this problem?


Did you happen to read in the docs that the same handler is called for tx and rx ?
Plus, just on rx, the handler is called whenever there is data, and “there is data” when it is taken out of the FIFO, and that happens when “it’s been there for a while”. The config has some parameters to trim the lingering time, this is mostly normal OS behavior. The driver tries to let the FIFO fill in order to minimize interrupts and get chunks of data. At the same time, it has to avoid it being filled while left unattended.

1 Like

It is your resposability to validate the incoming data.
The dispatcher can be called at any time, with or without any received data.

1 Like