Arduino Modbus TCP read Holding Register

Hallo,

ich versuche schon seit Tage mit der Library

...Daten von meiner Holzpelletsheizung auszulesen.
Das ganze funktioniert mit dem "CAS Modbus Scanner" vom PC aus gut, und ich erhalte auch Sinnvolle und richtige Werte.

Als erstes wollte ich eigentlich nur die Register 89 und 90 auslesen und am seriell Monitor ausgeben lassen...aber ich glaube da kommt nicht mal eine Verbindung zustande....die Ausgabe ist jedenfalls für beide Register immer "0".
Hier der verwendete Sketch:

/*
  Modbus-Arduino Example - KTemp (Modbus IP)
  Copyright by André Sarmento Barbosa
  http://github.com/andresarmento/modbus-arduino
*/

#include <SPI.h>
#include <Ethernet.h>
#include <Modbus.h>
#include <ModbusIP.h>

//Fürs Programm definiert: 1xxx ISTS; 2xxx COIL; 3xxx IREG; 4xxx HREG
//IDs für Modbus-Variablen
const int PU_TPO_IST_HREG = 89;
const int PU_TPM_IST_HREG = 90;

//#define TCP_KEEP_ALIVE sollte aktiv sein

//Objekte erstellen
ModbusIP mb;

void setup() {
  Serial.begin(9600);

  // The media access control (ethernet hardware) address for the shield
  byte mac[] = { 0x01, 0xA2, 0xDA, 0x0F, 0x08, 0xE2 };  // The IP address for the shield
  byte ip[] = { 192, 168, 178, 18 };                    // Config Modbus IP
  byte DNS[] = {192, 168, 178, 1};                      // Local dns
  byte gateway[] = {192, 168, 178, 1};                  // Local gateway
  byte subnet[] = {255, 255, 255, 0};                   // Local subnet
 
  mb.config(mac, ip, DNS, gateway, subnet);


  //Modbus-Variablen erstellen
  mb.addHreg(PU_TPO_IST_HREG, 0);
  mb.addHreg(PU_TPM_IST_HREG, 0);
}

void loop() {
  //Call once inside loop() - all magic here
  mb.task();

  Serial.print("Puffertemperatur oben:");
  Serial.println(mb.Hreg(PU_TPO_IST_HREG));
  Serial.print("Puffertemperatur mitte:");
  Serial.println(mb.Hreg(PU_TPM_IST_HREG));


  delay(3000);
}

Was mache ich flasch?
Ausserdem habe ich nirgendwo gefunden wo ich die IP-Adresse der Pelletsheizung einzugeben (die wartet auf eine Verbindung zum Client mit dem Port 502).....ist die IP des Masters nicht notwendig?

Vielen Dank für eure Hilfe!

Hallo und Willkommen im Forum! :slight_smile:

Ist der Arduino direkt mit der Heizung verbunden oder über den Router?

Gruß

Das ist eine Library die nur Slave auf RTU Basis kann und Server auf TCP/IP. In der Beschreibung steht klar das Master noch "in development" ist.
Mobus Funktioniert so.
Der Master fragt beim Slave und bekommt die Daten vom Salve. (Bei RTU RS485)
Der Client fragt beim Server die Daten (Bei TCP/IP).
In diesem Fall ist deine Heizung der Server und und du musst mit einem Client(Arduino) beim Server(Heizung) die Daten abfragen. Mit deiner Lib die du nutzt geht es "noch"nicht.
Suche mal arudino modbus tcp client.
>HIER<

Hallo...und vielen Dank für die Antworten!
Der Arduino ist mit der Heizung über Router und Switch verbunden.

Danke für die Erklärung, und ich denke ich habs verstanden....und bin deinem Tip von volvodani nachgegangen.
Ich hab den Sketch jetzt hochgeladen, aber wie kann ich jetzt bestimmte Holding Register z.B 89 und 90 auslesen?
...ich hab dazu leider auch keine Anleitung gefunden :confused:

Im Serial Monitor kann ich 3 oder 4 eingeben....wenn ich über 0 die Daten aufliste steht immer 0 drin??

Hier der Sketch:

#include <SPI.h>
#include <Ethernet.h>
#include "MgsModbus.h"

MgsModbus Mb;
int inByte = 0; // incoming serial byte

// Ethernet settings (depending on MAC and Local network)
byte mac[] = {0x00, 0xA2, 0xDA, 0x0F, 0x08, 0xE2 };
IPAddress ip(192, 168, 178, 17);
IPAddress gateway(192, 168, 178, 1);
IPAddress subnet(255, 255, 255, 0);


void setup()
{
  // serial setup
  Serial.begin(9600);
  Serial.println("Serial interface started");

  // initialize the ethernet device
  Ethernet.begin(mac, ip, gateway, subnet);   // start etehrnet interface
  Serial.println("Ethernet interface started"); 

  // print your local IP address:
  Serial.print("My IP address: ");
  for (byte thisByte = 0; thisByte < 4; thisByte++) {
    // print the value of each byte of the IP address:
    Serial.print(Ethernet.localIP()[thisByte], DEC);
    Serial.print("."); 
  }
  Serial.println();

    // slave address
  Mb.remSlaveIP = IPAddress(192,168,178,34);

  // Fill MbData
//  Mb.SetBit(0,false);
  Mb.MbData[0] = 0;
  Mb.MbData[1] = 0;
  Mb.MbData[2] = 0;
  Mb.MbData[3] = 0;
  Mb.MbData[4] = 0;
  Mb.MbData[5] = 0;
  Mb.MbData[6] = 0;
  Mb.MbData[7] = 0;
  Mb.MbData[8] = 0;
  Mb.MbData[9] = 0;
  Mb.MbData[10] = 0;
  Mb.MbData[11] = 0;
  
  // print MbData
  for (int i=0;i<12;i++) {
    Serial.print("address: "); Serial.print(i); Serial.print("Data: "); Serial.println(Mb.MbData[i]);
  }
// print menu
  Serial.println(F("0 - print the first 12 words of the MbData space"));
  Serial.println(F("1 - FC 1 - read the first 5 coils from the slave and store them in the lower byte of MbData[1]"));
  Serial.println(F("2 - FC 2 - read the first 5 discrete inputs from the slave and store them in the higer of the MbData[1]"));
  Serial.println(F("3 - FC 3 - read the first 5 registers from the slave and store them in MbData[3..7"));
  Serial.println(F("4 - FC 4 - read the first 5 input registers from the slave and store them in MbData[8..12]"));
  Serial.println(F("5 - FC 5 - write coil 0 of the slave with the bit valeu of MbData[0.0]"));
  Serial.println(F("6 - FC 6 - write register 0 of the slave with MbData[2]"));
  Serial.println(F("7 - FC 15 - write 5 coils of the slave starting with coil 0 with GetBit(16..20"));
  Serial.println(F("8 - Fc 16 - write 5 registers of the slave starting on register 0 with MbData[0..4]"));

  Serial.println(Mb.remSlaveIP);
}

void loop()
{
   if (Serial.available() > 0) {
    // get incoming byte:
    inByte = Serial.read();
    if (inByte == '0') {                                          // print MbData
      for (int i=0;i<12;i++) {
        Serial.print("address: "); Serial.print(i); Serial.print("Data: "); Serial.println(Mb.MbData[i]);
      }
    }  
    if (inByte == '1') {Mb.Req(MB_FC_READ_COILS,               6,6,6);} // 1 // ref, count, pos
    if (inByte == '2') {Mb.Req(MB_FC_READ_DISCRETE_INPUT,      6,6,6);} // 2
    if (inByte == '3') {Mb.Req(MB_FC_READ_REGISTERS,           6,6,6);} // 3
    if (inByte == '4') {Mb.Req(MB_FC_READ_INPUT_REGISTER,      6,6,6);} // 4
    if (inByte == '5') {Mb.Req(MB_FC_WRITE_COIL,               0,0,0);} // 5 // count can be x
    if (inByte == '6') {Mb.Req(MB_FC_WRITE_REGISTER,           7,0,0);} // 6 // count can be x
    if (inByte == '7') {Mb.Req(MB_FC_WRITE_MULTIPLE_COILS,     0,6,0);} // 15
    if (inByte == '8') {Mb.Req(MB_FC_WRITE_MULTIPLE_REGISTERS, 0,6,0);} // 16
  }

  Mb.MbmRun();
//  Mb.MbsRun();
}

wollt mal kurz nachfragen ob du dein System am laufen hast.

Ich möchte folgendes realisieren.
Temperaturen über 1-wire am arduino einlesen und dann per Modbus TCP an Beckhoff SPS CX8090 zur Verarbeitung weitergeben.
(CX8090 läuft Modbus Server)

Arduino und 1-wire funktioniert, jetzt will ich den Arduino als Modbus Client einstellen und die Temperaturen bereitstellen. Hat jemand ein Beispiel für Modbus TCP Client?

Danke

Beispiele aus der Library reichen nicht?

Sorry, leider nicht!
Bin grad völlig überfordert welche Modbus Lib ich für meine Anwendung nehmen muss.

Hab den Sketch oben mal auf meine IP Adresssen abgeändert kommt dann aber folgende Fehler:

Compiling 'Modbus_TCP_TEST' for 'Arduino/Genuino Uno'

ccUG7M1G.ltrans0.ltrans.o*: In function loop
Modbus_TCP_TEST.ino:80: undefined reference to MgsModbus Req(MB_FC, unsigned int, unsigned int, unsigned int)

Error linking for board Arduino/Genuino Uno
Build failed for project 'Modbus_TCP_TEST'
Modbus_TCP_TEST.ino:81: undefined reference to MgsModbus Req(MB_FC, unsigned int, unsigned int, unsigned int)
Modbus_TCP_TEST.ino:82: undefined reference to MgsModbus Req(MB_FC, unsigned int, unsigned int, unsigned int)
Modbus_TCP_TEST.ino:83: undefined reference to MgsModbus Req(MB_FC, unsigned int, unsigned int, unsigned int)
Modbus_TCP_TEST.ino:84: undefined reference to MgsModbus Req(MB_FC, unsigned int, unsigned int, unsigned int)

ccQWITgV.ltrans0.ltrans.o*: C:\Users\Arduino\AppData\Local\Temp\VMBuilds\Modbus_TCP_TEST\uno\Debug\Modbus_TCP_TEST.cpp:89: more undefined references to MgsModbus::Req(MB_FC, unsigned int, unsigned int, unsigned int) follow

ccQWITgV.ltrans0.ltrans.o*: In function loop
Modbus_TCP_TEST.ino:90: undefined reference to MgsModbus MbmRun()

ccQWITgV.ltrans1.ltrans.o*: In function __static_initialization_and_destruction_0
Modbus_TCP_TEST.ino:5: undefined reference to MgsModbus MgsModbus()

collect2.exe*: error: ld returned 1 exit status