ArduinoModbusSlave bitte um Erklärung

Es geht um diese Library: GitHub - yaacov/ArduinoModbusSlave: Modbus slave library for Arduino
Habe die Beispiele angeschaut, verstehe aber nicht was da passiert.

slave.writeCoilToBuffer(i, digitalRead(address + i));
Was für adress und welches i ?

for (int i = 0; i < length; i++)
Wo kommt das length her und was macht das hier?

readDigitalIn(uint8_t fc, uint16_t address, uint16_t length)
Muss ich hier die parameter übergeben um ein pin auszulesen?
Also so: readDigitalIn(1, 0, 1) // Function Coil, register 0, bit 0

Mit dieser Library habe ich folgenden Code testen können, funktioniert und ich verstehe so halbwegs was warum und wohin gehört, bis auf eine Sache:
uint16_t au16data[4]; // Alle register?
slave.poll( au16data, 4 ); // Alle register?
Diese 4, die muss immer bei beiden gleich sein? Wo kommt die her? Wovon hängt es ab was da reingehört?

bitWrite( au16data[0], 0, ledState); // Register 0 bit 0? //coil
bitWrite( au16data[0], 1, digitalRead( ledPin )); // Register 0 bit 1? //coil
bitWrite( au16data[0], 2, digitalRead( buttonPin1 )); // Register 0 bit 2? //coil
au16data[1] = LEDfunction; // Register 1 //holding
Ich denke mir mal das hat damit zu tun. Die Frage ist jetzt nur, zähl ich die 4 Zeilen zusammen ( au16data[0], 0 + au16data[0], 1 + au16data[0], 2 + au16data[1] ) oder ist es die letzte Ziffer von au16data[1] = LEDfunction; die bei uint16_t au16data[4]; und slave.poll( au16data, 4 ); reinkommt?

#include <ModbusRtu.h>
#include "ClickButton.h"
uint16_t au16data[4];
Modbus slave(1,0,23);
// the LED
const int ledPin = 19;
const int ledPin5 = 5;
const int ledPin6 = 6;
int8_t state = 0;
unsigned long tempus;

 int ledState = 0;

// the Button
const int buttonPin1 = 2;
ClickButton button1(buttonPin1, HIGH);

// Arbitrary LED function 
 int LEDfunction = 0;


void setup()
{
  pinMode(ledPin,OUTPUT);  
  pinMode(ledPin5,OUTPUT);  
  pinMode(ledPin6,OUTPUT); 
  //tempus = millis() + 100;
  //digitalWrite(ledPin6, HIGH );
  slave.begin( 19200 ); // baud-rate at 19200
  // Setup button timers (all in milliseconds / ms)
  // (These are default if not set, but changeable for convenience)
  button1.debounceTime   = 20;   // Debounce timer in ms
  button1.multiclickTime = 250;  // Time limit for multi clicks
  button1.longClickTime  = 1000; // time until "held-down clicks" register


}


void loop()
{

  // Update button state
  button1.Update();

  // Save click codes in LEDfunction, as click codes are reset at next Update()
  if (button1.clicks != 0) LEDfunction = button1.clicks;
  

  // Simply toggle LED on single clicks
  // (Cant use LEDfunction like the others here,
  //  as it would toggle on and off all the time)
  if(button1.clicks == 1) ledState = !ledState;

  // blink faster if double clicked
  if(LEDfunction == 2) ledState = (millis()/500)%2;

  // blink even faster if triple clicked
  if(LEDfunction == 3) ledState = (millis()/200)%2;

  // slow blink (must hold down button. 1 second long blinks)
  if(LEDfunction == -1) ledState = (millis()/1000)%2;

  // slower blink (must hold down button. 2 second loong blinks)
  if(LEDfunction == -2) ledState = (millis()/2000)%2;

  // even slower blink (must hold down button. 3 second looong blinks)
  if(LEDfunction == -3) ledState = (millis()/3000)%2;

  slave.poll( au16data, 4 );
  
   bitWrite( au16data[0], 0, ledState);
   bitWrite( au16data[0], 1, digitalRead( ledPin ));
   bitWrite( au16data[0], 2, digitalRead( buttonPin1 ));
   au16data[1] = LEDfunction;
  
  // update the LED
  digitalWrite(ledPin,ledState);
  digitalWrite(ledPin5, bitRead( au16data[0], 0 ));
}

Ich habe jetzt mal nur kurz über die Lib geguckt.
Aber ich denke das Length kommt vom Master dem ja gesagt wurde das diese COIL x-Byte groß ist.
So viele Bytes holt sich das Beispiel dann von den Analogen Eingängen address + i.

Der Callback kannst du ja schreiben wie du komisch bist. Der Wert kann natürlich auch irgendwo anders
als von aufeinander folgenden analogen Ports kommen. Du musst halt wissen was der Master will und
wo du es her nimmst.

Ulli

Wenn jemand das Beispiel anders schreiben könnte, so dass ich es versteh, wärs schon top :slight_smile:
Wie aus ModbusRtu ist für mich schon verständlich.

Das mit den Registern ( uint16_t au16data[4]; slave.poll( au16data, 4 ); ) ist mir jetzt klar.
Ich hatte Errors angezeigt bekommen weil ich die diagnose Register auf 50 gesetzt hab, von 2 bis 49 war dann sonst nix.
Es müssen also alle Register da eingetragen werden und es darf keine "Lücke" zwischen den Registern sein, also muss fortlaufend sein.