emelianov / modbus-esp8266

Most complete Modbus library for Arduino. A library that allows your Arduino board to communicate via Modbus protocol, acting as a master, slave or both. Supports network transport (Modbus TCP) and Serial line/RS-485 (Modbus RTU). Supports Modbus TCP Security for ESP8266/ESP32.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ESP32: ModbusRTU readHreg not working in Master Mode

pprakash opened this issue · comments

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 (a.m.emelianov@gmail.com)
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 (a.m.emelianov@gmail.com)
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'.