Auto switching RS485 using SP3485 chip using ESP32C3 on UART0. How to make it work?
Posted: Wed Jun 07, 2023 9:06 pm
I designed a custom board to read an RS485 device using UART0 of the ESP32C3, GPIO 20 for RX, 21 for TX. I have now spent days trying to troublshoot it with no success. So any hints will be really really helpful
Here is my code and schematic. I couldn't manage to get any data out: Same schematic with SP3485 works fine with RPI PICO w based board. I tested them side by side.
#include "uart_handler.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_log.h"
#include "driver/uart.h"
#include "string.h"
#include "driver/gpio.h"
const uart_port_t uart_num = UART_NUM_0;
uart_config_t uart_config = {
.baud_rate = 38400,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
//.rx_flow_ctrl_thresh = 122,
};
// Configure UART parameters
ESP_ERROR_CHECK(uart_param_config(uart_num, &uart_config));
// Set UART pins(TX: IO4, RX: IO5, RTS: IO18, CTS: IO19)
ESP_ERROR_CHECK(uart_set_pin(UART_NUM_0, 20, 21, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
// Setup UART in rs485 mode
ESP_ERROR_CHECK(uart_set_mode(uart_num, UART_MODE_RS485_APP_CTRL));
ESP_ERROR_CHECK(uart_set_mode(uart_num, UART_RS485_CONF_REG.UART_RS485RXBY_TX_EN = 1));
ESP_ERROR_CHECK(uart_set_mode(uart_num, , UART_RS485_CONF_REG.UART_RS485TX_RX_EN = 0));
// Setup UART buffered IO with event queue
const int uart_buffer_size = (1024 * 2);
QueueHandle_t uart_queue;
// Install UART driver using an event queue here
ESP_ERROR_CHECK(uart_driver_install(UART_NUM_0, uart_buffer_size, \
uart_buffer_size, 10, &uart_queue, 0));
void tx_task() {
// Write data to UART.
uart_flush(uart_num);
// uart_flush_input(uart_num);
char* test_str = "getData\n\r";
uart_write_bytes(uart_num, (const char*)test_str, strlen(test_str));
// Write data to UART, end with a break signal.
// uart_write_bytes_with_break(uart_num, const char*)test_str,strlen(test_str), 100);
vTaskDelay(pdMS_TO_TICKS(500));
}
void rx_task(char rxdata[RX_BUF_SIZE]) {
tx_task();
// Read data from UART.
const uart_port_t uart_num = UART_NUM_0;
uint8_t data[128];
int length = 0;
ESP_ERROR_CHECK(uart_get_buffered_data_len(uart_num, (size_t*)&length));
length = uart_read_bytes(uart_num, data, length, 100);
ESP_LOGI("UART HANDLER", "Read %d bytes: '%s'", length, (char*) data);
uart_flush(uart_num);
Here is my code and schematic. I couldn't manage to get any data out: Same schematic with SP3485 works fine with RPI PICO w based board. I tested them side by side.
#include "uart_handler.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_log.h"
#include "driver/uart.h"
#include "string.h"
#include "driver/gpio.h"
const uart_port_t uart_num = UART_NUM_0;
uart_config_t uart_config = {
.baud_rate = 38400,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
//.rx_flow_ctrl_thresh = 122,
};
// Configure UART parameters
ESP_ERROR_CHECK(uart_param_config(uart_num, &uart_config));
// Set UART pins(TX: IO4, RX: IO5, RTS: IO18, CTS: IO19)
ESP_ERROR_CHECK(uart_set_pin(UART_NUM_0, 20, 21, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
// Setup UART in rs485 mode
ESP_ERROR_CHECK(uart_set_mode(uart_num, UART_MODE_RS485_APP_CTRL));
ESP_ERROR_CHECK(uart_set_mode(uart_num, UART_RS485_CONF_REG.UART_RS485RXBY_TX_EN = 1));
ESP_ERROR_CHECK(uart_set_mode(uart_num, , UART_RS485_CONF_REG.UART_RS485TX_RX_EN = 0));
// Setup UART buffered IO with event queue
const int uart_buffer_size = (1024 * 2);
QueueHandle_t uart_queue;
// Install UART driver using an event queue here
ESP_ERROR_CHECK(uart_driver_install(UART_NUM_0, uart_buffer_size, \
uart_buffer_size, 10, &uart_queue, 0));
void tx_task() {
// Write data to UART.
uart_flush(uart_num);
// uart_flush_input(uart_num);
char* test_str = "getData\n\r";
uart_write_bytes(uart_num, (const char*)test_str, strlen(test_str));
// Write data to UART, end with a break signal.
// uart_write_bytes_with_break(uart_num, const char*)test_str,strlen(test_str), 100);
vTaskDelay(pdMS_TO_TICKS(500));
}
void rx_task(char rxdata[RX_BUF_SIZE]) {
tx_task();
// Read data from UART.
const uart_port_t uart_num = UART_NUM_0;
uint8_t data[128];
int length = 0;
ESP_ERROR_CHECK(uart_get_buffered_data_len(uart_num, (size_t*)&length));
length = uart_read_bytes(uart_num, data, length, 100);
ESP_LOGI("UART HANDLER", "Read %d bytes: '%s'", length, (char*) data);
uart_flush(uart_num);