OneButton Library mit Schleife vereinfachen

Hi Leute,

ich möchte mehrere Schalter über die OneButton Library erzeugen die dann bestimmte Gruppen von LEDs schalten. Ich bin programmiertechnisch aber anscheinend zu blöd um das in einer Schleife zu machen (und ich kann es auch wirklich nicht richtig). Mein Code braucht jetzt schon knapp 50% vom Ram meines MEGA und dabei hab ich gerade erst angefangen zu schreiben.

Hier der Teil von meinem Code der die Buttons erzeugt:

OneButton btn0(btnId[0],false,false);
OneButton btn1(btnId[1],false,false);
OneButton btn2(btnId[2],false,false);
OneButton ...

void sc0() {SingleClick (0);}
void sc1() {SingleClick (1);}
void sc2() {SingleClick (2);}
void sc3() ...

void dc0() {DoubleClick (0);}
void dc1() {DoubleClick (1);}
void dc2() ...

void lpStart0() {LongPressStart (0);}
void lpStart2() {LongPressStart (2);}
void lpStart9() ...

void lpStop0() {LongPressStop (0);}
void lpStop2() {LongPressStop (2);}
void lpStop9() {LongPressStop (9);}
void lpStop15() ...

void dlp0() {DuringLongPress (0);}
void dlp2() {DuringLongPress (2);}
void dlp9() {DuringLongPress (9);}
void dlp15() ...

void SetupButtons() {
  btn0.attachClick(sc0);
  btn1.attachClick(sc1);
  btn2.attachClick(sc2);
  btn3...

  btn0.attachDoubleClick(dc0);
  btn1.attachDoubleClick(dc1);
  btn2.attachDoubleClick(dc2);
  btn3...

  btn0.attachLongPressStart(lpStart0);
  btn2.attachLongPressStart(lpStart2);
  btn9.attachLongPressStart(lpStart9);
  btn15...

  btn0.attachLongPressStop(lpStop0);
  btn2.attachLongPressStop(lpStop2);
  btn9.attachLongPressStop(lpStop9);
  btn15...

  btn0.attachDuringLongPress(dlp0);
  btn2.attachDuringLongPress(dlp2);
  btn9.attachDuringLongPress(dlp9);
  btn15...
}

void ButtonTicks() {
  btn0.tick();
  btn1.tick();
  btn2.tick();
  btn3...
}

Ich möchte mit jeder Klickvariante (Singleclick, Doubleklick,...) eigentlich immer gleiche Funktion aufrufen, jedoch soll die jeweilige ID vom Button mitgegeben werden damit ich weiß zu welcher Gruppe er gehört. Irgendwie schaffe ich das nicht. Deshalb habe ich für jeden Variante und für jeden Button eine eigene Funktion erstellt die immer die selbe Funktion aufruft und die ID mitgibt.

Leider kann ich nicht den ganzen Code posten weil nur der Onebutton Teil schon über 9000 Zeichen hat und nicht mehr im Forum erlaubt sind.

Geht das nicht irgendwie einfacher? Es muss auch nicht unbedingt die OneButton Library sein, aber ich müsste halt die selben Aktionen raus bekommen. Um das selbst zu programmieren bin ich leider nicht gut genug :'(

Danke schonmal!

lg Martin

Die OneButton ist schon recht ressourcenfressend. Bei einem Taster macht sich das nicht so bemerkbar, aber wenn es viele werden.... Vielleicht sind die MobaTols da was für dich. Die Klasse MoToButtons ist darauf ausgerichtet, viele Taster ( bis zu 32 in einer Instanz ) möglichst ressourcenschonend zu verwalten. Die Arbeitsweise ist aber anders. Es wird nicht mit Callback Funktionen gearbeitet ( ein Grund für den Ressourcenbedarf der OneButton), sondern mit direkten Abfragen der Tasterstatus. Es sind auch Beispiele dabei z.B. dieses.

EDIT: Um wieviel Taster/Schalter geht es eigentlich?

9000 Zeichen

dann behaupte ich, dass in den 9000 Zeichen vieles drinnen ist, das RAM verschwendet.

häng dein INO als Attachement an das Post, dann schauen wir uns das mal an.

Oder bevor WIR uns das ansehen - kennst du schon das F-Makro?

https://www.arduino.cc/reference/de/language/variables/utilities/progmem/

Danke für die schnelle Antwort. Ich schau mir die beiden Sachen mal an und melde mich dann. Und ja, in den weit über 9000 Zeichen ist sicher viel Schrott drin :D

Hi Zusammen,
hab jetzt versucht mich ein bisschen einzulesen.

MicroBahner:
EDIT: Um wieviel Taster/Schalter geht es eigentlich?

Ja… Hab ich vergessen mit zu schreiben. Sorry! ::slight_smile: Es geht um 40+ Schalter mit 20+ LED’s in 25+ Gruppen. Da fallen die MobaTools wohl raus, da ich nichts gefunden habe 2 Instanzen mit einem Mega gleichzeitig laufen zu lassen…

noiasca:

Oder bevor WIR uns das ansehen - kennst du schon das F-Makro?

Habe ich nicht gekannt. Schaut interessant, aber auch recht komplex aus. Vielleicht gibt es doch noch eine Variante in den den Code abzuspecken ohne ihn in den Flash schreiben zu müssen. Eigentlich muss das Teil ja nicht wirklich viel können.
Ich brauche:

  • debounce für die 40+ Schalter (active HIGH, Resistoren sind schon verbaut)
  • Press
  • LongPressStart
  • LongPressRelease
  • DuringLongPress
  • Double-/MultiPress

noiasca:

häng dein INO als Attachement an das Post, dann schauen wir uns das mal an.

Hab ich angehängt.
Würgt mich aber bitte nicht wegen dem Code ;D Ich programmiere nur als Hobby und bin eigentlich noch blutiger Anfänger…

Vielleicht fällt euch noch was ein? :slight_smile:
LG
Martin

OBLed.ino (14.2 KB)

matspa: Da fallen die MobaTools wohl raus, da ich nichts gefunden habe 2 Instanzen mit einem Mega gleichzeitig laufen zu lassen...

Wo ist das Problem 2 ( oder meinetwegen auch mehr ) Instanzen einzurichten?

matspa: (active HIGH, Resistoren sind schon verbaut)

Ganz schlecht, sowas macht man nicht - erst recht nicht bei so vielen Tastern. Aber egal, wenn Du die MoToButtons mit einer Callback-Funktion für das Tasterlesen betreibst, könntest Du die Taster beliebig anschließen - auch über Portexpander. Hast Du auch schonmal daran gedacht, die Taster als Matrix aufzubauen? Würde sich bei der Anzahl ja anbieten.

matspa: - LongPressStart

Wie bitte soll das funktionieren? Woher soll die Software bei Drücken eines Tasters erahnen, wann Du ihn loslassen willst?

ich glaube du kannst Speicher sparen wenn du mal genau überprüfst,ob deine Werte jemals mehr als ein byte benötigen:

int btnId[] = {A8,A9,A10,A11,A12,A13,A14,A15,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53};
int btnToGroupSinglePress[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,5,6,7,8,9,10,11,12,13,14,15};
int btnToGroupDoublePress[] = {0,1,2,3,4,-1,-1,-1,-1,0,1,2,3,4,-1,-1,-1,12,13,14,15,16,-1,-1,-1,-1,-1,12,13,14,15,16,-1,12,13,14,15,16,-1,-1};
int btnToGroupLongPressStart[] = {-1,-1,-1,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,20,21,22,23,24,25,-1};
int btnToGroupDuringLongPress[] = {-1,-1,21,22,23,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,21,22,23,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,21,22,23,-1,-1,-1,-1,-1,-1,-1,-1};

int lightGroups[29][21] = {

da kannst vermutlich vieles auf int8_t umstellen wenn dir -128...127 reicht.

oder uint8_t wenn du keine negativen Werte benötigst aber von 0..255 gehen willst. Wenn sich die Werte nie ändern, definiere sie const!(!!!)

Hi und nochmal danke für die Antworten!

MicroBahner: Wo ist das Problem 2 ( oder meinetwegen auch mehr ) Instanzen einzurichten?

Hauptsächlich liegt das Problem darin, dass ich nicht weiß wie das geht. Wenn du aber sagst, dass es funktioniert werde ich mir die MobaTools doch nochmal genau anschauen.

MicroBahner: Ganz schlecht, sowas macht man nicht - erst recht nicht bei so vielen Tastern.

Mein Problem ist, dass die Kabel zu den Schaltern teilweise ziemlich lang sind (bis zu 15 Metern). Deshalb wollte ich von meinem MW Netzteil mit dem ich auch den Arduino betreibe die 5V direkt an den Schaltern anliegen lassen. Damit hab ich dann nicht das Probleme als wenn ich den Strom vom Pin an den Schaltern anliegen lasse. Die Schalter werden immer nur kurz betätigt. So hab ich zumindest im Internet heraus gelesen. Liege ich damit falsch?

MicroBahner: Hast Du auch schonmal daran gedacht, die Taster als Matrix aufzubauen?

Nein, aber das klingt gut. Werde ich mir anschauen.

MicroBahner: Wie bitte soll das funktionieren?

Die Bezeichnung kommt aus der OneButton Lib. LongPressBeginn startet nach einer bestimmten Zeit (z.B.: 600ms). Davor wird ein release als Singlepress gewertet. Ein zweimaliges drücken innerhalb von diesem Zeitraum als Double/Multipress.

noiasca: da kannst vermutlich vieles auf int8_t umstellen wenn dir -128...127 reicht.

oder uint8_t wenn du keine negativen Werte benötigst aber von 0..255 gehen willst. Wenn sich die Werte nie ändern, definiere sie const!(!!!)

Da gibt es sicher viele Bereiche in denen ich das umsetzen kann. Ich wusste nicht, dass das Auswirkungen hat. Danke! Letztendlich bedeutet es aber, dass die OneButton eben wirklich nur für EINEN Button gut ist und ich mich nach was besserem umsehe :)

Danke nochmal lg Martin

Letztendlich bedeutet es aber, dass die OneButton eben wirklich nur für EINEN Button gut ist und ich mich nach was besserem umsehe

nö das bedeutet es gar nicht. Dein Sketch ist das Problem, nicht die Library!

Klar kann man sich einen Button Klasse genau für seine Zwecke anpassen, aber da würde ich zunächst den restlichen Sketch aufräumen.

Original
Der Sketch verwendet 8852 Bytes (3%) des Programmspeicherplatzes. Das Maximum sind 253952 Bytes.
Globale Variablen verwenden 3884 Bytes (47%) des dynamischen Speichers, 4308 Bytes für lokale Variablen verbleiben. Das Maximum sind 8192 Bytes.

nach Umbau auf 1 Byte Variablen
Der Sketch verwendet 8064 Bytes (3%) des Programmspeicherplatzes. Das Maximum sind 253952 Bytes.
Globale Variablen verwenden 3134 Bytes (38%) des dynamischen Speichers, 5058 Bytes für lokale Variablen verbleiben. Das Maximum sind 8192 Bytes.

wenn du mit 7 Änderungen 700 Byte freischaufeln kannst dann mach das!

ob es die ganzen Code-Duplikate braucht müsste man sich auch noch ansehen.