Die OneButton library und Mux

Hallo liebe Community,

meine Button reagieren nicht richtig ich mache da etwas falsch und ich habe keine Ahnung was?

Wenn ich den Code für einen Button ohne MUX teste geht alles so wie es soll:

#include "OneButton.h"

int dataPin_2 = 2;

OneButton button(dataPin_2, true);

void setup(){
  Serial.begin(9600);
  button.attachClick(singleClick);
  button.attachDoubleClick(doubleClick);
}

void loop(){
  button.tick();
}

void singleClick(){
  Serial.println("singleClick() detected.");
}

void doubleClick(){
  Serial.println("doubleClick() detected.");
}

Wenn ich 8 Buttons an eine 4051 MUX ohne die OneButton lib. nutze ist auch alles TOP!!!:

int multiBut_sA = 5;
int multiBut_sB = 6;
int multiBut_sC = 7;
int dataPin_2 = 10;
int butWert[8] = {0};
int butWertAlt[8] = {0};
int butNummer[] = {20,21,22,23,24,25,26,27};

void setup() {
  pinMode(multiBut_sA, OUTPUT);
  pinMode(multiBut_sB, OUTPUT);
  pinMode(multiBut_sC, OUTPUT);
  pinMode(dataPin_2, INPUT_PULLUP);
  Serial.begin(9600);
}

void loop() {
  butTest();
}

void butTest () {
  for (int i = 0; i < 8; i++){
    digitalWrite(multiBut_sA, HIGH && (i & B00000001));
    digitalWrite(multiBut_sB, HIGH && (i & B00000010));
    digitalWrite(multiBut_sC, HIGH && (i & B00000100));
    butWert[i] = digitalRead(dataPin_2);
    
    if (butWert[i] != butWertAlt[i]) {
      Serial.print("But  ");
      Serial.print(butNummer[i]);
      Serial.print("  ");
      Serial.println(butWert[i]);
  }
     butWertAlt[i] = butWert[i];
  }
  }

Wenn ich hier jedoch versuche die Lib. einzubinden gehen mir clicks verloren!
Die Ausgabe ist korrekt wenn sie kommt.

#include "OneButton.h"

int multiBut_sA = 5;  // select A
int multiBut_sB = 6;  // select B
int multiBut_sC = 7;  // select C
int dataPin_2 = 10;   // Daten
int butWert[8] = {0};
int butWertAlt[8] = {0};
int butNummer[] = {20,21,22,23,24,25,26,27};
int Wert = {0};
int but = {0};

OneButton button(dataPin_2, true);

void setup() {
  pinMode(multiBut_sA, OUTPUT);
  pinMode(multiBut_sB, OUTPUT);
  pinMode(multiBut_sC, OUTPUT);
  pinMode(dataPin_2, INPUT_PULLUP);
  Serial.begin(9600);

  button.attachClick(singleClick);
  button.attachDoubleClick(doubleClick);
}

void loop() {
  butTest();
}

void butTest () {
  for (int i = 0; i < 8; i++){
    digitalWrite(multiBut_sA, HIGH && (i & B00000001));
    digitalWrite(multiBut_sB, HIGH && (i & B00000010));
    digitalWrite(multiBut_sC, HIGH && (i & B00000100));
    butWert[i] = digitalRead(dataPin_2);
    
    if (butWert[i] != butWertAlt[i]) {
        but = butNummer[i];
        Wert = butWert[i];
        button.tick();      
        }
    butWertAlt[i] = butWert[i];
    }
  }
  
void singleClick(){
  Serial.print("Button");
  Serial.print("  ");
  Serial.println(but);
  Serial.println("singleClick() detected.");
  Serial.print("Status");
  Serial.print("  ");
  Serial.println(Wert);
  Serial.println("");
}

void doubleClick(){
  Serial.print("Button");
  Serial.print("  ");
  Serial.println(but);
  Serial.println("doubleClick() detected.");
  Serial.print("Status");
  Serial.print("  ");
  Serial.println(Wert);
  Serial.println("");
}

Was mache ich falsch?

m8trix:
Was mache ich falsch?

Ich hab wirklich keine Ahnung, da ich die lib nicht benutze und auch sonst nicht brauche.
Damit ist dann der andere Thread erledigt.

Vielleicht ist es die Zuordnung wert/wertalt und der tick.

Alt:

void butTest () {
  for (int i = 0; i < 8; i++) {
    digitalWrite(multiBut_sA, HIGH && (i & B00000001));
    digitalWrite(multiBut_sB, HIGH && (i & B00000010));
    digitalWrite(multiBut_sC, HIGH && (i & B00000100));
    butWert[i] = digitalRead(dataPin_2);

    if (butWert[i] != butWertAlt[i]) {
      but = butNummer[i];
      Wert = butWert[i];
      button.tick();
    }
    butWertAlt[i] = butWert[i];
  }
}

neu:

void butTest () {
  for (int i = 0; i < 8; i++) {
    digitalWrite(multiBut_sA, HIGH && (i & B00000001));
    digitalWrite(multiBut_sB, HIGH && (i & B00000010));
    digitalWrite(multiBut_sC, HIGH && (i & B00000100));
    butWert[i] = digitalRead(dataPin_2);

    if (butWert[i] != butWertAlt[i]) {
      but = butNummer[i];
      Wert = butWert[i];
      butWertAlt[i] = butWert[i];
    }
    button.tick();
  }
}

Aber dann bin ich aus der Nummer auch raus.

Ich habe deine Code Änderung mal getestet leider kommt da gar keine Ausgabe mehr.

my_xy_projekt:
Ich hab wirklich keine Ahnung, da ich die lib nicht benutze und auch sonst nicht brauche.
Damit ist dann der andere Thread erledigt.

Ich habe mich ja dazu entschlossen den LED Code ja in die Buttonfunktion zu schreiben.
Wenn du die lib nicht nutzt wie macht du das mit einer Multifunktion bei einem Button?

my_xy_projekt:
Vielleicht ist es die Zuordnung wert/wertalt und der tick.

In dem Code von mir ohne die Lib geht es ja auch mit wert/wertalt und der tick?

m8trix:
Ich habe deine Code Änderung mal getestet leider kommt da gar keine Ausgabe mehr.

Nicht leider. Es kommt nicht - fertig.
War meine Idee falsch.

Die Idee dahinter ist ja, das Wertalt und Wert ausserhalb der Abfrage "NichtGleich" jedes Mal gesetzt werden..
Wenn .tick dazu gehört, muss das also so.
Ich würde trotzdem Wertalt mit Wert füllen, wenn es nötig ist.
alt:

if (butWert[i] != butWertAlt[i]) {
  but = butNummer[i];
  Wert = butWert[i];
  button.tick();
}
butWertAlt[i] = butWert[i];

neu:

if (butWert[i] != butWertAlt[i]) {
  but = butNummer[i];
  Wert = butWert[i];
  butWertAlt[i] = butWert[i];
  button.tick();
}

Na dann...

Ich glaube nicht, dass man die OneButton Lib so verwenden kann. Die erwartet schon, dass sie an ihrem Pin genau einen Taster hat. Für mehrere Taster musst Du mehrere Instanzen anlegen. Ob man da immer den gleichen Pin angeben kann, und den dann zwischen den tick-Aufrufen umschaltet weis ich nicht - müsste man probieren.

Du könntest es auch mal mit der MoToButtons Klasse von den MobaTools versuchen. Die arbeiten zwar grundsätzlich etwas anders ( nicht mit Callback-Funktionen sondern mit 'klassischen' Methoden ), haben aber eine ähnlich Funktionalität wie die OneButton. Die MotoButtons sind aber eher darauf ausgerichtet viele Taster zu verwalten( bis zu 32 in einer Instanz ). Das Einlesen der 'Rohwerte' der Taster kannst Du in einem Callback machen , und damit auch mit deinem 4051. Du musst der Lib dann nur eine Bitleiste mit den eingelesenen Tasterwerten zur Verfügung stellen.

Ein Beispiel - auch mit den Callbacks - ist auch dabei.

Da MicroBahner schneller war, als ich mit meinem edit lasse ich meinen (schlechten) Ansatz stehen.

Trotzdem:

my_xy_projekt:

if (butWert[i] != butWertAlt[i]) {

but = butNummer[i];
 Wert = butWert[i];
 butWertAlt[i] = butWert[i];
 button.tick();
}

Das verhält sich leider wie bei meinen Code.
Das von MicroBahner verstehe ich nicht , allerdings Raucht mir auch schon der Schädel und versuche es morgen nochmal zu verstehen. Vielen Dank.

my_xy_projekt:
Da MicroBahner schneller war, als ich mit meinem edit lasse ich meinen (schlechten) Ansatz stehen.

Trotzdem:
OneButton/examples/TwoButtons/TwoButtons.ino at master · mathertel/OneButton · GitHub

Das verstehe ich und komme damit zu einer Lösung. Das glaube ich zu mindestens morgen wisst ihr mehr.
Mal schauen ob ich mich zum Affen mache.
Ich danke euch bis Morgen

m8trix:
Das von MicroBahner verstehe ich nicht ,

Ich dachte sowas in der Art:

#include <OneButton.h>

const byte dataPin_2 = 2;
OneButton buttons[4] = {
    { dataPin_2, true },
    { dataPin_2, true },
    { dataPin_2, true },
    { dataPin_2, true }
};

void setup() {
    // put your setup code here, to run once:
    ....
}

void loop() {
    for ( byte i=0; i<4; i++ ) {
        // hier den 8051 umschalten
        buttons[i].tick();
    }
    // put your main code here, to run repeatedly:
    ....
}

Edit: Code geändert

Aber ich würde es mit meinen MoToButtons lösen :wink:

MicroBahner:
Ich dachte sowas in der Art:....

Habe ich grade versucht bei mir umzusetzen wie folgt:

#include <OneButton.h>
int multiBut_sA = 5;  // select A
int multiBut_sB = 6;  // select B
int multiBut_sC = 7;  // select C
int dataPin_2 = 10;   // Daten
int butWert[8] = {0};
int butWertAlt[8] = {0};
int butNummer[] = {20,21,22,23,24,25,26,27};
int Wert = {0};
int but = {0};
OneButton buttons[8] = {
    { dataPin_2, true },
    { dataPin_2, true },
    { dataPin_2, true },
    { dataPin_2, true },
    { dataPin_2, true },
    { dataPin_2, true },
    { dataPin_2, true },
    { dataPin_2, true }
};
void setup() {
  pinMode(multiBut_sA, OUTPUT);
  pinMode(multiBut_sB, OUTPUT);
  pinMode(multiBut_sC, OUTPUT);
  pinMode(dataPin_2, INPUT_PULLUP);
  Serial.begin(9600);
  buttons[8].attachClick(singleClick[8]);
  buttons[8].attachDoubleClick(doubleClick[8]);
}
void loop() {
  for (int i = 0; i < 8; i++){
    digitalWrite(multiBut_sA, HIGH && (i & B00000001));
    digitalWrite(multiBut_sB, HIGH && (i & B00000010));
    digitalWrite(multiBut_sC, HIGH && (i & B00000100));
    butWert[i] = digitalRead(dataPin_2);
    
    if (butWert[i] != butWertAlt[i]) {
        but = butNummer[i];
        Wert = butWert[i];
        buttons[i].tick();      
        }
    butWertAlt[i] = butWert[i];
    }
  }
  
void singleClick1(){
  Serial.print("Button");
  Serial.print("  ");
  Serial.println(but);
  Serial.println("singleClick1() detected.");
  Serial.print("Status");
  Serial.print("  ");
  Serial.println(Wert);
  Serial.println("");
}
void doubleClick1(){
  Serial.print("Button");
  Serial.print("  ");
  Serial.println(but);
  Serial.println("doubleClick1() detected.");
  Serial.print("Status");
  Serial.print("  ");
  Serial.println(Wert);
  Serial.println("");
}
void singleClick2(){
  Serial.print("Button");
  Serial.print("  ");
  Serial.println(but);
  Serial.println("singleClick2() detected.");
  Serial.print("Status");
  Serial.print("  ");
  Serial.println(Wert);
  Serial.println("");
}
void doubleClick2(){
  Serial.print("Button");
  Serial.print("  ");
  Serial.println(but);
  Serial.println("doubleClick2() detected.");
  Serial.print("Status");
  Serial.print("  ");
  Serial.println(Wert);
  Serial.println("");
}

Leider kommt folgende Fehlermeldung:

Arduino: 1.8.13 (Windows 10), Board: "Arduino Leonardo"
C:\Users\M8TriX\Desktop\test ardu\text_mux_but_NEU\text_mux_but_NEU.ino: In function 'void setup()':
text_mux_but_NEU:31:26: error: 'singleClick' was not declared in this scope
   buttons[8].attachClick(singleClick[8]);
                          ^~~~~~~~~~~
C:\Users\M8TriX\Desktop\test ardu\text_mux_but_NEU\text_mux_but_NEU.ino:31:26: note: suggested alternative: 'singleClick2'
   buttons[8].attachClick(singleClick[8]);
                          ^~~~~~~~~~~
                          singleClick2
text_mux_but_NEU:32:32: error: 'doubleClick' was not declared in this scope
   buttons[8].attachDoubleClick(doubleClick[8]);
                                ^~~~~~~~~~~
C:\Users\M8TriX\Desktop\test ardu\text_mux_but_NEU\text_mux_but_NEU.ino:32:32: note: suggested alternative: 'doubleClick2'
   buttons[8].attachDoubleClick(doubleClick[8]);
                                ^~~~~~~~~~~
                                doubleClick2
exit status 1
'singleClick' was not declared in this scope

Darauf hin habe ich dann den Code ergäntzt:

int singleClick[8];
int doubleClick[8];

Es kommt zwar keine Fehlermeldung mehr aber auch keine Ausgabe im Seriellen Monitor.

m8trix:

  buttons[8].attachClick(singleClick[8]);

buttons[8].attachDoubleClick(doubleClick[8]);

So kann das auch nicht funktionieren. Du hast nun 8 Instanzen der OneButton, da musst Du auch jeder einzelnen Instanz eine Callback-Funktion zuordnen. Du kannst vermutlich auch jeder die gleiche Callback zuordnen, aber Du musst es für jede Instanz einzeln machen.

Die Lib heißt nicht umsonst 'OneButton' :wink: Für mehrere Button ist die nMn eher nicht so toll. Sie geht auch nicht gerade sparsam mit den RAM-Ressourcen um.

Edit: und kannst Du mal erklären, wozu dieser Konstrukt gut sein soll:

    butWert[i] = digitalRead(dataPin_2);
    
    if (butWert[i] != butWertAlt[i]) {
        but = butNummer[i];
        Wert = butWert[i];
        buttons[i].tick();      
        }
    butWertAlt[i] = butWert[i];
    }

Für die Auswertung der Taster ist doch die OneButton da.

  buttons1.attachClick(singleClick1);
  buttons1.attachClick(singleClick2);
  buttons1.attachClick(singleClick3);
  buttons1.attachClick(singleClick4;
  buttons1.attachClick(singleClick5);
  buttons1.attachClick(singleClick6);
  buttons1.attachClick(singleClick7);
  buttons1.attachClick(singleClick8);
  buttons1.attachDoubleClick(doubleClick1);
....
....

Das hatte ich schon versucht allerdings kommt dann wieder eine Fehlermeldung:
'buttons1' was not declared in this scope

Und wenn ich dann deine Code:

MicroBahner:
Ich dachte sowas in der Art:

#include <OneButton.h>

const byte dataPin_2 = 2;
OneButton buttons[4] = {
   { dataPin_2, true },
   { dataPin_2, true },
   { dataPin_2, true },
   { dataPin_2, true }
};



ändere in:



OneButton buttons1(dataPin_2, true);  
OneButton buttons2(dataPin_2, true);
....
....





kommt die F:ehler Meldung:

exit status 1
'buttons' was not declared in this scope

MicroBahner:
Edit: und kannst Du mal erklären, wozu dieser Konstrukt gut sein soll:

    butWert[i] = digitalRead(dataPin_2);

if (butWert[i] != butWertAlt[i]) {
       but = butNummer[i];
       Wert = butWert[i];
       buttons[i].tick();      
       }
   butWertAlt[i] = butWert[i];
   }



Für die Auswertung der Taster ist doch die OneButton da.

Da reicht glaube ich:

buttons[i].tick();

Ich habe die Taster mit einen anderen Code (nur 1click) am laufen und ich wollte die Lib da einbinden
und wenn es läuft der Rest rausschmeißen.

So sollte das gehen:

for (int i = 0; i < 8; i++){
  buttons[i].attachClick(singleClick);
  buttons[i].attachDoubleClick(doubleClick);
}

Wenn Du die OneButton Instanzen als Array anlegst, musst Du die auch immer mit einem Arrayindex ansprechen.

Danke!!! Jetzt geht es super.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.