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

Query a block of registers from a slave

StefanR71 opened this issue · comments

Hello,

i'm trying to use a ESP32 with 2 Modbus interfaces. (MAX13487 chip). So far i got it working.

From the Modbus Master part i query some values from a Carlo Gavazzi power meter. The values i got from there i put into local registers, most of them directly and 4 i had to modify.

Now i need to query the values the same way i got the values from the power meter, from a different Master device, for that i used the Slave part here.

The first batch is starting at 0 with 12 values, the second batch starting at 268 with also 12 values and the last batch from 280 with 8 values.

I have here a additional Modbus TCP/RTU gateway to query the values for testing from a linux PC with the mosbus-cli installed. When query a single value it is working, but when i query more values at the same time i'm getting a tmeout, there is no response.

This is my code:

#include <Arduino.h>
#include <HardwareSerial.h>
#include <ModbusRTU.h>

#define RX_S_PIN 16
#define TX_S_PIN 17
#define RX_M_PIN 25
#define TX_M_PIN 26

HardwareSerial MasterSerial(1);
HardwareSerial SlaveSerial(2);

ModbusRTU MMaster;
ModbusRTU MSlave;

uint16_t holdingRegistersA[12];
uint16_t holdingRegistersB[12];
uint16_t holdingRegistersC[8];
uint16_t ptotal;
uint16_t pl1;
uint16_t pl2;
uint16_t pl3;

void setup() {
  MasterSerial.begin(9600, SERIAL_8N1, RX_M_PIN, TX_M_PIN);
  SlaveSerial.begin(9600, SERIAL_8N1, RX_S_PIN, TX_S_PIN);
  MMaster.begin(&MasterSerial);
  MMaster.master();
  MSlave.begin(&SlaveSerial);
  MSlave.slave(4);
  MSlave.addHreg(0,1,300);
  }

void loop() {
  if (!MMaster.slave()) {
    MMaster.readHreg(4, 0, holdingRegistersA, 12);
  }
  while(MMaster.slave()) {
    MMaster.task();
    delay(10);
  }

  if (!MMaster.slave()) {
    MMaster.readHreg(4, 268, holdingRegistersB, 12);
  }
  while(MMaster.slave()) {
    MMaster.task();
    delay(10);
  }

  if (!MMaster.slave()) {
    MMaster.readHreg(4, 280, holdingRegistersC, 8);
  }
  while(MMaster.slave()) {
    MMaster.task();
    delay(10);
  }
  
  MSlave.Hreg(0, holdingRegistersA[0]);
  MSlave.Hreg(1, holdingRegistersA[1]);
  MSlave.Hreg(2, holdingRegistersA[2]);
  MSlave.Hreg(3, holdingRegistersA[3]);
  MSlave.Hreg(4, holdingRegistersA[4]);
  MSlave.Hreg(5, holdingRegistersA[5]);
  MSlave.Hreg(6, holdingRegistersA[6]);
  MSlave.Hreg(7, holdingRegistersA[7]);
  MSlave.Hreg(8, holdingRegistersA[8]);
  MSlave.Hreg(9, holdingRegistersA[9]);
  MSlave.Hreg(10, holdingRegistersA[10]);
  MSlave.Hreg(11, holdingRegistersA[11]);

  MSlave.Hreg(268, holdingRegistersB[0]);
  MSlave.Hreg(269, holdingRegistersB[1]);
  MSlave.Hreg(270, holdingRegistersB[2]);
  MSlave.Hreg(271, holdingRegistersB[3]);
  MSlave.Hreg(272, holdingRegistersB[4]);
  MSlave.Hreg(273, holdingRegistersB[5]);
  pl1 = holdingRegistersB[6] + 333;
  MSlave.Hreg(274, pl1);
  MSlave.Hreg(275, holdingRegistersB[7]);
  pl3 = holdingRegistersB[8] + 333;
  MSlave.Hreg(276, pl2);
  MSlave.Hreg(277, holdingRegistersB[9]);
  pl3 = holdingRegistersB[10] + 333;
  MSlave.Hreg(278, pl3);
  MSlave.Hreg(279, holdingRegistersB[11]);

  ptotal = holdingRegistersC[0] + 999;
  MSlave.Hreg(280, ptotal);
  MSlave.Hreg(281, holdingRegistersC[1]);
  MSlave.Hreg(282, holdingRegistersC[2]);
  MSlave.Hreg(283, holdingRegistersC[3]);
  MSlave.Hreg(284, holdingRegistersC[4]);
  MSlave.Hreg(285, holdingRegistersC[5]);
  MSlave.Hreg(286, holdingRegistersC[6]);
  MSlave.Hreg(287, holdingRegistersC[7]);

  MSlave.task();
  
  yield();
}

So, why can't i query the holding registers from 280 to 287 in one request form the Slave part?

Kind regards
Stefan

Oh i just noticed that i made an mistake with the query. :-(

Here with a sniffer the bus traffic:

162.96 : 04 03 01 18 00 01 05 A4 <- Working query
163.04 : 04 03 02 16 F0 7A 60 <- Response
167.62 : 06 03 01 12 00 07 A4 46 <- not working query

I reused every time a command on the linux shell, but i missed that i had used a wrong modbus ID.

So i think, all is fine...

Hmm... In general my programm is working, but not stable, the device what makes the query for the values sometimes don't get an answer from the slave part...

Perhaps i need to modify that with multithreading like in this example: https://github.com/emelianov/modbus-esp8266/blob/master/examples/RTU/ESP32-Concurent/ESP32-Concurent.ino

I got it, with a little help is its now working perfect!

Thaynk you for that wonderful library!