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 188 forks source link

Setting up RTU server with IREGs #245

Closed That-Dude closed 2 years ago

That-Dude commented 2 years ago

Apologies if this is simple, I'm not a dev and I'm really struggling this, I find the master,slave,server,client language is confusing and I may have completely misunderstood something.

I have an inverter (the client?) that polls a power meter (the server?) over RTU.

It transmits this RTU frame:

TX: 01 04 00 00 00 0E 71 CE

Part of Data Package Description Value
01 Slave address 0x01 (1)
04 Function code 0x04 (4) - Read Input Registers
00 00 Starting address Physical: 0x0000 (0) Logical: 0x0001 (1)
00 0E Quantity 0x000E (14)
71 CE CRC 0x71CE (29134)

I would like to respond to this request.

I have a working ESP8266 with 485 module attached. I would like an example of how to create the 14 IREG and handle the polling from the inverter.

void setup() {
  Serial.begin(9600); // This serial for debug prints
  S.begin(9600, SWSERIAL_8N1);
  mb.begin(&S,D0); // RE/DE connected to D0 of ESP8266
  mb.master();

// voltage input register - 250.340 volts

  mb.addReg(IREG(0));     // Add Input register #0
  mb.Ireg(0, 100); // set input 0 to value 250

  mb.addReg(IREG(1));     // Add Input register #1
  mb.Ireg(1, 100); // set input 1 to value 340
That-Dude commented 2 years ago

I think that I've figured it out.

I needed a slave device, my inverter is acting as the master and requesting 14 IREGs.

It's magical how so little code is needed for this, @emelianov your work is amazing!

#include <ModbusRTU.h>
#include <SoftwareSerial.h>

// #define MODBUSRTU_DEBUG

SoftwareSerial S(D3, D2); // we need one serial port for communicating with RS 485 to TTL adapter

#define SLAVE_ID 1

ModbusRTU mb;

void setup() {
  Serial.begin(9600); // This serial for debug prints
  S.begin(9600, SWSERIAL_8N1);
  mb.begin(&S,D0); // RE/DE connected to D0 of ESP8266

  mb.slave(SLAVE_ID);

  // add a series of Input registers
  mb.addIreg(0);
  mb.addIreg(1);
  mb.addIreg(2);
  mb.addIreg(3);
  mb.addIreg(4);
  mb.addIreg(5);
  mb.addIreg(6);
  mb.addIreg(7);
  mb.addIreg(8);
  mb.addIreg(9);
  mb.addIreg(10);
  mb.addIreg(11);
  mb.addIreg(12);
  mb.addIreg(13);

  // set Input register values
  mb.Ireg(0, 250);  // line to neutral volts (integer-part)
  mb.Ireg(1, 400);  // line to neutral volts (fractional-part)
  mb.Ireg(2, 10);   // Current Amps  (integer-part)
  mb.Ireg(3, 54);   // Current Amps (fractional part)
  mb.Ireg(4, 2500); // Active power Watts (integer part)
  mb.Ireg(5, 76);   // Active power Watts (fractional part)
  mb.Ireg(6, 2639); // Apparent power VoltAmps (integer part)
  mb.Ireg(7, 216);  // Apparent power VoltAmps (float part)
  mb.Ireg(8, 2375); // Reactive power VAr (integer part)
  mb.Ireg(9, 5);    // Reactive power VAr (fractional part)
  mb.Ireg(10, 0);   // Power factor (none) (integer part)
  mb.Ireg(11, 90);  // Power factor (none) (fractional part)
  mb.Ireg(12, 30);  // Phase angle (Degree) (integer-part) - ** this is not a calculated value but my device doesnt actially use it
  mb.Ireg(13, 1);   // Phase angle (Degree) (fractional-part) - ** this is not a calculated value but my device doesnt actially use it

}

void loop() {
  // write code here to update the input register values from data held on the mqTT server
  mb.task();
  yield();
}