Page 1 of 1

UART messages out of sync; responding to the wrong message

Posted: Thu May 15, 2025 1:45 pm
by yeold00
Hello

I have an ESP32-C6 running ESP-IDF 5.4.1
I have set ut an RS485 connection with half duples mode and an RTS pin.

I'm trying to set up a function that should respond to a specific message on the bus.
But when I check the bus the response is sent to the subsequent received message instead.
So my understanding is that there might be messages in the queue and the routine is responding to the message that's first in the queue and not the one that it's supposed to respond to.

With my code below, what am I doing wrong and how should I do instead?

UART config:

Code: Select all

const uart_config_t uart_config = {
    .baud_rate = 115200,
    .data_bits = UART_DATA_8_BITS,
    .parity = UART_PARITY_DISABLE,
    .stop_bits = UART_STOP_BITS_1,
    .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
};

Init function:
void Init()
{
// Initialize UART
ESP_ERROR_CHECK(uart_driver_install(UART_NUM, BUF_SIZE, BUF_SIZE, 10, &uart_queue, 0));
ESP_ERROR_CHECK(uart_param_config(UART_NUM, &uart_config));
ESP_ERROR_CHECK(uart_set_pin(UART_NUM, UART_TX, UART_RX, UART_RTS, UART_PIN_NO_CHANGE));
ESP_ERROR_CHECK(uart_set_mode(UART_NUM, UART_MODE_RS485_HALF_DUPLEX));
ESP_ERROR_CHECK(uart_enable_pattern_det_baud_intr(UART_NUM, MESSAGE_DELIMITER, MESSAGE_DELIMITER_REPEAT, 20000, 0, 0));
ESP_ERROR_CHECK(uart_pattern_queue_reset(UART_NUM, 30));

xTaskCreate(rxTask, "rx_task", 12288, NULL, configMAX_PRIORITIES - 1, NULL);
}
The uart handler:

Code: Select all

void spaRxTask(void *arg)
{
    uart_event_t event;
    size_t buffered_size;
    uint8_t *rcv_data = (uint8_t *)malloc(BUF_SIZE);

    while (1)
    {
        if (xQueueReceive(uart_queue, (void *)&event, (TickType_t)portMAX_DELAY))
        {
            switch (event.type)
            {
            case UART_DATA:
                // Only process data if it matches pattern
                break;
            case UART_FIFO_OVF:
            case UART_BUFFER_FULL:
                ESP_LOGI(TAG, "UART overflow or buffer full");
                uart_flush_input(UART_NUM);
                xQueueReset(uart_queue);
                break;
            case UART_BREAK:
                ESP_LOGI(TAG, "UART break");
                break;
            case UART_PARITY_ERR:
                ESP_LOGI(TAG, "UART parity error");
                break;
            case UART_FRAME_ERR:
                ESP_LOGI(TAG, "UART frame error");
                break;
            case UART_PATTERN_DET:
                uart_get_buffered_data_len(UART_NUM, &buffered_size);
                int pos = uart_pattern_pop_pos(UART_NUM);

                if (pos == -1)
                {
                    uart_flush_input(UART_NUM);
                }
                else
                {
                    int read_len = uart_read_bytes(UART_NUM, rcv_data, pos + MESSAGE_DELIMITER_REPEAT, 0);
                    if (read_len < pos + MESSAGE_DELIMITER_REPEAT) {
                        ESP_LOGW(TAG, "UART read incomplete: %d/%d", read_len, pos + MESSAGE_DELIMITER_REPEAT);
                        break;
                    }
                    if (isValidChannel(rcv_data[CHANNEL_ID_OFFSET]))
                    {
                        parseData(rcv_data, pos);
                    }
                    else
                    {
                        uart_flush_input(UART_NUM);
                        xQueueReset(uart_queue);
                    }
                }
                break;
            default:
                ESP_LOGD(TAG, "UART event: %d", event.type);
                break;
            }
        }
    }

    free(rcv_data);
    rcv_data = NULL;
    vTaskDelete(NULL);
}
I've tried to replace the parseData function with uart_write_bytes and it does no difference.

Here's the logic analyzer output, the message to the left is the one I want to respond to, but it responds to the 2nd instead causing a collision with the 3rd message.
Skärmbild 2025-05-15 154057.png
Skärmbild 2025-05-15 154057.png (33.02 KiB) Viewed 70 times
Thanks in advance!

Re: UART messages out of sync; responding to the wrong message

Posted: Fri May 16, 2025 8:47 am
by MicroController
Try setting a low(er) RX full threshold and/or RX timeout in order to be notified sooner of received data.