Reading MODBUS RTU acknowledgment with esp-idf
Posted: Mon Sep 08, 2025 11:29 am
Hi,
I'm working on implementing MODBUS communication by sending data via UART from an ESP.
When transmitting, I successfully send RS485 data to the MODBUS device by setting the RE/DE (tied together) pins high. Then, I immediately set them low to receive data on the RX line of the ESP.
However, the received data includes the correct values along with leading and trailing zeros. Sometimes, garbage data appears instead of the actual response.
can you check my source code once and let me know if any corections are needed.
--------------Logs-----------
Expected Data : 01 03 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1B A5
Actual Data : 00 01 03 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1B A5 00
I'm working on implementing MODBUS communication by sending data via UART from an ESP.
When transmitting, I successfully send RS485 data to the MODBUS device by setting the RE/DE (tied together) pins high. Then, I immediately set them low to receive data on the RX line of the ESP.
However, the received data includes the correct values along with leading and trailing zeros. Sometimes, garbage data appears instead of the actual response.
can you check my source code once and let me know if any corections are needed.
Code: Select all
#include <stdio.h>
#include <stdint.h>
#include "driver/uart.h"
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#define ZONE_READ_REG_VAL 7000
#define MAX_ZONES 64
#define FRAME_SIZE 8
#define UART_NUM UART_NUM_2
#define TXD_PIN GPIO_NUM_41
#define RXD_PIN GPIO_NUM_42
#define RS485_ENABLE_PIN GPIO_NUM_2
#define SLAVE_ID 01
#define BAUD_RATE 9600
#define BUF_SIZE 1024
static void poll_all_zones(void) {
uint8_t rx_data[135];
uint8_t frame[FRAME_SIZE];
uint16_t reg = ZONE_READ_REG_VAL;
frame[0] = SLAVE_ID;
frame[1] = 0x03;
frame[2] = (reg >> 8) & 0xFF;
frame[3] = reg & 0xFF;
frame[4] = 0x00;
frame[5] = MAX_ZONES & 0xFF;
//uint16_t crc = modbus_crc16(frame, 6);
frame[6] = 0xC3;//crc & 0xFF;
frame[7] = 0x0D;//(crc >> 8) & 0xFF;
gpio_set_level(RS485_ENABLE_PIN, 1);
vTaskDelay(pdMS_TO_TICKS(10));
uart_write_bytes(UART_NUM, (const char *)frame, FRAME_SIZE);
uart_wait_tx_done(UART_NUM, pdMS_TO_TICKS(50));
vTaskDelay(pdMS_TO_TICKS(10));
gpio_set_level(RS485_ENABLE_PIN, 0);
//vTaskDelay(pdMS_TO_TICKS(5));
int len = uart_read_bytes(UART_NUM, rx_data, sizeof(rx_data), pdMS_TO_TICKS(100));
printf("\n");
if (len > 0) {
for (int i = 0; i < sizeof(rx_data); i++) {
printf("%02X ", rx_data[i]);
}
printf("\n");
}
}
void rs485_task(void *arg) {
// ESP_LOGI(TAG_RS485_DATA, "Zone polling task started");
for (;;) {
poll_all_zones();
vTaskDelay(pdMS_TO_TICKS(200));
}
}
void app_main(void) {
uart_config_t uart_config = {
.baud_rate = BAUD_RATE,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE
};
// Init UART
ESP_ERROR_CHECK(uart_driver_install(UART_NUM, 256, 0, 0, NULL, 0));
ESP_ERROR_CHECK(uart_param_config(UART_NUM, &uart_config));
ESP_ERROR_CHECK(uart_set_pin(UART_NUM, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
// Init RS485 direction control pins
gpio_set_direction(RS485_ENABLE_PIN, GPIO_MODE_OUTPUT);
gpio_set_level(RS485_ENABLE_PIN, 0); // Default to RX mode
vTaskDelay(50);
xTaskCreate(rs485_task, "rs485_task", 8192, NULL, 5, NULL);
}
Expected Data : 01 03 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1B A5
Actual Data : 00 01 03 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1B A5 00