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.
Other
534 stars 190 forks source link

stuck with Master and Slave on one ESP32 board #369

Closed pacraf closed 2 weeks ago

pacraf commented 3 weeks ago

I tried to make modbus "man in the middle" or kind of bridge. So on one ESP32 start Master RTU (Serial1) that will talk to Chint energy meter , and on second serial (Serial2) emulate a few registers of this Chint , as RTU Slave. This Slave is talking with computer with RS485 dongle with Modbus test software. This software (free QModMaster is also tested, and talks for example with direct connect to Chint meter) Based on basic.ino , tried to setup this like below. I see that Master talks to Chint (see that with external RS485 dongle). But Slave does not respond.

I am pretty sure wiring is OK, as I can change serial 1 and 2 in program (and also swap Energy meter on port) , and again Master RTU talks to Meter. But Slave beeing asked (on second is timing out (not sending anything) what can be wrong...

` /* Modbus ESP8266/ESP32 Simple ModbesRTU bridge

(c)2020 Alexander Emelianov (a.m.emelianov@gmail.com) https://github.com/emelianov/modbus-esp8266 */

include

include

define TO_REG 0x2006

//#define TO_UABC_REG 0x2006

define SLAVE_ID 1

define PULL_ID 1

define FROM_REG 0x2006

//#define FROM_UABC_REG 0x2006

ModbusRTU mb1; ModbusRTU mb2;

void setup() {

//

Serial2.begin(9600, SERIAL_8N1, 33, 32); //Init Serial2
Serial1.begin(9600, SERIAL_8N1, 19, 18); // Init Serial1 Serial.begin(115200, SERIAL_8N1); // default pins for ESP32 debug

mb2.begin(&Serial2, 27); // slave = emu chint mb1.begin(&Serial1, 17); // master for chint on Serial1

Serial.println("setup"); mb1.master(); //master for chint mb2.server(); //server = slave = emulator of chint mb2.addHreg(TO_REG); // mb2.addHreg(TO_UABC_REG); }

void loop() { if(!mb1.slave()) mb1.pullHreg(PULL_ID, FROM_REG, TO_REG,2); mb1.task(); mb2.task(); yield(); delay(50); //Serial.println("loop"); // if(!mb1.slave()) // mb1.pullHreg(PULL_ID, FROM_UABC_REG, TO_UABC_REG,6); // mb1.task(); // mb2.task(); // delay(50); } `

pacraf commented 3 weeks ago

As expected, it was my mistake, I did not setup slave address adding this mb2.slave(SLAVE_ID); in setup , makes slave happily responding and serve registers pulled by master...

pacraf commented 3 weeks ago

If I could ask for explanation of this part of code: mb1.pullHreg(PULL_ID, FROM_REG, TO_REG,2); My understanding is that it is pulling registers from slave device starting from register "FROM_REG" and writes it under register "TO_REG" , and register count is 2 in this example. That makes in this basic example the case that "ESP32 - Slave RTU" properly responds the same values that were just read by "ESP32 - Master RTU" from Energy meter.
and my question is - what is limit of registers count? should it not be defined in advance if I would like to take 90 registers from this meter? or it is just fine to mb1.pullHreg(PULL_ID, FROM_REG, TO_REG,90); and not worry

pacraf commented 3 weeks ago

Looking on modbus documentation, seems that 90 is below suggested message length, so seems it is just fine to set 90 . I know, I talk to myself in this thread, but in fact I am doing that when shaving too, so it’s normal … after stress test a few days of my little RTU bridge, I will close this topic. Hope all will work and inverter will not realize that it’s not really talking to energy meter, but impostor. Then I will try to make it custom component of esphome.

By the way , kindly thank you for this great library.

emelianov commented 2 weeks ago

mb1.pullHreg(PULL_ID, FROM_REG, TO_REG,90);

Works exactly as expected reading 90 sequential registers. mb1.pullHreg(PULL_ID, FROM_REG, TO_REG) reads just one register.

pacraf commented 2 weeks ago

Thank you for confirming. basically program works (as bridge RTU <>RTU) .

Once again thank you for great library. all what I wanted to do with modbus bridge works.