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.
    • 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

                              812
                              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