I did post this in another area but have not had much response.
My project uses RS485 (set up code below). The project sends RS485 data every 200ms to a remote unit that replies.
At some "random" time (sometimes it might run 30 minutes and at other times runs 2-3 days) the ENABLE signal goes low at start of packet before the data is sent. Once this happens, it appears to remain in that state and no communication occurs until hardware is reset. There was a discussion in 2019 about this but I did not understand what solution worked and whether this is something needs fixing in the driver. I am running ESP-IDF 4.2
Below is my setup and TX code (Note: I added the line that waits for TX done after sending in the hope this fixes it, I have only just done this so not sure if it has fixed anything yet).
[code]
#define UART_BREAK_TIME 4
#define UART_QUEUE_SIZE 100
extern xSemaphoreHandle received_uart_data;
#define TAG "UART"
QueueHandle_t uart_queue;
int8_t bytesReceived;
uint8_t rx_buffer[RX_BUFFER_SIZE];
void uart_event_task(void *params)
{
uart_event_t uart_event;
while(1)
{
if(xQueueReceive(uart_queue,&uart_event,portMAX_DELAY))
{
switch(uart_event.type)
{
case
UART_DATA:
if(uart_event.timeout_flag)
{
uart_read_bytes(rs485_uart, rx_buffer, uart_event.size,UART_BREAK_TIME);
bytesReceived = uart_event.size;
xSemaphoreGive(received_uart_data);
}
break;
case UART_FIFO_OVF:
ESP_LOGI(TAG, "hw fifo overflow");
uart_flush_input(rs485_uart);
xQueueReset(uart_queue);
break;
//Event of UART ring buffer full
case UART_BUFFER_FULL:
ESP_LOGI(TAG, "ring buffer full");
uart_flush_input(rs485_uart);
xQueueReset(uart_queue);
break;
default:
break;
}
}
}
}
void init_rs485_uart(void)
{
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,
.source_clk = UART_SCLK_APB,
};
ESP_ERROR_CHECK(uart_driver_install(rs485_uart, RX_BUFFER_SIZE,0,UART_QUEUE_SIZE,&uart_queue,0));
uart_param_config(rs485_uart, &uart_config);
uart_set_pin(rs485_uart, RS485_TXD_PIN, RS485_RXD_PIN, RS485_EN_PIN, UART_PIN_NO_CHANGE);
ESP_ERROR_CHECK(uart_set_mode(rs485_uart, UART_MODE_RS485_HALF_DUPLEX));
uart_set_rx_timeout(rs485_uart,UART_BREAK_TIME);
//uart_set_always_rx_timeout(rs485_uart,true);
xTaskCreate(uart_event_task,"uart event task",2048,NULL,20,NULL);
}
int send_rs845_uart_data(char *command,int numbytes)
{
//uart_clear_intr_status(rs485_uart, UART_TX_DONE_INT_CLR_M);
if(uart_write_bytes(rs485_uart, command, numbytes) != numbytes)
{
ESP_LOGI(TAG,"Critical Send Data Error");
}
ESP_ERROR_CHECK(uart_wait_tx_done(rs485_uart,50));
return true;
}
int receive_rs485_uart_data(char* response, uint32_t max_length, int wait_ms)
{
return uart_read_bytes(rs485_uart, (uint8_t *)response, max_length, pdMS_TO_TICKS(wait_ms));
}
void uart_init(void)
{
gpio_pad_select_gpio(RS485_EN_PIN);
gpio_set_direction(RS485_EN_PIN,GPIO_MODE_OUTPUT);
init_rs485_uart();
}
[/code]
RS485 Uart issue
-
- Posts: 25
- Joined: Mon Jun 28, 2021 4:55 am
Re: RS485 Uart issue
I have faced something like this before, are you using an RS485 transceiver with direction control pin?
Hobbyist and electronic design consultant! (https://PCBArtists.com/)
Re: RS485 Uart issue
Yes
I have set mode for Half Duplex and have the Enable pin being controlled by the Uart Driver
I have set mode for Half Duplex and have the Enable pin being controlled by the Uart Driver
Who is online
Users browsing this forum: No registered users and 55 guests