Arduino C - Modbus TCP

  • C++

Es gibt 2 Antworten in diesem Thema. Der letzte Beitrag () ist von dive26.

    Arduino C - Modbus TCP

    Hallo liebe Community,

    ich wage einen Schritt aus meiner gewohnten VB.NET Programmierumgebung raus in eine kleine Anwendung auf einem M5Stack Core 2.
    Da wird ja eine Art "C" oder "C++" programmiert.
    Im Großen und Ganzen klappt das auch.

    Ich habe die Library modbus-esp8266-master eingebunden, welche eine Modbus TCP Verbindung anbietet.
    Es gibt auch einen Beispielcode wie man ein HoldingRegister ausliest.


    Die Beschreibung der Funktion:

    C-Quellcode

    1. uint16_t readHreg(IPAddress ip, uint16_t offset, uint16_t* value, uint16_t numregs = 1, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);


    Mein Code:

    C-Quellcode

    1. // Beispiel:
    2. // IP: 192.168.0.188
    3. // Modbus-ID des Gerätes: 3
    4. // Register 32064
    5. // 2 Bytes sollen ausgelesen werden (Int32)
    6. //
    7. // IPAddress Huawei_MB_IP_Address(192, 168, 0, 188);
    8. // const int REG_Inverter_InputPower = 32064;
    9. // uint16_t result_UINT16 = 0;
    10. // int Huawei_Modbus_ID_Inverter1 = 3;
    11. //
    12. // Dies ist die Zeile die aus dem Source-Code-Beispiel stammt. Da fehlt aber die Modbus-ID
    13. // Huawei_MB_Client.readHreg(Huawei_MB_IP_Address, REG_Inverter_InputPower, &result_UINT16);
    14. Huawei_MB_Client.readHreg(Huawei_MB_IP_Address, REG_Inverter_InputPower, &result_UINT16, 1, nullptr ,Huawei_Modbus_ID_Inverter1);


    Bei meinem Code habe ich aber nur das UIN'T16 und 1 Registerstelle angegeben.
    Wie muss der Code aussehen bei einem Register das 2 Bytes lang ist?
    Bilder
    • HoldingRegister_wieModbus_ID_angeben.jpg

      276,71 kB, 1.077×802, 81 mal angesehen
    Liebe Grüße
    Roland Berghöfer

    Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „dive26“ ()

    Hey dive26,

    kannst du dein Vorhaben mal genau erklären? Warum mit einem Arduino? Willst du eigene Hardware bauen? Oder willst du nur einen "Server" preisgünstig laufen lassen?
    Bei letzterem: Nimm einen Raspberry PI, gibt da auch schöne Gehäuse mit Touchscreen, wobei das auch gut ohne Monitor geht, Datenaustausch usw. via SSH, Server ist dann wie gewohnt via TCP erreichbar.


    Gerade eben erstmal geschaut, was genau dieses "M5Stack Core 2" ist, tolles Spielzeug :thumbsup: Kannte ich noch nicht. Allerdings zu teuer, für das Geld bau ich 4-5 davon.

    Also ich sehe nun mehrere Wege nach Rom.
    Ein Register besteht ja aus 2 Bytes, also int16/uint16 aka Short in NET. Du hast geschrieben 2 Bytes sollen ausgelesen werden, in Klammern int32, die Zahl hinter int steht für die Anzahl an Bits, int32 also 32 bit, 32 / 8 = 4 Bytes

    Also wenn du einfach einen uint16 zu uint32 haben willst, caste

    C-Quellcode

    1. uint16_t num16 = 1234;
    2. uint32_t num32 = (uint32_t)num16;

    willst du 2 uint16_t zu einem int32_t "verschmelzen"

    C-Quellcode

    1. uint16_t num1 = 0; //most significant
    2. uint16_t num2 = 1;
    3. uint32_t numResult = (uint32_t) num1 << 16 | num2;
    4. //ergibt 1 als int32_t


    Du kannst also einfach auch 2 Register auslesen und so verschmelzen. Aber vorher würde ich was anderes probieren.
    Ich sehe man kann die Anzahl an Registern die gelesen werden sollen angeben.

    Ich täte einfach das probieren:

    C-Quellcode

    1. uint32_t res;
    2. Huawei_MB_Client.readHreg(Huawei_MB_IP_Address, REG_Inverter_InputPower, &res, 2, nullptr ,Huawei_Modbus_ID_Inverter1);


    Falls du nun nicht weist was ein Pointer ist, wird dich das wohl irritieren. Mit dem & wird hier auf die Adresse im Speicher gezeigt, an dieser Adresse wird dann der Wert hingeschrieben, siehe Elandas C++ Tutorial, da sollten Pointer(Zeiger) erklärt sein. Sollte das nicht gehen, lese die beiden Register aus und verschmelze die Werte.

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „BitBrösel“ ()

    Vielen lieben Dank.
    Werde das gleich ausprobieren, sobald das Gerät da ist.

    Das mit dem Pointer war mir klar. Aber nicht, wie man einen größeren Bereich reserviert, damit kein Überlauf entsteht.
    Aber wie Du schon richtig schreibst - einfach probieren und zur Not 2x auslesen und zusammenführen.

    Werde in ein paar Tagen berichten wie es geklappt hat ;-).
    Liebe Grüße
    Roland Berghöfer

    Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at