Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. ioBroker Allgemein
    4. Modbus RS485 Konfiguration

    NEWS

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    • Monatsrückblick - April 2025

    Modbus RS485 Konfiguration

    This topic has been deleted. Only users with topic management privileges can see it.
    • J
      jg last edited by jg

      Modbus seriell (RS485) Konfiguration
      Habe mich zum ersten Mal überhaupt bei einem Forum angemeldet, hoffentlich mache ich nicht zu viele Formfehler.
      Möchte per RS485 Daten zwischen IO-Broker (Raspi4) und einem Microcontroller (Arduino Mega) austauschen. IO-Broker ist aktuell, ebenso der Modbus Adapter (V5.0.11).

      da052cda-6096-4d04-a5cc-5d2b863778e0-grafik.png
      9cdb7927-0cbe-43b8-bfb3-98978c03e0bb-grafik.png
      dda5235d-c53f-424d-ad53-c4b1a72c18b6-grafik.png

      Datenübertragung vom MC zum IOB funktioniert mit Funktion 4 in die Eingangsregister.
      Datenübertragung mit Funktion 3 in die Holdingregister funktioniert auch, benötige ich eigentlich nicht. Wenn ich die "Abfrage" in der Konfig Holdingregister abschalte, kommt kein Protokoll 3 mehr an. Allerdings auch kein Protokoll 6 (bzw.16) je nach Auswahl in der allgemeinen Instanzeinstellung. Nach meinem Verständnis erwarte ich bei der Konfiguration der Holdingregister "Abfrage" nein und "CW" ja entsprechene Anfragen vom Master (IOB) mit Funktion 6 bzw. 16. Leider gelingt mir die gewünschte Datenübertragung nicht.
      Bei der Konfiguration "Abfrage" ja und "CW" ja erscheint das von mir nicht benötigte Protokoll 3 und auch 4 Protokolle 6 (bzw.16 je nach Konfig) für die 4 konfigurierten Holdingregister, allerdings alle mit dem Inhalt 0. siehe Monitorausschrift vom Arduino:

      a9e315ed-7074-47f3-bf65-573e273f638c-grafik.png

      Kann mir bitte jemand Hinweise zur Konfiguration des Modbusadapters geben, um die gewünschten Protokolle 6 bzw. 16 mit Dateninhalt zu erhalten?

      hier noch die Log Einträge:

      8579dc9d-d19b-491f-aa73-70ac4e6d0a63-grafik.png
      Danke, Jörg

      Homoran 1 Reply Last reply Reply Quote 0
      • Homoran
        Homoran Global Moderator Administrators @jg last edited by Homoran

        @jg sagte in Modbus RS485 Konfiguration:

        hoffentlich mache ich nicht zu viele Formfehler.

        naja, den ArduinoCode und das log bitte als Text in code-tags 🙂


        hast du eine Beschreibung der Register für den Arduino?

        BTW RS485 ist nicht Modbus!

        J 2 Replies Last reply Reply Quote 0
        • J
          jg @Homoran last edited by

          @homoran
          hier der komplette Arduino Code, sollte an sich kein Problem im Code sein, die Protokolle muß ja der IOB als Master initiieren, der Arduino antwortet nur, ist auch einiges nicht notwendiges im Code, da aus einem anderen eigenen Programm kopiert!

          // für Arduino Mega im schmalen Hutschienengehäuse 6 * 4-polig RS485 an tx: 18, rx: 19, txEnabRs485: 17
          
          #define       debugCycle           0
          #define       debugLoop            1
          #define       debugRs485           1
          #define       modBaud              115200      // Modbus Baudrate
          #define       modAdr               1           // Modbus Geräteadresse Master
          
          #define       SoftRxPin            31          // RS485   Rx Software Seriell
          #define       SoftTxPin            21          // RS485   Tx Software Seriell
          #define       SoftTxEnab           15          // RS485   Transmit Enable Pin Software Seriell
          //#define       SoftSerial            1          // soft seriell verwenden
          
          #ifdef SoftSerial
          #include <SoftwareSerial.h>
          SoftwareSerial mySerial(SoftRxPin, SoftTxPin, false);        // RX, TX, inversLogic
          #endif
          
          /* Pinbelegung Hutschienengehäuse 24 polig (6 * 4 polig):    Stand 22/01
          * Pin 1.1, 2.1, 3.1, 4.1, 5.1, 6.1:               // Masse
          * Pin 1.4, 2.4, 3.4, 4.4, 5.4, 6.4:               // Versorgungsspannung + 5V
          * Pin 1.2:                             D20        // I2C SDA
          * Pin 1.3:                             D21        // I2C SCL
          * Pin 2.2:                             D2         // frei Interruptfähig
          * Pin 2.3:                             D9         // frei
          * Pin 3.2:                                        // Versorgungsspannung + 24V (9..30V) besser nicht benutzen!
          * Pin 3.3:                             D16        // Tx2
          * Pin 4.2:                             D18        // Tx1
          * Pin 4.3:                             D19        // Rx1
          * Pin 5.2:                             D31        // frei    mit Diode Anode, Diode Katode an Pin D30 für Onewire
          * Pin 5.3:                             D17        // Rx2
          * Pin 6.2:                             D27        // frei    mit Diode Anode, Diode Katode an Pin D26 für Onewire
          * Pin 6.3:                             D15        // Masse
          * Onewire an D30/31 und D27/26: D31, 27 Eingang mit Pullup, D30, D26 Ausgang
          * 24 V Eingang: Schaltregler auf 5V mit Supressordiode 6V ohne Sicherung!
          * Achtung: 4polige Stecker vertauschen Pins bei Verwendung auf anderer Gehäuseseite! 1,2,3 sind gleich, 4,5,6 auch
          */
          
          //storage variables
          //Definitionen E/A:
          //Pin 0 Rx USB
          //Pin 1 Tx USB
          #define       resLan               42              // Reset ethernet shield (MEGA2560)
          #define       taste                44              // Taste Pullup gegen Masse
          #define       ledR                 45              // LED 3Color Rot
          #define       ledG                 46              // LED 3Color Grün
          #define       ledB                 47              // LED 3Color Blau
          #define       csSd                 48              // ChipSelect SD card 
          #define       csLan                53              // ChipSelect ethernet shield (MEGA2560)
          #define       rd485send            17              // Umschaltung max485 auf Senden
          #define       solar600Ein           8              // Solarpumpe alt (600 Liter) ein
          #define       heizungBadEin         7              // Heizungspumpe Bad / Terrasse ein
          #define       nachheizung2Ein      22              // Nachheizungspumpe Speicher alt (600 Liter) ein
          
          //SPI wird z.B. von LAN und SD-card extern verwendet
          //Pins 10(SPI_CS), 11(MOSI), 12(MISO) & 13(SCK) werden vom ethernet shield verwendet (UNO, NANO)
          //Pins 53(SPI_CS), 51(MOSI), 50(MISO) & 52(SCK) werden vom ethernet shield verwendet (MEGA2560)
          //I2C wird z.B. von EEPROM extern per wire.h verwendet
          //Pin A4(SDA) und A5(SCL) (UNO, NANO)
          //Pin D20(SDA) und D21(SCL) (MEGA2560)
          
          // Variablen für Verwendung in Interrupt Service Routinen sind volatile zu vereinbaren
          unsigned int n;
          unsigned long milliAlt, diffLoop;
          
          bool writePar;
          int stunde;
          int minuten;
          int wochentag;
          int datum;
          int monat;
          int jahr;
          
          int inTag=255;
          int inStunde=16;
          int inMinute=30;
          int inTemp=200;                                   // entspricht 20°C
          int x=0;
          int anzahl;                                       // Anzahl Zeichen für Modbus Sendung
          
          bool          tasteOld, tasteAct, tasteFp, tasteFn;
          
          bool          t0sel,t1sel,t2sel,t3sel,t4sel,t5sel,t6sel,t7sel,t1min,t8min,t64min;
          bool          t0done,t1done,t2done,t3done,t4done,t5done,t6done,t7done,t1minDone;
          
          //************************************************************************************************************************
          
          // volatile zur Verwendung im Interrupt
          volatile int ledRms, ledGms, ledBms;
          volatile int intms, intsec, int10sec, intmin, intstunde, inttag;
          volatile bool boolsec, bool10sec, boolmin, boolstunde, booltag, boolwoche;
          bool impulsSec, impuls10Sec, impulsMin, impulsStunde, impulsTag, impulsWoche, rstrt;
          
          #define       stx                 2           //StartOfText
          #define       etx                 3           //EndOfText
          #define       nul                 0           //Null
          #define       maxBuffer           64          //size of serial buffer
          char rcvBuffer1[maxBuffer+1], rcvBuffer2[maxBuffer+1], sendBuffer1[maxBuffer+1], readChar;
          bool serial1block2, enableSend03, enableSend04, enableSend06, enableSend16, timeoutMod;
          uint16_t  serial1pointer, serial2pointer, recAnzZei, crcRcv;
          uint32_t timeMod;
          
          
          //************************* F U N K T I O N E N **************************************************************************
          
          uint16_t crc1(byte *z, byte l) {
            uint16_t sum = 0xFFFF;                                                      // Startwert 0xFFFFh
            for (int i=0;i<l;i++) {                                                     // CRC16 berechnen nach Modbus RTU
              sum = sum ^ *z++;
              for (int j=8;j>0;j--) {
                 if((sum & 0x01) == 0) { sum >>= 1; }                                   // crc16 polynom (X16 + X15 + X2 + 1):
                 else { sum >>= 1; sum ^= 0xA001; }                                     // 0xA001 = 1010 0000 0000 0001
              }                                                                         // Berechnung vlnr oder vrnl!:
            }                                                                           // 0x8005 = 1000 0000 0000 0101
            return(sum);
          }
          
          uint16_t crc (byte *z, byte l) {
          static const word wCRCTable[] PROGMEM = {
          0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
          0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
          0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
          0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
          0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
          0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
          0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
          0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
          0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
          0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
          0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
          0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
          0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
          0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
          0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
          0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 };
          
          uint16_t sum = 0xFFFF; 
            while (l--)
            {
               byte nTemp = *z++ ^ sum;
               sum >>= 8;
               sum ^= pgm_read_word(&wCRCTable[nTemp]);
            }
            return (sum);
          }
          
          
          void intToAscii (int i, byte *z){                                     // integer Zahl in 4 ASCII Zeichen wandeln
          *z = (((i>>12) & 0xf) + 0x30); if(*z > 0x39) *z += 7;
          z++;
          *z = (((i>>8) & 0xf) + 0x30); if(*z > 0x39) *z += 7;
          z++;
          *z = (((i>>4) & 0xf) + 0x30); if(*z > 0x39) *z += 7;
          z++;
          *z = (((i>>0) & 0xf) + 0x30); if(*z > 0x39) *z += 7;
          }
          
          int asciiToInt (byte *z){                                            // 4 ASCII Zeichen in integer Zahl in wandeln
          int a, b;
          if(*z > 0x39) a = *z - 0x37; else a = *z - 0x30;
          z++; b = (a << 4);
          if(*z > 0x39) a = *z - 0x37; else a = *z - 0x30;
          z++; b = ((b + a) << 4);
          if(*z > 0x39) a = *z - 0x37; else a = *z - 0x30;
          z++; b = ((b + a) << 4);
          if(*z > 0x39) a = *z - 0x37; else a = *z - 0x30;
          return (b + a);
          }
          void hexByte(byte zeichen) {
           if (zeichen < 16) Serial.print('0');
           Serial.print(highByte(unsigned(zeichen)), HEX); 
           Serial.print(lowByte(unsigned(zeichen)), HEX); 
           Serial.print(' ');
          }
          
          //************************* S E T U P ************************************************************************************
          void setup(){
           cli();                                           // stop interrupts
                                                            // set timer1 interrupt
           TCCR1A = 0;                                      // set entire TCCR1A register to 0
           TCCR1B = 0;                                      // same for TCCR1B
           TCNT1  = 0;                                      // initialize counter value to 0
           // set compare match register: 7999 entspricht 2KHz/prescaler
           OCR1A = 19999;// = (16*10^6) / (1*prescaler) - 1 (must be <65536) entspricht 1KHz
           // turn on CTC mode
           TCCR1B |= (1 << WGM12);
           // Set CS10, CS11 and CS12 bits for prescaler 1=1, 2=8, 3=64, 4=256, 5=1024
           TCCR1B |= (0 << CS12) | (1 << CS11) | (0 << CS10);
           // enable timer compare interrupt
           TIMSK1 |= (1 << OCIE1A);
          
           sei();                                           // allow interrupts vor aufruf wire notwendig!
           pinMode(rd485send, OUTPUT);                      // pin als Ausgang deklarieren CS ADS1118 Modul
           digitalWrite(rd485send,LOW);                     // max485 empfangen
           Serial.begin(115200);
           Serial.println("Setup gestartet");
           Serial1.begin(modBaud);                          // 250000 geht, getestet
           Serial.print("Modbus Baudrate: "); Serial.println(modBaud);
           //Serial2.begin(57600);
          
          #ifdef SoftSerial
           pinMode(SoftTxEnab, OUTPUT);
           digitalWrite(SoftTxEnab,LOW);                                 // Freigabe Empfangen an Max485
           mySerial.begin(2000);
           Serial.println("Setup SoftSerial beendet");
          #endif
          
           rstrt = true;                                    // Restart Merker setzen
           Serial.println("Setup beendet");
          }  //end setup
          
          //************************* I N T E R R U P T   T I M E R   1   Z E I T   1 0 m s ****************************************
          
          ISR(TIMER1_COMPA_vect){  //timer 1 interrupt
           
          intms++;
          if (intms     >=  100) {boolsec    = true; intms     = 0; intsec++;    }
          if (intsec    >=   10) {bool10sec  = true; intsec    = 0; bool10sec++;    }
          if (int10sec  >=    6) {boolmin    = true; int10sec  = 0; intmin++;    }
          if (intmin    >=   60) {boolstunde = true; intmin    = 0; intstunde++; }
          if (intstunde >=   24) {booltag    = true; intstunde = 0; inttag++;    }
          if (inttag    >=    7) {boolwoche  = true; inttag    = 0;              }
          
          }  //end isr timer 1 interrupt
          
          
          //********************************* M A I N ******************************************************************************
          
          
          //    O O         O O           O O           O O O O     O O         O O 
          //    O O O     O O O         O O O O           O O       O O O       O O
          //    O O O O O O O O       O O     O O         O O       O O O O     O O 
          //    O O   O O   O O     O O         O O       O O       O O   O O   O O
          //    O O         O O     O O O O O O O O       O O       O O     O O O O
          //    O O         O O     O O         O O       O O       O O       O O O 
          //    O O         O O     O O         O O     O O O O     O O         O O
          
          void loop() {
           cli();                                                              // stop interrupts
           if (boolsec)    {impulsSec    = true; boolsec    = false;}
           if (bool10sec)  {impuls10Sec  = true; bool10sec  = false;}
           if (boolmin)    {impulsMin    = true; boolmin    = false;}
           if (boolstunde) {impulsStunde = true; boolstunde = false;}
           if (booltag)    {impulsTag    = true; booltag    = false;}
           if (boolwoche)  {impulsWoche  = true; boolwoche  = false;}
           sei();                                                              // allow interrupts
          
           t0sel = (milliAlt & 0b00000000001110000000000) == 0b0;                   // 0 ms
           t1sel = (milliAlt & 0b00000000001110000000000) == 0b0010000000000;       // 1024 ms
           t2sel = (milliAlt & 0b00000000001110000000000) == 0b0100000000000;       // 2048 ms
           t3sel = (milliAlt & 0b00000000001110000000000) == 0b0110000000000;       // 3072 ms
           t4sel = (milliAlt & 0b00000000001110000000000) == 0b1000000000000;       // 4096 ms
           t5sel = (milliAlt & 0b00000000001110000000000) == 0b1010000000000;       // 5120 ms
           t6sel = (milliAlt & 0b00000000001110000000000) == 0b1100000000000;       // 6144 ms
           t7sel = (milliAlt & 0b00000000001110000000000) == 0b1110000000000;       // 7188 ms
           t1min = (milliAlt & 0b00000001110000000000000) == 0;                     // 65,536 s
           t8min = (milliAlt & 0b00001111110000000000000) == 0;                     // 524,288 s
           t64min = (milliAlt & 0b1111111110000000000000) == 0;                     // 4194,304 s
           if (!t0sel) {t0done = false;}
           if (!t1sel) {t1done = false;}
           if (!t2sel) {t2done = false;}
           if (!t3sel) {t3done = false;}
           if (!t4sel) {t4done = false;}
           if (!t5sel) {t5done = false;}
           if (!t6sel) {t6done = false;}
           if (!t7sel) {t7done = false;}
           if (!t1min) {t1minDone = false;}
          //  if (t4sel && t1min) {}
          //  if (t5sel && t1min) {}
          /*  Serial.println(milliAlt);
           Serial.print(t0sel);
           Serial.print(t1sel);
           Serial.print(t2sel);
           Serial.print(t3sel);       
           Serial.print(t4sel);
           Serial.print(t5sel);
           Serial.print(t6sel);
           Serial.println(t7sel);*/
          
          //************************* R E C E I V E   1    M O D B U S   S E R I A L ****************************************************
           //  if (Serial1.available() > 5) Serial.println(Serial1.available());
            timeoutMod = (timeMod < (millis()-10));
            while (Serial1.available()) {
               timeMod = millis();
               if (serial1pointer >= maxBuffer) serial1pointer = maxBuffer - 1;
               readChar = Serial1.read();  
               if (timeoutMod) { serial1pointer = 0; recAnzZei = 12; }          // Geräteadresse prüfen
               rcvBuffer1[serial1pointer] = readChar;
               if (serial1pointer > 2) {
                 // if (rcvBuffer1[1] == 3) recAnzZei = 4;
                 // if (rcvBuffer1[1] == 4) recAnzZei = 4;
                 // if (rcvBuffer1[1] == 6) recAnzZei = 4;
                 if (rcvBuffer1[1] == 16) recAnzZei = 7; else recAnzZei = 4;
                 //Serial.println(recAnzZei);
               }
               if (debugRs485 && 0) {Serial.print(serial1pointer); Serial.print(": "); Serial.print(readChar); Serial.print(", "); Serial.println(readChar,HEX);}                                                 // read the incoming byte
               if (serial1pointer == recAnzZei + 3) {
                   crcRcv = ((lowByte(rcvBuffer1[recAnzZei+3])<<8) + lowByte(rcvBuffer1[recAnzZei+2]));
                   rcvBuffer1[serial1pointer+1] = nul;
                   if (debugRs485) {Serial.print("Empfangen: ");                 // an Monitor
                                    for (int i=0; i<recAnzZei + 4; i++) {
          //                             Serial.print(highByte(unsigned(rcvBuffer1[i])), HEX); Serial.print(lowByte(unsigned(rcvBuffer1[i])), HEX); Serial.print(' ');
                 hexByte(rcvBuffer1[i]);
                                    }
                                    Serial.print(", CRC Buffer: "); Serial.print(crcRcv,HEX);
                                    Serial.print(", CRC berechnet: "); Serial.print(crc(&rcvBuffer1[0],(recAnzZei+2)),HEX);
                                    Serial.print(", "); Serial.print(serial1pointer + 1); Serial.println(" Zeichen"); 
                   }
                   if (crc(&rcvBuffer1[0],(recAnzZei+2))==crcRcv) {
                     // hier empfangene Werte verarbeiten
                     // if (debugRs485) {Serial.print(" rcv1 1 o.k., Funktionscode: "); Serial.println(rcvBuffer1[1], HEX);} // an Monitor   
                     if (rcvBuffer1[1] == 3) enableSend03 = true;             // Funktionscode 03: senden Integerwerte
                     if (rcvBuffer1[1] == 4) enableSend04 = true;             // Funktionscode 04: senden Integerwerte
                     if (rcvBuffer1[1] == 6) enableSend06 = true;             // Funktionscode 06: empfangen Integerwerte
                     if (rcvBuffer1[1] == 16) enableSend16 = true;            // Funktionscode 16: empfangen Integerwerte
                   } else 
                   {
                     if (debugRs485) Serial.println(" rcv1: CRC n.o.k."); // an Monitor 
                   }
               }
               serial1pointer++;   
            }
          //************************* S E N D **************************************************************************************
          /* Modbus Beschreibungen  
          **************************************************************************************************************************
          Befehle:
          FUNKTIONSKODE  WAS DIE FUNKTION TUT                                                               WERTTYP     ZUGRIFFSTYP
          01 (0x01)      Liest DO                       Read Discrete Output Coil                           Diskret     Lesen
          02 (0x02)      Liest DI                       Read Discrete Input Contact                         Diskret     Lesen
          03 (0x03)      Liest AO                       Read Analog Output Holding Register                 16 Bit      Lesen
          04 (0x04)      Liest AI                       Read Analog Input Register                          16 Bit      Lesen
          05 (0x05)      Schreibt ein DO                Setzen einer Discrete Output Coil                   Diskret     Schreiben
          06 (0x06)      Schreibt ein AO                Setzen eines Analog Output Holding Registers        16 Bit      Schreiben
          15 (0x0F)      Aufzeichnung mehrerer DOs      Setzen mehrerer Discrete Output Coil                Diskret     Schreiben
          16 (0x10)      Aufzeichnung mehrerer AOs      Setzen mehrerer Analog Output Holding Registers     16 Bit      Schreiben
          **************************************************************************************************************************
          REGISTERNUMMER REGISTERADRESSE HEX  TYP             NAME                            TYP
          1-9999         0000 to 270E         lesen-schreiben Discrete Output Coils           DO
          10001-19999    0000 to 270E         lesen Discrete  Input Contacts                  DI
          30001-39999    0000 to 270E         lesen Analog    Input Registers                 AI
          40001-49999    0000 to 270E         lesen-schreiben Analog Output Holding Registers AO
          **************************************************************************************************************************
          BYTE  ANFRAGE                                 BYTE  ANTWORT
          (Hex) Feldname                                (Hex) Feldname
          11  Geräteadresse                             11    Geräteadresse
          01  Funktionaler Code                         01    Funktionaler Code
          00  Adresse des ersten Registers Hi Bytes     05    Anzahl der Antwortbytes
          13  Adresse des ersten Registers Lo Bytes     CD    Registerwert DO 27-20 (1100 1101)
          00  Anzahl der Register Hi Bytes              6B    Registerwert DO 35-28 (0110 1011)
          25  Anzahl der Register Lo Bytes              B2    Registerwert DO 43-36 (1011 0010)
          0E  Prüfsumme CRC                             0E    Registerwert DO 51-44 (0000 1110)
          84  Prüfsumme CRC                             1B    Registerwert DO 56-52 (0001 1011)
                                                       45    Prüfsumme CRC
                                                       E6    Prüfsumme CRC
          **************************************************************************************************************************
          BYTE  ANFRAGE                                 BYTE  ANTWORT
          (Hex) Feldname                                (Hex) Feldname
          11  Geräteadresse                             11    Geräteadresse
          02  Funktionaler Code                         02    Funktionaler Code
          00  Adresse des ersten Registers Hi Bytes     03    Anzahl der Antwortbytes
          C4  Adresse des ersten Registers Lo Bytes     AC    Registerwert DI 10204-10197 (1010 1100)
          00  Anzahl der Register Hi Bytes              DB    Registerwert DI 10212-10205 (1101 1011)
          16  Anzahl der Register Lo Bytes              35    Registerwert DI 10218-10213 (0011 0101)
          BA  Prüfsumme CRC                             20    Prüfsumme CRC
          A9  Prüfsumme CRC                             18    Prüfsumme CRC
          **************************************************************************************************************************
          BYTE  ANFRAGE                                 BYTE  ANTWORT
          (Hex) Feldname                                (Hex) Feldname
          11  Geräteadresse                             11    Geräteadresse
          03  Funktionaler Code                         03    Funktionaler Code
          00  Adresse des ersten Registers Hi Bytes     06    Anzahl der Antwortbytes bei 16bit pro Wert)
          6B  Adresse des ersten Registers Lo Bytes     AE    Registerwert Hi #40108
          00  Anzahl der Register Hi Bytes              41    Registerwert Lo #40108
          03  Anzahl der Register Lo Bytes              56    Registerwert Hi #40109
          76  Prüfsumme CRC                             52    Registerwert Lo #40109
          87  Prüfsumme CRC                             43    Registerwert Hi #40110
                                                       40    Registerwert Lo #40110
                                                       49    Prüfsumme CRC
                                                       AD    Prüfsumme CRC
          **************************************************************************************************************************
          BYTE  ANFRAGE                                 BYTE  ANTWORT
          (Hex) Feldname                                (Hex) Feldname
          11  Geräteadresse                             11    Geräteadresse
          04  Funktionaler Code                         04    Funktionaler Code
          00  Adresse des ersten Registers Hi Bytes     02    Anzahl der Antwortbytes
          08  Adresse des ersten Registers Lo Bytes     00    Registerwert Hi #30009
          00  Anzahl der Register Hi Bytes              0A    Registerwert Lo #30009
          01  Anzahl der Register Lo Bytes              F8    Prüfsumme CRC
          B2  Prüfsumme CRC                             F4    Prüfsumme CRC
          98  Prüfsumme CRC 
          **************************************************************************************************************************
          BYTE  ANFRAGE                                 BYTE  ANTWORT
          (Hex) Feldname                                (Hex) Feldname
          11  Geräteadresse                             11    Geräteadresse
          05  Funktionaler Code                         05    Funktionaler Code
          00  Adresse des ersten Registers Hi Bytes     00    Adresse des ersten Registers Hi Bytes
          AC  Adresse des ersten Registers Lo Bytes     AC    Adresse des ersten Registers Lo Bytes
          FF  Wert der Hi Bytes                         FF    Wert der Hi Bytes
          00  Wert der Lo Bytes                         00    Wert der Lo Bytes
          4E  Prüfsumme CRC                             4E    Prüfsumme CRC
          8B  Prüfsumme CRC                             8B    Prüfsumme CRC
          **************************************************************************************************************************
          BYTE  ANFRAGE                                 BYTE  ANTWORT
          (Hex) Feldname                                (Hex) Feldname
          11  Geräteadresse                             11    Geräteadresse
          06  Funktionaler Code                         06    Funktionaler Code
          00  Adresse des ersten Registers Hi Bytes     00    Adresse des ersten Registers Hi Bytes
          01  Adresse des ersten Registers Lo Bytes     01    Adresse des ersten Registers Lo Bytes
          00  Wert der Hi Bytes                         00    Wert der Hi Bytes
          03  Wert der Lo Bytes                         03    Wert der Lo Bytes
          9A  Prüfsumme CRC                             9A    Prüfsumme CRC
          9B  Prüfsumme CRC                             9B    Prüfsumme CRC
          **************************************************************************************************************************
          BYTE  ANFRAGE                                 BYTE  ANTWORT
          (Hex) Feldname                                (Hex) Feldname
          11  Geräteadresse                             11    Geräteadresse
          0F  Funktionaler Code                         0F    Funktionaler Code
          00  Adresse des ersten Registers Hi Bytes     00    Adresse des ersten Registers Hi Bytes
          13  Adresse des ersten Registers Lo Bytes     13    Adresse des ersten Registers Lo Bytes
          00  Anzahl der zu beschr. Register Hi Bytes   00    Anzahl der gesetzten Register Hi Bytes
          0A  Anzahl der zu beschr. Register Lo Bytes   0A    Anzahl der gesetzten Register Lo Bytes
          02  Anz Bytes, die die zu setz. Werte enthalt.26    Prüfsumme CRC
          CD  Wert des Bytes für die Register           99    Prüfsumme CRC
             27-20 (1100 1101)                         
          01  Wert des Bytes für die Register 
             29-28 (0000 0001) 
          BF  Prüfsumme CRC
          0B  Prüfsumme CRC
          **************************************************************************************************************************
          BYTE  ANFRAGE                                 BYTE  ANTWORT
          (Hex) Feldname                                (Hex) Feldname
          11  Geräteadresse                             11    Geräteadresse
          10  Funktionaler Code                         10    Funktionaler Code
          00  Adresse des ersten Registers Hi Bytes     00    Adresse des ersten Registers Hi Bytes
          01  Adresse des ersten Registers Lo Bytes     01    Adresse des ersten Registers Lo Bytes
          00  Anzahl der Register Hi Bytes              00    Anzahl der aufgezeichneten Register Hi Bytes
          02  Anzahl der Register Lo Bytes              02    Anzahl der aufgezeichneten Register Lo Bytes
          04  Anz der Bytes, die gesetzt werden sollen. 12    Prüfsumme CRC
             Hier: 2 Werte mit je 16bit.
          00  Wert Hi 40002                             98    Prüfsumme CRC
          0A  Wert Lo 40002 
          01  Wert Hi 40003
          02  Wert Lo 40003
          C6  Prüfsumme CRC
          F0  Prüfsumme CRC
          **************************************************************************************************************************
          */
           
           
           
           if (enableSend03) {
              digitalWrite(rd485send,HIGH);                                     // max485 senden
              // 11 04 27 7B 00 03 C8 36       Beispiel
             anzahl         = 5;                                                         // von [0] bis 2.Byte CRC == Index letztes byte + 1
              sendBuffer1[0] = modAdr;                                                   // Geräteadresse
              sendBuffer1[1] = 0x03;                                                     // Funktionscode
              sendBuffer1[2] = 0x00;                                                     // Anzahl der Antwort-Bytes 
              sendBuffer1[3] = char((crc(&sendBuffer1[0],(anzahl-2))) & 0xff);           // Prüfsumme CRC
              sendBuffer1[4] = char(((crc(&sendBuffer1[0],(anzahl-2))) >> 8) & 0xff);    // Prüfsumme CRC
          
              anzahl         = 15;                                                       // von [0] bis 2.Byte CRC == Index letztes byte + 1
              sendBuffer1[0] = modAdr;                                                   // Geräteadresse
              sendBuffer1[1] = 0x03;                                                     // Funktionscode
              sendBuffer1[2] = 0x0A;                                                     // Anzahl der Antwort-Bytes 
              sendBuffer1[3] = 0x00;                                                     // Wert des high Registerbytes 1
              sendBuffer1[4] = 0x0A;                                                     // Wert des low Registerbytes 1
              sendBuffer1[5] = 0x00;                                                     // Wert des high Registerbytes 2
              sendBuffer1[6] = 0xAA;                                                     // Wert des low Registerbytes 2
              sendBuffer1[7] = 0x00;                                                     // Wert des high Registerbytes 3
              sendBuffer1[8] = 0x55;                                                     // Wert des low Registerbytes 3
              sendBuffer1[9] = 0x00;                                                     // Wert des high Registerbytes 4
              sendBuffer1[10] = 0x05;                                                    // Wert des low Registerbytes 4
              sendBuffer1[11] = 0x00;                                                    // Wert des high Registerbytes 5
              sendBuffer1[12] = 0x05;                                                    // Wert des low Registerbytes 5
              sendBuffer1[13] = char((crc(&sendBuffer1[0],(anzahl-2))) & 0xff);          // Prüfsumme CRC
              sendBuffer1[14] = char(((crc(&sendBuffer1[0],(anzahl-2))) >> 8) & 0xff);   // Prüfsumme CRC
          
              anzahl         = 13;                                                       // von [0] bis 2.Byte CRC == Index letztes byte + 1
              sendBuffer1[0] = modAdr;                                                   // Geräteadresse
              sendBuffer1[1] = 0x03;                                                     // Funktionscode
              sendBuffer1[2] = 0x08;                                                     // Anzahl der Antwort-Bytes == 4 * Integer
              sendBuffer1[3] = 0x00;                                                     // Wert des high Registerbytes 1
              sendBuffer1[4] = char(random(0,255));//0x0A;                               // Wert des low Registerbytes 1
              sendBuffer1[5] = 0x00;                                                     // Wert des high Registerbytes 2
              sendBuffer1[6] = char(random(0,255));//0xAA;                               // Wert des low Registerbytes 2
              sendBuffer1[7] = 0x00;                                                     // Wert des high Registerbytes 3
              sendBuffer1[8] = char(random(0,255));//0x55;                               // Wert des low Registerbytes 3
              sendBuffer1[9] = 0x00;                                                     // Wert des high Registerbytes 4
              sendBuffer1[10] = char(random(0,255));//0x05;                              // Wert des low Registerbytes 4
              sendBuffer1[11] = 0x00;                                                    // Wert des high Registerbytes 5
              sendBuffer1[12] = char(random(0,255));//0x05;                              // Wert des low Registerbytes 5
              sendBuffer1[11] = char((crc(&sendBuffer1[0],(anzahl-2))) & 0xff);          // Prüfsumme CRC
              sendBuffer1[12] = char(((crc(&sendBuffer1[0],(anzahl-2))) >> 8) & 0xff);   // Prüfsumme CRC
          
              Serial.print("     Send: ");
              for (int i=0; i<anzahl; i++) {
                 Serial1.write(sendBuffer1[i]);
                 hexByte(sendBuffer1[i]);
              }
              //Serial.println(); 
              //for (int i=0; i<anzahl; i++) { Serial.write(sendBuffer1[i]); } 
              Serial.print(",     ");// Serial.print("  CRC: "); Serial.print(crc(&sendBuffer1[0],(anzahl-2)),HEX);
              for (int i=0; i<anzahl; i++) { Serial.print(", "); Serial.print(byte(sendBuffer1[i])); } 
              Serial.println(); 
                 
              if (debugRs485 && 0) {Serial.print("Send 3 ");                        // an Monitor
                                    Serial.println(sendBuffer1);
                                    for (int i=0; i<maxBuffer; i++) {
                                      Serial.print(highByte(unsigned(sendBuffer1[i])), HEX); Serial.print(lowByte(unsigned(sendBuffer1[i])), HEX); Serial.print(' ');
                                      // if (sendBuffer1[i] == 0) break;
                                    }
                                    Serial.println();
              }
            enableSend03 = false;
          
            for (int i=0;i<maxBuffer;i++) sendBuffer1[i] = 0x00;              // Puffer löschen
            
            Serial1.flush();                                                  // Waits for the transmission of outgoing serial data to complete
            //delayMicroseconds(10);
            digitalWrite(rd485send,LOW);                                      // max485 empfangen
           
            } // end send answer 3
          
           if (enableSend04) {
              digitalWrite(rd485send,HIGH);                                     // max485 senden
              // 11 04 27 7B 00 03 C8 36       Beispiel
              anzahl         = 13;                                                       // von [0] bis 2.Byte CRC == Index letztes byte + 1
              sendBuffer1[0] = modAdr;                                                   // Geräteadresse
              sendBuffer1[1] = 0x04;                                                     // Funktionscode
              sendBuffer1[2] = 0x08;                                                     // Anzahl der Antwort-Bytes == 4 * Integer
              sendBuffer1[3] = 0x00;                                                     // Wert des high Registerbytes 1
              sendBuffer1[4] = char(random(0,255));//0x0A;                               // Wert des low Registerbytes 1
              sendBuffer1[5] = 0x00;                                                     // Wert des high Registerbytes 2
              sendBuffer1[6] = char(random(0,255));//0xAA;                               // Wert des low Registerbytes 2
              sendBuffer1[7] = 0x00;                                                     // Wert des high Registerbytes 3
              sendBuffer1[8] = char(random(0,255));//0x55;                               // Wert des low Registerbytes 3
              sendBuffer1[9] = 0x00;                                                     // Wert des high Registerbytes 4
              sendBuffer1[10] = char(random(0,255));//0x05;                              // Wert des low Registerbytes 4
              sendBuffer1[11] = char((crc(&sendBuffer1[0],(anzahl-2))) & 0xff);          // Prüfsumme CRC
              sendBuffer1[12] = char(((crc(&sendBuffer1[0],(anzahl-2))) >> 8) & 0xff);   // Prüfsumme CRC
          
              Serial.print("     Send: ");
              for (int i=0; i<anzahl; i++) {
                 Serial1.write(sendBuffer1[i]);
                 hexByte(sendBuffer1[i]);
              }
              Serial.print(",     ");// Serial.print("  CRC: "); Serial.print(crc(&sendBuffer1[0],(anzahl-2)),HEX);
              for (int i=0; i<anzahl; i++) { Serial.print(", "); Serial.print(byte(sendBuffer1[i])); } 
              Serial.println(); 
                 
              if (debugRs485 && 0) {Serial.print("Send 4: ");                        // an Monitor
                                    Serial.println(sendBuffer1);
                                    for (int i=0; i<maxBuffer; i++) {
                                      Serial.print(highByte(unsigned(sendBuffer1[i])), HEX); Serial.print(lowByte(unsigned(sendBuffer1[i])), HEX); Serial.print(' ');
                                      // if (sendBuffer1[i] == 0) break;
                                    }
                                    Serial.println();
              }
            enableSend04 = false;
          
            for (int i=0;i<maxBuffer;i++) sendBuffer1[i] = 0x00;              // Puffer löschen
            
            Serial1.flush();                                                  // Waits for the transmission of outgoing serial data to complete
            //delayMicroseconds(10);
            digitalWrite(rd485send,LOW);                                      // max485 empfangen
          
            // delay(10);
            // enableSend06 = true;
            } // end send answer 4
          
           if (enableSend06) {
              digitalWrite(rd485send,HIGH);                                     // max485 senden
              anzahl         = 8;                                                        // von [0] bis 2.Byte CRC == Index letztes byte + 1
              sendBuffer1[0] = modAdr;                                                   // Geräteadresse
              sendBuffer1[1] = 0x06;//rcvBuffer1[1];                                            // Funktionscode
              sendBuffer1[2] = rcvBuffer1[2];                                            // Adresse des ersten Registers Hi Bytes
              sendBuffer1[3] = rcvBuffer1[3];                                            // Adresse des ersten Registers Lo Bytes
              sendBuffer1[4] = rcvBuffer1[4];                                            // Anzahl der aufgezeichneten Register Hi Bytes
              sendBuffer1[5] = rcvBuffer1[5];                                            // Anzahl der aufgezeichneten Register Lo Bytes
              sendBuffer1[6] = char((crc(&sendBuffer1[0],(anzahl-2))) & 0xff);           // Prüfsumme CRC
              sendBuffer1[7] = char(((crc(&sendBuffer1[0],(anzahl-2))) >> 8) & 0xff);    // Prüfsumme CRC
              Serial.print("     Send: ");
              for (int i=0; i<anzahl; i++) {
                 Serial1.write(sendBuffer1[i]);
                 hexByte(sendBuffer1[i]);
              }
              //Serial.println(); 
              //for (int i=0; i<anzahl; i++) { Serial.write(sendBuffer1[i]); } 
              Serial.print(",     ");// Serial.print("  CRC: "); Serial.print(crc(&sendBuffer1[0],(anzahl-2)),HEX);
              for (int i=0; i<anzahl; i++) { Serial.print(", "); Serial.print(byte(sendBuffer1[i])); } 
              Serial.println(); 
                 
              if (debugRs485 && 0) {Serial.print("Send 06: ");                        // an Monitor
                                    Serial.println(sendBuffer1);
                                    for (int i=0; i<maxBuffer; i++) {
                                      Serial.print(highByte(unsigned(sendBuffer1[i])), HEX); Serial.print(lowByte(unsigned(sendBuffer1[i])), HEX); Serial.print(' ');
                                      // if (sendBuffer1[i] == 0) break;
                                    }
                                    Serial.println();
              }
            enableSend06 = false;
          
            for (int i=0;i<maxBuffer;i++) sendBuffer1[i] = 0x00;              // Puffer löschen
            
            Serial1.flush();                                                  // Waits for the transmission of outgoing serial data to complete
            //delayMicroseconds(10);
            digitalWrite(rd485send,LOW);                                      // max485 empfangen
           
            } // end send answer 06
          
           if (enableSend16) {
              digitalWrite(rd485send,HIGH);                                     // max485 senden
              anzahl         = 8;                                                        // von [0] bis 2.Byte CRC == Index letztes byte + 1
              sendBuffer1[0] = modAdr;                                                   // Geräteadresse
              sendBuffer1[1] = rcvBuffer1[1];                                            // Funktionscode
              sendBuffer1[2] = rcvBuffer1[2];                                            // Adresse des ersten Registers Hi Bytes
              sendBuffer1[3] = rcvBuffer1[3];                                            // Adresse des ersten Registers Lo Bytes
              sendBuffer1[4] = rcvBuffer1[4];                                            // Anzahl der aufgezeichneten Register Hi Bytes
              sendBuffer1[5] = rcvBuffer1[5];                                            // Anzahl der aufgezeichneten Register Lo Bytes
              sendBuffer1[6] = char((crc(&sendBuffer1[0],(anzahl-2))) & 0xff);           // Prüfsumme CRC
              sendBuffer1[7] = char(((crc(&sendBuffer1[0],(anzahl-2))) >> 8) & 0xff);    // Prüfsumme CRC
              Serial.print("     Send: ");
              for (int i=0; i<anzahl; i++) {
                 Serial1.write(sendBuffer1[i]);
                 hexByte(sendBuffer1[i]);
              }
              //Serial.println(); 
              //for (int i=0; i<anzahl; i++) { Serial.write(sendBuffer1[i]); } 
              Serial.print(",     ");// Serial.print("  CRC: "); Serial.print(crc(&sendBuffer1[0],(anzahl-2)),HEX);
              for (int i=0; i<anzahl; i++) { Serial.print(", "); Serial.print(byte(sendBuffer1[i])); } 
              Serial.println(); 
                 
              if (debugRs485 && 0) {Serial.print("Send 16: ");                        // an Monitor
                                    Serial.println(sendBuffer1);
                                    for (int i=0; i<maxBuffer; i++) {
                                      Serial.print(highByte(unsigned(sendBuffer1[i])), HEX); Serial.print(lowByte(unsigned(sendBuffer1[i])), HEX); Serial.print(' ');
                                      // if (sendBuffer1[i] == 0) break;
                                    }
                                    Serial.println();
              }
            enableSend16 = false;
          
            for (int i=0;i<maxBuffer;i++) sendBuffer1[i] = 0x00;              // Puffer löschen
            
            Serial1.flush();                                                  // Waits for the transmission of outgoing serial data to complete
            //delayMicroseconds(10);
            digitalWrite(rd485send,LOW);                                      // max485 empfangen
           
            } // end send answer 16
          
           
           if (debugCycle) {diffLoop=(millis()-milliAlt); Serial.print("Zykluszeit: "); Serial.print(diffLoop); Serial.println(" ms"); }
           milliAlt = millis(); 
           
           impulsSec    = false;
           impuls10Sec  = false;
           impulsMin    = false;
           impulsStunde = false;
           impulsTag    = false;
           impulsWoche  = false;
           rstrt        = false;
          
          }  // end loop
          

          und noch ein Stück vom Log IOBroker:

          modbus.0
          	2023-03-26 18:12:45.710	debug	[DevID_7/holdingRegs] Poll address 0 DONE
          modbus.0
          	2023-03-26 18:12:45.684	debug	[DevID_7/holdingRegs] Poll address 0 - 4 registers
          modbus.0
          	2023-03-26 18:12:45.682	debug	[DevID_7/inputRegs] Poll address 0 DONE
          modbus.0
          	2023-03-26 18:12:45.669	debug	[DevID_7/inputRegs] Poll address 0 - 4 registers
          modbus.0
          	2023-03-26 18:12:45.669	debug	[DevID_7] Poll start ---------------------
          modbus.0
          	2023-03-26 18:12:42.224	debug	[DevID_7/holdingRegs] Poll address 0 DONE
          modbus.0
          	2023-03-26 18:12:42.204	debug	[DevID_7/holdingRegs] Poll address 0 - 4 registers
          modbus.0
          	2023-03-26 18:12:42.202	debug	[DevID_7/inputRegs] Poll address 0 DONE
          modbus.0
          	2023-03-26 18:12:42.189	debug	[DevID_7/inputRegs] Poll address 0 - 4 registers
          modbus.0
          	2023-03-26 18:12:42.189	debug	[DevID_7] Poll start ---------------------
          modbus.0
          	2023-03-26 18:12:42.189	info	Connected to slave
          modbus.0
          	2023-03-26 18:12:42.180	debug	connect to serial /dev/ttyUSB2 with 115200
          modbus.0
          	2023-03-26 18:12:31.071	debug	Cleaning up request fifo.
          modbus.0
          	2023-03-26 18:12:31.071	debug	Clearing timeout of the current request.
          modbus.0
          	2023-03-26 18:12:31.068	info	Disconnected from slave
          modbus.0
          	2023-03-26 18:12:30.191	warn	Poll error count: 2 code: "App Timeout"
          modbus.0
          	2023-03-26 18:12:30.068	error	Cannot write single registers {"deviceId":7,"address":1,"buffer":{"type":"Buffer","data":[0,0]}}: {"err":"timeout","timeout":100}
          modbus.0
          	2023-03-26 18:12:30.068	error	Request timed out.
          modbus.0
          	2023-03-26 18:12:30.066	warn	Error: undefined
          modbus.0
          	2023-03-26 18:12:29.926	debug	[DevID_7/holdingRegs] Poll address 0 DONE
          modbus.0
          	2023-03-26 18:12:29.904	debug	[DevID_7/holdingRegs] Poll address 0 - 4 registers
          modbus.0
          	2023-03-26 18:12:29.903	debug	[DevID_7/inputRegs] Poll address 0 DONE
          modbus.0
          	2023-03-26 18:12:29.891	debug	[DevID_7/inputRegs] Poll address 0 - 4 registers
          modbus.0
          	2023-03-26 18:12:29.890	debug	[DevID_7] Poll start ---------------------
          modbus.0
          	2023-03-26 18:12:29.890	info	Connected to slave
          modbus.0
          	2023-03-26 18:12:29.885	debug	connect to serial /dev/ttyUSB2 with 115200
          modbus.0
          	2023-03-26 18:12:18.777	debug	Cleaning up request fifo.
          modbus.0
          	2023-03-26 18:12:18.776	debug	Clearing timeout of the current request.
          modbus.0
          	2023-03-26 18:12:18.773	info	Disconnected from slave
          modbus.0
          	2023-03-26 18:12:17.772	warn	Poll error count: 1 code: {"err":"timeout","timeout":100}
          modbus.0
          	2023-03-26 18:12:17.772	error	Request timed out.
          modbus.0
          	2023-03-26 18:12:17.771	warn	Error: undefined
          modbus.0
          	2023-03-26 18:12:17.670	debug	[DevID_7/holdingRegs] Poll address 0 - 4 registers
          modbus.0
          	2023-03-26 18:12:17.669	debug	[DevID_7/inputRegs] Poll address 0 DONE
          modbus.0
          	2023-03-26 18:12:17.657	debug	[DevID_7/inputRegs] Poll address 0 - 4 registers
          modbus.0
          	2023-03-26 18:12:17.657	debug	[DevID_7] Poll start ---------------------
          modbus.0
          	2023-03-26 18:12:14.213	debug	[DevID_7/holdingRegs] Poll address 0 DONE
          modbus.0
          	2023-03-26 18:12:14.189	debug	[DevID_7/holdingRegs] Poll address 0 - 4 registers
          modbus.0
          	2023-03-26 18:12:14.188	debug	[DevID_7/inputRegs] Poll address 0 DONE
          modbus.0
          	2023-03-26 18:12:14.175	debug	[DevID_7/inputRegs] Poll address 0 - 4 registers
          modbus.0
          	2023-03-26 18:12:14.175	debug	[DevID_7] Poll start ---------------------
          modbus.0
          	2023-03-26 18:12:10.726	debug	[DevID_7/holdingRegs] Poll address 0 DONE
          modbus.0
          	2023-03-26 18:12:10.712	debug	[DevID_7/holdingRegs] Poll address 0 - 4 registers
          modbus.0
          	2023-03-26 18:12:10.706	debug	[DevID_7/inputRegs] Poll address 0 DONE
          modbus.0
          	2023-03-26 18:12:10.693	debug	[DevID_7/inputRegs] Poll address 0 - 4 registers
          modbus.0
          	2023-03-26 18:12:10.693	debug	[DevID_7] Poll start ---------------------
          modbus.0
          	2023-03-26 18:12:07.249	debug	[DevID_7/holdingRegs] Poll address 0 DONE
          modbus.0
          	2023-03-26 18:12:07.231	debug	[DevID_7/holdingRegs] Poll address 0 - 4 registers
          modbus.0
          	2023-03-26 18:12:07.230	debug	[DevID_7/inputRegs] Poll address 0 DONE
          modbus.0
          	2023-03-26 18:12:07.217	debug	[DevID_7/inputRegs] Poll address 0 - 4 registers
          modbus.0
          	2023-03-26 18:12:07.217	debug	[DevID_7] Poll start ---------------------
          modbus.0
          	2023-03-26 18:12:03.774	debug	[DevID_7/holdingRegs] Poll address 0 DONE
          modbus.0
          	2023-03-26 18:12:03.759	debug	[DevID_7/holdingRegs] Poll address 0 - 4 registers
          modbus.0
          	2023-03-26 18:12:03.756	debug	[DevID_7/inputRegs] Poll address 0 DONE
          modbus.0
          	2023-03-26 18:12:03.742	debug	[DevID_7/inputRegs] Poll address 0 - 4 registers
          modbus.0
          	2023-03-26 18:12:03.742	debug	[DevID_7] Poll start ---------------------
          modbus.0
          	2023-03-26 18:12:03.741	info	Connected to slave
          modbus.0
          	2023-03-26 18:12:03.733	debug	connect to serial /dev/ttyUSB2 with 115200
          modbus.0
          	2023-03-26 18:11:52.625	debug	Cleaning up request fifo.
          modbus.0
          	2023-03-26 18:11:52.624	debug	Clearing timeout of the current request.
          modbus.0
          	2023-03-26 18:11:52.620	info	Disconnected from slave
          modbus.0
          	2023-03-26 18:11:51.619	warn	Poll error count: 1 code: {"err":"timeout","timeout":100}
          modbus.0
          	2023-03-26 18:11:51.619	error	Request timed out.
          modbus.0
          	2023-03-26 18:11:51.619	warn	Error: undefined
          modbus.0
          	2023-03-26 18:11:51.519	debug	[DevID_7/holdingRegs] Poll address 0 - 4 registers
          modbus.0
          	2023-03-26 18:11:51.518	debug	[DevID_7/inputRegs] Poll address 0 DONE
          modbus.0
          	2023-03-26 18:11:51.506	debug	[DevID_7/inputRegs] Poll address 0 - 4 registers
          modbus.0
          	2023-03-26 18:11:51.506	debug	[DevID_7] Poll start ---------------------
          modbus.0
          	2023-03-26 18:11:48.061	debug	[DevID_7/holdingRegs] Poll address 0 DONE
          modbus.0
          	2023-03-26 18:11:48.042	debug	[DevID_7/holdingRegs] Poll address 0 - 4 registers
          modbus.0
          	2023-03-26 18:11:48.042	debug	[DevID_7/inputRegs] Poll address 0 DONE
          modbus.0
          	2023-03-26 18:11:48.029	debug	[DevID_7/inputRegs] Poll address 0 - 4 registers
          modbus.0
          	2023-03-26 18:11:48.029	debug	[DevID_7] Poll start ---------------------
          modbus.0
          	2023-03-26 18:11:44.586	debug	[DevID_7/holdingRegs] Poll address 0 DONE
          modbus.0
          	2023-03-26 18:11:44.568	debug	[DevID_7/holdingRegs] Poll address 0 - 4 registers
          modbus.0
          	2023-03-26 18:11:44.566	debug	[DevID_7/inputRegs] Poll address 0 DONE
          modbus.0
          	2023-03-26 18:11:44.554	debug	[DevID_7/inputRegs] Poll address 0 - 4 registers
          modbus.0
          	2023-03-26 18:11:44.553	debug	[DevID_7] Poll start ---------------------
          modbus.0
          	2023-03-26 18:11:44.553	info	Connected to slave
          
          
          
          Homoran 1 Reply Last reply Reply Quote 0
          • Homoran
            Homoran Global Moderator Administrators @jg last edited by

            @jg sagte in Modbus RS485 Konfiguration:

            hier der komplette Arduino Code,

            ich kann kein Arduinisch!

            @jg sagte in Modbus RS485 Konfiguration:

            die Protokolle muß ja der IOB als Master initiieren

            Deswegen fragte ich nach den Registern!

            gibt es da offsets?

            1 Reply Last reply Reply Quote 0
            • J
              jg @Homoran last edited by

              @homoran
              Der Arduino hat in dem Sinne des Modbus keine Register. Ich möchte mir nur Integer Werte aus dem IOB zum weiterverarbeiten zum Arduino senden. diese sollte ich aus den Protokollen mit Funktion 6 aus den Bytes 3 und 4 (Adresse 0 .. 3) und den Bytes 5 und 6 (Dateninhalt) auslesen können.

              Homoran 1 Reply Last reply Reply Quote 0
              • Homoran
                Homoran Global Moderator Administrators @jg last edited by

                @jg sagte in Modbus RS485 Konfiguration:

                Der Arduino hat in dem Sinne des Modbus keine Register

                dann befürchte ich, dass der Modbus Adapter dann nicht der richtige ist.
                Wie gesagt

                @homoran sagte in Modbus RS485 Konfiguration:

                RS485 ist nicht Modbus!

                über RS485 können verschiedene Protokolle laufen.

                J 1 Reply Last reply Reply Quote 0
                • J
                  jg @Homoran last edited by

                  @homoran
                  gibt es denn andere RS485 Adapter für den IO-Broker?

                  Daten zum IOB senden geht ja einwandfrei mit dem Modbus Adapter, siehe die Antwort des Arduino auf die Anfrage des IOB, Protokolle 3 und 4.
                  Anfrage IOB: 007 003 000 000 000 004 0F1 0AF bedeutet 4 Eingangsregister ab Adresse 0 anfragen
                  Antwort MC: 001 003 008 000 07B ... bedeutet 8 Byte Werte als 4 Integerwerte zurück.

                  Deshalb war meine ursprüngliche Frage nach der Konfiguration des Modbus Adapters um die Protokolle 6 (bzw. 16) mit Dateninhalt aus dem IOB zu senden. Auswerten kann ich die dann im Arduino nach meinen Vorstellungen, aber der IOB muß die Daten erst mal senden.
                  Die Definition Funktionscode 6 ist:

                  BYTE  ANFRAGE                                 BYTE  ANTWORT
                  (Hex) Feldname                                (Hex) Feldname
                  11  Geräteadresse                             11    Geräteadresse
                  06  Funktionaler Code                         06    Funktionaler Code
                  00  Adresse des ersten Registers Hi Bytes     00    Adresse des ersten Registers Hi Bytes
                  01  Adresse des ersten Registers Lo Bytes     01    Adresse des ersten Registers Lo Bytes
                  00  Wert der Hi Bytes                         00    Wert der Hi Bytes
                  03  Wert der Lo Bytes                         03    Wert der Lo Bytes
                  9A  Prüfsumme CRC                             9A    Prüfsumme CRC
                  9B  Prüfsumme CRC                             9B    Prüfsumme CRC
                  

                  leider kommen keine Werte an, nur Nullen, obwohl in den Registern Werte im IOB vorhanden sind:

                  d0318944-0139-4e80-a9e4-a34f2e0e34c0-grafik.png

                  Homoran 1 Reply Last reply Reply Quote 0
                  • Homoran
                    Homoran Global Moderator Administrators @jg last edited by

                    @jg sagte in Modbus RS485 Konfiguration:

                    Deshalb war meine ursprüngliche Frage nach der Konfiguration des Modbus Adapters um die Protokolle 6 (bzw. 16) mit Dateninhalt aus dem IOB zu senden.

                    da kann ich dir nicht helfen.

                    J 1 Reply Last reply Reply Quote 0
                    • J
                      jg @Homoran last edited by

                      @homoran

                      Danke erst mal, evtl. meldet sich noch mal jemand, der Modbus seriell vielleicht schon in eigenen Projekten verwendet hat.

                      K 1 Reply Last reply Reply Quote 0
                      • K
                        klassisch Most Active @jg last edited by

                        @jg Ist das Arduino Programm von Dir erstellt? Kennst Du Dich damit aus? Dann würde es sich anbieten die Kommunikation mit dem ioBroker auf TCP (Ethernet) umzustellen.
                        Dazu gibt es den simpleApi Adapter

                        J 1 Reply Last reply Reply Quote 0
                        • J
                          jg @klassisch last edited by

                          @klassisch
                          mit dem Arduino kann ich umgehen, das Testprogramm für den Modbusadapter habe ich selbst geschrieben, außer die Prüfsummenberechnung.
                          Eine Kommunikation per Ethernet mit dem IOB habe ich laufen, diese ist aber recht instabil, daher möchte ich die Kommunikation zum IOB lieber seriell aufbauen. Über den Ethernetadapter mit W5500 habe ich gleichzeitig einen Webserver, NTP per UDP, Datenkommunikation mit einem anderen Arduino per UDP und MQTT zum IOB laufen. Leider hängt sich die MQTT Übertragung bei Zugriff auf den Webserver unregelmäßig auf, was sogar zum Absturz des IOB führt. Beide fangen sich zwar wieder per watchdog, aber so ist das ganze leider nicht brauchbar. Deshalb möchte ich eine serielle Verbindung zum IOB aufbauen, den 2. Arduino habe ich auch schon seriell angebunden und NTP könnte ich auch einsparen, wenn ich mir die NTP Zeit vom IOB seriell abholen könnte. Ebenfalls habe ich schon mit Wlan mit einem ESP32 und einem Raspberry Pico getestet. Das läuft leider noch instabiler als die Version mit dem Ethernet Chip W5500.
                          Daher wäre mein Ausweg aus dem Dilemma eine serielle Verbindung zum IOB in beide Richtungen. Möglich wären ja theoretisch bis reichlich 120 Integerwerte in einem Telegramm (Funktionscode 16). Kennst du dich mit der Konfiguration des Modbus Adapters aus?

                          K 1 Reply Last reply Reply Quote 0
                          • K
                            klassisch Most Active @jg last edited by

                            @jg Ich kann gerade mal Modbus Geräte mehr oder weniger per trial & Error in den Modbus Adapter einlesen. Ich mache das dann auch nicht über USB sondern über einen RS485 <->TCP Server.
                            Ich kann aber kein Modbus Protokoll aufbauen, wie es hier erforderlich wäre. Bzw. ich habe das noch nie gemacht und habe auch keine Notwendigkeit dazu.
                            Ich habe eine kleine Herde von ESP8266, die recht stabil über simpleApi oder MQTT Daten an den ioBroker liefern. Ist hat WLAN und beim Update der Fritte oder sonstigen Wifi Störungen macht das ein oder andere schlecht mit WLAN versorgte Teil mal einen Neustart. Aber ich hatte auch schon jahrelange update Zeiten, bis ein Bagger alles stromlos machte.
                            Wenn aber Deine ESP32 in Deiner Umgebung kein stabiles WLAN und Deine Arduinios kein stabile LAN aufbauen können, dann ist das auch nichts.
                            Was Du eventuell testen könntest:

                            • Anfrage, ob der simpleApi Adapter um eine serielle Schnittstelle erweiterbar wäre. Ich denke, die Realisierungsschancen sind eher gering, denn der Entwickler ist sehr beschäftigt und serielle Schnittstellen bei nodejs scheinen etwas aufwendiger zu sein.
                            • Testen, ob Du mit einem serial <-> TCP Konverter weiter kommst und so auf den simpleApi Adapter zugreifen kannst. Ich denke hierbei speziell an den USR-WIFI232-A2 (WLAN), da dieser laut Manual https://www.pusr.com/download/WIFI/USR-WIFI232-A2_User_Manual-V6.0.pdf über einen "transparent Mode" verfügt (Kap. 4.2.1, S.20). Damit könnte es nach meinem Verständnis möglich sein eine Art serial via TCP aufzubauen.
                              Entweder die serielle Verbindung zwischen dem Arduino und dem USRIOT direkt über "TTL"-Digitalleitungen schaffen oder eben über die kostengünstigen RS484 Konverter auf beiden Seiten.
                              Habe aber diesen transparenten Modus bei dem USRIOT nicht getetet. Ich verwende ihn im Modbus RTU mode, um einen modbusfähigen Stromzähler mithilfe des Modbus Adapters auszulesen.
                            J 1 Reply Last reply Reply Quote 0
                            • J
                              jg @klassisch last edited by

                              @klassisch
                              danke für deine Vorschläge, werde mich mal mit dem Thema simpleAPI befassen

                              K 1 Reply Last reply Reply Quote 0
                              • K
                                klassisch Most Active @jg last edited by

                                @jg https://github.com/ioBroker/ioBroker.simple-api
                                setbulk um mehrere Werte an ioBroker zu übertragen

                                Kannst Du vom Browser aus testen. SimpleApi Adapter installieren und vom Office PC Browser den Befehl abschießen.

                                1 Reply Last reply Reply Quote 0
                                • First post
                                  Last post

                                Support us

                                ioBroker
                                Community Adapters
                                Donate
                                FAQ Cloud / IOT
                                HowTo: Node.js-Update
                                HowTo: Backup/Restore
                                Downloads
                                BLOG

                                831
                                Online

                                31.7k
                                Users

                                79.8k
                                Topics

                                1.3m
                                Posts

                                3
                                14
                                677
                                Loading More Posts
                                • Oldest to Newest
                                • Newest to Oldest
                                • Most Votes
                                Reply
                                • Reply as topic
                                Log in to reply
                                Community
                                Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                                The ioBroker Community 2014-2023
                                logo