Raffstore + dimmbare LEDs - Steuerung Multimaster I2C

Haben unseren Wintergarten umgebaut - und 8 Raffsores eingebaut.
Die sollen alle einzeln - bzw. in Gruppenschaltungen fahren können.
Weiters soll eine Lichtsteuerung mit 5 Zonen - 3 davon dimmbar realisiert werden.

Als Taster habe ich mir bereits einen Jung LS2248 gekauft. 3 weitere solche Taster sollten folgen.
Jeder LS2248 hat 8 einzelne Taster + 8 LEDs - die extra ansteuerbar sind.
Für die Taster brauche ich also 24 digitale Eingänge - wo jeder eine andere Funktion haben sollte.
Dann noch einen Windsensor.
Für die Raffstores habe ich eine 16-Kanal Relaiskarte.
Für die Lichtsteuerung habe ich auf den IRFZ34 gedacht - geht wunderbar ... hänge ich auf PWM - und schon geht das dimmen wunderbar!
Ev. werde ich noch eine weitere Relaiskarte verbauen - für die Lichtsteuerung...
... habe also um die 40 I/O ... wenn ich die LEDs der Taster noch weglasse ... sonst um die 65 I/O
Die würde ich aber sicher mit I2C-Port-Expander machen...

Meine Idee wäre: Eine I2C Multimaster Lösung.
Für jeden Taster einen eingenen Arduino Pro Mini - 5V ---> alle als MASTER
Für die Raffstore-Relaiskarte und für das Licht (ev. auch Windsensor) - je einen weiteren Pro Mini --> als SLAVE

Auch sollte jeder Taster, bzw. jede Taste eine Doppel- und Dreifachbelegung haben.
Also einfacher Klich, Doppelklick, Trippleklick, und on Hold ... draufbleiben.

Hab mir gedacht das ich einfach beim:
Singleklick - Licht ein / aus
Doppelklick - Licht auf halbe Leistung dimmen
Tripple - keine Ahnung
onHold - auf und ab dimmen

Auch bei den Raffstores.
Wenn ich drauf bleibe sollten die Dinger nur mehr ganz kleine Schritte auf bzw. ab fahren.
Wegen Lichteinfall, Sichtschutz etc.

Derzeitiger Aufbau funktioniert perfekt.
Der (derzeit einzige) MASTER prüft die Taster ... auch Doppelklick und so.
Und übergibt einen Code an den SLAVE - und der macht auch was er soll.
Als PWM nehme ich derzeit auch den Master - da ich noch Pins frei habe...
Funktioniert auch sehr gut. Klick ich 1x Licht an/aus ... Doppelt 50% ... Tripple 100% Power.

Kann mir jemand sagen ob die Multimasterlösung überhaupt funktioniert?
Oder andere Lösungsvorschläge? Port-Expander?
Aber funktioniert dann auch der Doppelklick etc...???
Oder läuft der Bus dann auch hochtouren? Ist das egal? Oder eher nicht so?

Der Code des MASTERS: -- mal mit 4 Tastern:

#include <ClickButton.h>
#include <Wire.h>


const int Wert[]={0,1,2,3,4,5,6,7,8,9,10,15,20,25,30,35,45,55,65,75,90,255}; // 22 Werte
const int PWMpin=10;   //  ***************
const int swPin1=5;
const int swPin2=6;
const int swPin3=7;
const int swPin4=8;
ClickButton sw1(swPin1,HIGH); // Taster1 = Raffstor 1
ClickButton sw2(swPin2,HIGH); // Taster2 = Raffstor 2
ClickButton sw3(swPin3,HIGH); // Taster3 = Raffstor 3
ClickButton sw4(swPin4,HIGH); // Taster4 = Raffstor 4

const int TILTtime=40;  // 100=1 Sekunde


int Pos=0;
long time0=0,time1=0;

void setup() {
  Wire.begin(); // join i2c bus (address optional for master)
  pinMode(swPin1,INPUT);
  pinMode(swPin2,INPUT);
  pinMode(swPin3,INPUT);
  pinMode(swPin4,INPUT);
  pinMode(PWMpin,OUTPUT);  // ---------
  
  sw1.maxPresses     = 3;    // max button multiclick count
  sw1.debounceTime   = 15;   // Debounce timer in ms
  sw1.multiclickTime = 250;  // Time limit for multi clicks
  sw1.heldDownTime   = 1000; // time until "held-down clicks" register
  sw2.maxPresses     = 3;    // max button multiclick count
  sw2.debounceTime   = 15;   // Debounce timer in ms
  sw2.multiclickTime = 250;  // Time limit for multi clicks
  sw2.heldDownTime   = 1000; // time until "held-down clicks" register
  sw3.debounceTime   = 15;   // Debounce timer in ms
  sw3.multiclickTime = 250;  // Time limit for multi clicks
  sw3.heldDownTime   = 1000; // time until "held-down clicks" register
  sw4.debounceTime   = 15;   // Debounce timer in ms
  sw4.multiclickTime = 250;  // Time limit for multi clicks
  sw4.heldDownTime   = 1000; // time until "held-down clicks" register
  
  Serial.begin(9600);
  Serial.println("Programm gestartet:");
  time0=millis()/100;time1=millis()/100;
  
}

void loop() {
  
  analogWrite(PWMpin,Wert[Pos]);
  

  time0=millis()/10;
  
  sw1.Update(); //Taster 1 lesen
  sw2.Update(); //Taster 2 lesen
  sw3.Update(); //Taster 3 lesen
  sw4.Update(); //Taster 4 lesen
  
  if(sw1.click==1) {Serial.println("A - Klick 1!"); // Taster 1 - Single Klick
                      Wire.beginTransmission(4); Wire.write("A"); Wire.write(sw1.click);Wire.endTransmission(); }
  if(sw1.click==2) {Serial.println("A - Klick 2!"); // Taster 1 - Doppel Klick
                      Wire.beginTransmission(4); Wire.write("A"); Wire.write(sw1.click);Wire.endTransmission(); 
                      Pos=1;}  // Dimmer Wert einstellen
  if(sw1.click==3) {Serial.println("A - Klick 3!"); // Taster 1 - Tripple Klick
                      Wire.beginTransmission(4); Wire.write("A"); Wire.write(sw1.click);Wire.endTransmission(); 
                      Pos=15;} // Dimmer Wert einstellen
  if(sw1.click<0) // Taster 1 - On Hold
   { time1=time0;
     Serial.print("Klick time: "); Serial.println(sw1.click); delay(100);
     while(sw1.depressed==true)
     { time0=millis()/10;
       if((time0-time1)>TILTtime) { Serial.print("PRESSES 100..."); time1=time0; Wire.beginTransmission(4); Wire.write("A"); Wire.write(5);Wire.endTransmission(); }
       Serial.print("Time: "); Serial.println(time0-time1); 
       sw1.Update(); delay(10);
     }
   }
  if(sw2.click==1) {Serial.println("B - Klick 1!"); // delay(100);
                      Wire.beginTransmission(4); Wire.write("B"); Wire.write(sw2.click);Wire.endTransmission(); }
  if(sw2.click==2) {Serial.println("B - Klick 2!"); // delay(100);
                      Wire.beginTransmission(4); Wire.write("B"); Wire.write(sw2.click);Wire.endTransmission(); }  
  if(sw2.click==3) {Serial.println("B - Klick 3!"); // delay(100);
                      Wire.beginTransmission(4); Wire.write("B"); Wire.write(sw2.click);Wire.endTransmission(); } 
  if(sw2.click<0)
   { time1=time0;
     Serial.print("Klick time: "); Serial.println(sw2.click); delay(100);
     while(sw2.depressed==true)
     { time0=millis()/10;
       if((time0-time1)>TILTtime) { Serial.print("PRESSES 100..."); time1=time0; Wire.beginTransmission(4); Wire.write("B"); Wire.write(5);Wire.endTransmission(); }
       Serial.print("Time: "); Serial.println(time0-time1); 
       sw2.Update(); delay(10);
     }
   }
  if(sw3.click==1) {Serial.println("C - Klick 1!"); // delay(100);
                      Wire.beginTransmission(4); Wire.write("C"); Wire.write(sw3.click);Wire.endTransmission(); }
  if(sw3.click==2) {Serial.println("C - Klick 2!"); // delay(100);
                      Wire.beginTransmission(4); Wire.write("C"); Wire.write(sw3.click);Wire.endTransmission(); }  
  if(sw3.click==3) {Serial.println("C - Klick 3!"); // delay(100);
                      Wire.beginTransmission(4); Wire.write("C"); Wire.write(sw3.click);Wire.endTransmission(); } 
  if(sw3.click<0)
   { time1=time0;
     Serial.print("Klick time: "); Serial.println(sw3.click); delay(100);
     while(sw3.depressed==true)
     { time0=millis()/10;
       if((time0-time1)>TILTtime) { Serial.print("PRESSES 100..."); time1=time0; Wire.beginTransmission(4); Wire.write("C"); Wire.write(5);Wire.endTransmission(); }
       Serial.print("Time: "); Serial.println(time0-time1); 
       sw3.Update(); delay(10);
     }
   }
  if(sw4.click==1) {Serial.println("D - Klick 1!"); // delay(100);
                      Wire.beginTransmission(4); Wire.write("D"); Wire.write(sw4.click);Wire.endTransmission(); }
  if(sw4.click==2) {Serial.println("D - Klick 2!"); // delay(100);
                      Wire.beginTransmission(4); Wire.write("D"); Wire.write(sw4.click);Wire.endTransmission(); }  
  if(sw4.click==3) {Serial.println("D - Klick 3!"); // delay(100);
                      Wire.beginTransmission(4); Wire.write("D"); Wire.write(sw4.click);Wire.endTransmission(); } 
  if(sw4.click<0)
   { time1=time0;
     Serial.print("Klick time: "); Serial.println(sw4.click); delay(100);
     while(sw4.depressed==true)
     { time0=millis()/10;
       if((time0-time1)>TILTtime) { Serial.print("PRESSES 100..."); time1=time0; Wire.beginTransmission(4); Wire.write("D"); Wire.write(5);Wire.endTransmission(); }
       Serial.print("Time: "); Serial.println(time0-time1); 
       sw4.Update(); delay(10);
     }
   }

  if(digitalRead(swPin1)==HIGH) {Serial.println("Schalter 1 aktiv!");} // delay(100);}
  if(digitalRead(swPin2)==HIGH) {Serial.println("Schalter 2 aktiv!");} // delay(100);}
  if(digitalRead(swPin3)==HIGH) {Serial.println("Schalter 3 aktiv!");} // delay(100);}
  if(digitalRead(swPin4)==HIGH) {Serial.println("Schalter 4 aktiv!");} // delay(100);}
}

Ohne den Code durchgesehen zu haben. Multimaster? Du meinst mehrere Master an einem I2C Bus? Nein, das funktioniert so nicht. Mache deine Pro Minis an den Tastern zu Slaves. Der Master fragt dann alle Taster ab.

Die interne Logik würde ich komplett über den Master laufen lassen. An sich würde auch ein I2C Expander gehen. Die frage ist aber, wo schließt du diese an. Wenn alles Zentral ist, entsteht ein recht dicker Kabelbaum. Mehrere Expander zu nutzen wird kritisch mit der Leitungslänge.

Einfache Darstellung:

SchalterPanel mit Pro Mini.

Taster 1- 8.

Master fragt Taster ab. Slave (ProMini) liefer einen Wert, zB. 10010001
Das könnte bedeuten das Taster 1, 4 und 8 gedrück sind. Nun kommt der Master ins Spiel und überprüft die Logik, wenn er zB. innerhalb von einer kurzen Zeit an Taster 1 ein 1 0 1 0 empfangen hat. Taster wurde 2 mal kurz gedrückt.

Die gesamte Steuerung wird zentral werden.
Mein Plan wäre alle auf eine Platine zu packen... oder zwei...

Werde das Ganze aber nochmal überdenken.
Portexpander für die Taster sollte auch gehen, probier ich mal.