modbus-esp8266
modbus-esp8266 copied to clipboard
ESP32: ModbusRTU readHreg not working in Master Mode
Thank you for this wonderful library. I am trying to implement Modbus communication between ESP32 and ESP8266 modules. My current configuration is
ESP8266 MAX485 MAX485 ESP32 D4(Rx) -------------- RO A A-----------RO-----------GPIO16 D5(Tx) -------------- DI B B----------DI------------ GPIO17 D12(DE_RE) ------ RE/DE RE/DE-------GPIO04
If ESP8266 is set as Master, both writeHreg & readHreg works with ESP32. But if ESP32 is set as Master, only writeHreg works while the readHreg returns 0 values.
Below are the codes, I have used the library from Git.
ESP8266 Code (Slave)
`/*---------------------------------------------------------------
ESP8266 Based Modbus RTU Slave
ModbusRTU ESP8266/ESP32 Simple slave example
(c)2019 Alexander Emelianov ([email protected]) https://github.com/emelianov/modbus-esp8266
modified 13 May 2020 by brainelectronics
This code is licensed under the BSD New License. See LICENSE.txt for more info.
Supported Functions:
0x01 - Read Coils 0x02 - Read Input Status (Read Discrete Inputs) 0x03 - Read Holding Registers 0x04 - Read Input Registers 0x05 - Write Single Coil 0x06 - Write Single Register 0x0F - Write Multiple Coils 0x10 - Write Multiple Registers 0x14 - Read File Record 0x15 - Write File Record 0x16 - Mask Write Register 0x17 - Read/Write multiple registers */
//--------------------------------------------------------------- #include <Arduino.h>
#define RX_Pin 4 //GPIO4 #define TX_Pin 5 // GPIO5 #define RE_DE_PIN 12 //GPIO12 #define SLAVE_ID 10
#include <SoftwareSerial.h> SoftwareSerial S(RX_Pin, TX_Pin);
#include <ModbusRTU.h> ModbusRTU mb;
bool cb(Modbus::ResultCode event, uint16_t transactionId, void* data) { // Callback to monitor errors if (event != Modbus::EX_SUCCESS) { Serial.print("Request result: 0x"); Serial.print(event, HEX); } return true; }
void setup() { Serial.begin(115200); Serial.println("MODSERV-8266");
S.begin(9600, SWSERIAL_8N1); mb.begin(&S, RE_DE_PIN); //Enable this is to use with RS485
mb.slave(SLAVE_ID); mb.addHreg(14); mb.Hreg(14, 100);
} uint16_t freq_val;
void loop() { if ( freq_val < 65535) { freq_val++; } else { freq_val=0; } if (!mb.Hreg(14, freq_val)){ Serial.println("FREQUENCY_1 register add failed!!!"); }
mb.task(); yield(); delay(10); }`
ESP32 (Master) `#include <Arduino.h>
/* ModbusRTU ESP32 Read multiple coils from slave device example
Client is the Master on Modbus
(c)2019 Alexander Emelianov ([email protected]) https://github.com/emelianov/modbus-esp8266
modified 13 May 2020 by brainelectronics
This code is licensed under the BSD New License. See LICENSE.txt for more info. */
#define rxPin 16 // GPIO16 #define txPin 17 // GPIO17 #define RE_DE_PIN 4// GPIO04
#include <ModbusRTU.h> #define SLAVE_ID 10
ModbusRTU mb;
bool cb(Modbus::ResultCode event, uint16_t transactionId, void* data) { // Callback to monitor errors if (event != Modbus::EX_SUCCESS) { Serial.print("Request result: 0x"); Serial.println(event, HEX); } return true; }
void setup() { Serial.begin(115200); Serial2.begin(9600, SERIAL_8N1, rxPin, txPin); mb.begin(&Serial2, RE_DE_PIN); mb.master(); }
uint16_t response; uint16_t freq_val;
void loop() {
if(!mb.slave()){
uint16_t response = mb.readHreg(10, 14,&freq_val,1,cb);
while(mb.slave()) { // Check if transaction is active
mb.task();
delay(10);
}
Serial.print("response : "); Serial.println(response);
Serial.print("Freq : "); Serial.println(freq_val);
} delay(1000); mb.task(); }`
Below is the output of ESP8266 when run in DEBUG mode.
3 0 E 0 1 E4 B2 3 2 DC C4 3 0 E 0 1 E4 B2 3 2 DD 8C 3 0 E 0 1 E4 B2 3 2 DE 54 3 0 E 0 1 E4 B2 3 2 DF 1C 3 0 E 0 1 E4 B2
Below is the output from ESP32 .. is leading 0s the correct response?
3 0 E 0 2 0 0 0 0 0 0 0 A 3 4 33 36 3F 73 FF AC 0 Request result: 0xE4
Fixed the leading 0s. Now the transmit and receive debug values are similar. But still getting 0xE4 error.
Server ( ESP8266 )
3 0 E 0 2 A4 B3
3 4 99 98 41 97
Client ( ESP32 )
3 0 E 0 2
A 3 4 99 98 41 97 9E 7E 0
Request result: 0xE4
Finally tweaked below setting in ModbusSettings.h on both ESP8266 & ESP32 and got it working.
#define MODBUSRTU_REDE_SWITCH_US 1200
and below setting in ESP32
#define MODBUSRTU_FLUSH_DELAY 4
Still the reads are not 100% successful, '0xE4' are reported at random points leading to invalid data being read.
In debug, I see 8266 is sending the data, but ESP32 receives it with leading '0s'.