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

How to query data #184

Closed stritti closed 2 years ago

stritti commented 2 years ago

Hi, I am very new using modbus. I want to query data of a component, which I was able by CASModbusScanner: image

How will this be done using modbus-esp8266? I tried following Code but instead of value 21 I receive 13792 on ESP.

I use following code:

#include <Arduino.h>
#include <WiFi.h>
#include <ModbusIP_ESP8266.h>

WiFiClient  theClient;  // Set up a client for the WiFi connection
const char* ssid     = "SSID";
const char* password = "PWD";

IPAddress remote(192, 168, 178, 60);  // Address of Modbus Slave device
const int PORT     = 1502;
const int SLAVE_ID = 71;

ModbusIP mb;  //ModbusTCP object

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(74880);
  while (!Serial) {
  }

  Serial.println(F("Connecting to WiFi"));
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(F("."));
  }

  IPAddress wIP = WiFi.localIP();
  Serial.printf("WIFi IP address: %u.%u.%u.%u\n", wIP[0], wIP[1], wIP[2], wIP[3]);

  // Set up ModbusTCP client.
  // mb.client();
  mb.slave(SLAVE_ID);

  Serial.println(F("Device started"));
}

#define REG_COUNT 2
const int32_t showDelay = 5000;  // Show result every n'th millisecond
uint32_t      showLast  = 0;

void loop() {

  if (millis() - showLast > showDelay) {  // Display register value every 5 seconds (with default settings)
    showLast = millis();
    uint16_t res[REG_COUNT];
    if (mb.isConnected(remote)) {                                     // Check if connection to Modbus Slave is established
      uint16_t trans = mb.readHreg(remote, 514, res, REG_COUNT, cb);  // Initiate Read Hreg from Modbus Server
      while (mb.isTransaction(trans)) {                               // Check if transaction is active
        mb.task();
        delay(10);
      }
    } else {
      mb.connect(remote, PORT);  // Try to connect if no connection
      Serial.println("Modbus connected.");
    }

    Serial.println(res[0]);
  }
}

In console I just get:

Request result: 0xE4
13792
emelianov commented 2 years ago

To make request exactly as CASModbusScanner you need to specify UnitId:

uint16_t trans = mb.readHreg(remote, 514, res, REG_COUNT, cb, SLAVE_ID); 

Otherwise standard ignore = 255 value is used.

stritti commented 2 years ago

Awesome, @emelianov that was the missing point! Now it works. I searched for hours ... Many thanks for this hint.