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:
The uart handler: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);
}
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);
}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. Thanks in advance!