Mehrere LEDs und Taster an einem Arduino Due

Hallo,
ich versuche eine Motorsteuerung zu bauen. Dafür benötige ich 12 verschiedene Geschwindigkeiten, die über analogWrite eingestellt werden. Das ganze soll über 12 Taster, die mit LEDs ausgestattet sind, angesteuert werden. Dafür habe ich bereits einen Code geschrieben, der soweit auch funktioniert. Jedesmal wenn ich einen Taster drücke soll sich die jeweils dahinter befinde Geschwindigkeit einstelle.. Es gibt jedoch noch ein Problem: Die LEDs in den Tastern sollen immer nur so lange leuchten, bis man eine neue Geschwindigkeit, also Taster, drückt. Das funktioniert jedoch nicht, denn die LEDs leuchten dauerhaft. Ich müsste in jedem if-Statement nochmal vorherige LEDs wieder deaktivieren. Gibt es dafür eine einfachere Möglichkeit, außer alle 11 anderen LEDs immer in jedem if-Statement zu deaktivieren?
Und gibt es insgesamt eine einfachere Variante, als das was ich bisher fabriziert habe?
Anbei noch der bisherige Code:


#include <Bounce2.h>

#define BUTTON_1 44 
#define BUTTON_2 45  
#define BUTTON_3 42  
#define BUTTON_4 43  
#define BUTTON_5 40  
#define BUTTON_6 41  
#define BUTTON_7 38  
#define BUTTON_8 39  
#define BUTTON_9 36  
#define BUTTON_10 37  
#define BUTTON_11 34 
#define BUTTON_12 35 
#define LED_1 30
#define LED_2 22
#define LED_3 33
#define LED_4 31
#define LED_5 32
#define LED_6 28
#define LED_7 26
#define LED_8 29
#define LED_9 24
#define LED_10 27
#define LED_11 23
#define LED_12 25
bool light_on1 = true;
bool light_on2 = true;
bool light_on3 = true;
bool light_on4 = true;
bool light_on5 = true;
bool light_on6 = true;
bool light_on7 = true;
bool light_on8 = true;
bool light_on9 = true;
bool light_on10 = true;
bool light_on11 = true;
bool light_on12 = true;


Bounce debouncer1 = Bounce();
Bounce debouncer2 = Bounce();
Bounce debouncer3 = Bounce();
Bounce debouncer4 = Bounce();
Bounce debouncer5 = Bounce();
Bounce debouncer6 = Bounce();
Bounce debouncer7 = Bounce();
Bounce debouncer8 = Bounce();
Bounce debouncer9 = Bounce();
Bounce debouncer10 = Bounce();
Bounce debouncer11 = Bounce();
Bounce debouncer12 = Bounce();

void setup() {

 
  pinMode(BUTTON_1, INPUT);
  pinMode(BUTTON_2, INPUT);
  pinMode(BUTTON_3, INPUT);
  pinMode(BUTTON_4, INPUT);
  pinMode(BUTTON_5, INPUT);
  pinMode(BUTTON_6, INPUT);
  pinMode(BUTTON_7, INPUT);
  pinMode(BUTTON_8, INPUT);
  pinMode(BUTTON_9, INPUT);
  pinMode(BUTTON_10, INPUT);
  pinMode(BUTTON_11, INPUT);
  pinMode(BUTTON_12, INPUT);
  pinMode(LED_1, OUTPUT);
  pinMode(LED_2, OUTPUT);
  pinMode(LED_3, OUTPUT);
  pinMode(LED_4, OUTPUT);
  pinMode(LED_5, OUTPUT);
  pinMode(LED_6, OUTPUT);
  pinMode(LED_7, OUTPUT);
  pinMode(LED_8, OUTPUT);
  pinMode(LED_9, OUTPUT);
  pinMode(LED_10, OUTPUT);
  pinMode(LED_11, OUTPUT);
  pinMode(LED_12, OUTPUT);
  
  analogWriteResolution(10);
  

  
  debouncer1.attach(BUTTON_1);
  debouncer1.interval(5);
  debouncer2.attach(BUTTON_2);
  debouncer2.interval(5);
  debouncer3.attach(BUTTON_3);
  debouncer3.interval(5);
  debouncer4.attach(BUTTON_4);
  debouncer4.interval(5);
  debouncer5.attach(BUTTON_5);
  debouncer5.interval(5);
  debouncer6.attach(BUTTON_6);
  debouncer6.interval(5);
  debouncer7.attach(BUTTON_7);
  debouncer7.interval(5);
  debouncer8.attach(BUTTON_8);
  debouncer8.interval(5);
  debouncer9.attach(BUTTON_9);
  debouncer9.interval(5);
  debouncer10.attach(BUTTON_10);
  debouncer10.interval(5);
  debouncer11.attach(BUTTON_11);
  debouncer11.interval(5);
  debouncer12.attach(BUTTON_12);
  debouncer12.interval(5);

}

void loop() {
  // Update the Bounce instance :
  debouncer1.update();
  debouncer2.update();
  debouncer3.update();
  debouncer4.update();
  debouncer5.update();
  debouncer6.update();
  debouncer7.update();
  debouncer8.update();
  debouncer9.update();
  debouncer10.update();
  debouncer11.update();
  debouncer12.update();


  if (debouncer1.fell() ) {
    light_on1 = !light_on1;
    digitalWrite(LED_1, light_on1 );
      analogWrite(66,100);
  }
    if (debouncer2.fell() ) {
    light_on2 = !light_on2;
    digitalWrite(LED_2, light_on2 );
    analogWrite(66,200);
  }
    if (debouncer3.fell() ) {
    light_on3 = !light_on3;
    digitalWrite(LED_3, light_on3 );
    analogWrite(66,300);
  }
    if (debouncer4.fell() ) {
    light_on4 = !light_on4;
    digitalWrite(LED_4, light_on4 );
    analogWrite(66,400);
  }
    if (debouncer5.fell() ) {
    light_on5 = !light_on5;
    digitalWrite(LED_5, light_on5 );
    analogWrite(66,500);
  }
    if (debouncer6.fell() ) {
    light_on6 = !light_on6;
    digitalWrite(LED_6, light_on6 );
    analogWrite(66,600);
  }
    if (debouncer7.fell() ) {
    light_on7 = !light_on7;
    digitalWrite(LED_7, light_on7 );
    analogWrite(66,700);
  }
    if (debouncer8.fell() ) {
    light_on8 = !light_on8;
    digitalWrite(LED_8, light_on8 );
    analogWrite(66,800);
  }
    if (debouncer9.fell() ) {
    light_on9 = !light_on9;
    digitalWrite(LED_9, light_on9 );
    analogWrite(66,900);
  }
    if (debouncer10.fell() ) {
    light_on10 = !light_on10;
    digitalWrite(LED_10, light_on10 );
    analogWrite(66,1000);
  }
    if (debouncer11.fell() ) {
    light_on11 = !light_on11;
    digitalWrite(LED_11, light_on11 );
    analogWrite(66,10);
  }
    if (debouncer12.fell() ) {
    light_on12 = !light_on12;
    digitalWrite(LED_12, light_on12 );
    analogWrite(66,1023);
  }
   
}

Ich bin für Tips und HIlfe sehr dankbar :slight_smile:
Vielen Dank und viele Grüße
J

Also, wenn Du sowieso auf das auslösen der Taste reagieren willst, kannst Du auf das debouncen verzichten.
Du reagierst ja nicht auf das loslassen :wink:

Dann gehört das zusammengefasst und nicht in so unendlich langem Code geschrieben. Da werden ja die Finger wund und die Augen brennen.

Und dann mal ne Frage: Bist Du sicher, das 1023 auf den PWM-Pin richtig ist?

Ich habs drin gelassen.
Versuch mal, ob das geht:
(Hinweis: Ich gehe davon aus, das mit Level LOW die gedrückte Taste erkannt wird. Wenn die HIGH ist, musst die constante ändern)


const byte myButton[] = {44, 45, 42, 43, 40, 41, 38, 39, 36, 37, 34, 35};
const byte anzahlTast = sizeof(myButton) / sizeof(myButton[0]);
const byte butLed[anzahlTast] = {30, 22, 33, 31, 32, 28, 26, 29, 24, 27, 23, 25};
const bool gedrueckt = LOW; // Pegel bei dem erkannt wird, das die Taste gedrückt wurde

void setup()
{
  for (byte b = 0; b < anzahlTast; b++)
  {
    pinMode(myButton[b], INPUT);
    digitalWrite(butLed[b], LOW);
    pinMode(butLed[b], OUTPUT);
  }
  analogWriteResolution(10);
}
void loop()
{
  for (byte b = 0; b < anzahlTast; b++)
  {
    if (digitalRead(myButton[b]) == gedrueckt) // siehe #8
    {
      antrieb(b);
    }
  }
}
void antrieb(const byte nummer)
{
  for (byte b = 0; b < anzahlTast; b++)
    digitalWrite(butLed[b], LOW);
  digitalWrite(butLed[nummer], HIGH);
  switch (nummer)
  {
    case 0: analogWrite(66, 100); break;
    case 1: analogWrite(66, 200); break;
    case 2: analogWrite(66, 300); break;
    case 3: analogWrite(66, 400); break;
    case 4: analogWrite(66, 500); break;
    case 5: analogWrite(66, 600); break;
    case 6: analogWrite(66, 700); break;
    case 7: analogWrite(66, 800); break;
    case 8: analogWrite(66, 900); break;
    case 9: analogWrite(66, 1000); break;
    case 10: analogWrite(66, 10); break;
    case 11: analogWrite(66, 1023); break;
    default: analogWrite(66, 0); break;
  }
}

Pin 66 ist DAC2, also nicht PWM!

DANKE!
Stimmt ist ja nen Due.... ;(

Dann stimmt auch 0 bis 1023, fehlt bei Dir :slightly_smiling_face:

... nicht mehr :slight_smile:

#define BUTTON_1 44 
#define BUTTON_2 45  
#define BUTTON_3 42  
#define BUTTON_4 43  

Solche Variablen Gräber in Spaghettiform tun mir weh.
Bitte Informiere Dich was Arrays sind und benutze diese. Das macht den Code auf ca 1/10 schrumpfen.

Du mußt den ansteigenden und fallend Flanke benutzen um die LED einzuschalten und dann auszuschalten.

Grüeß Uwe

Ist Dir hier eine Klammer verrutscht?
if (digitalRead(myButton[b]) == gedrueckt)

Ja, ich sas noch rüttelnd im öffie...

Warum?
Er will doch nur die zuletzt aktivierte LED sehen. vorher alle aus - und nur die eine an.

Mir auch!
Und die nachfolgenden Codeduplikate eigentlich noch mehr.

Wie auch immer man es gestaltet, es werden 2 Durchläufe nötig sein.

Durchaus!

Mir würde spontan sowas einfallen:

constexpr unsigned analogPin {66}; 

struct Stufe
{
  unsigned button; 
  unsigned led;
  unsigned speed; // analog value

  void init()
  {
    pinMode(button,INPUT);
    pinMode(led,OUTPUT);
  }

   Stufe *check()
   {
     return digitalRead(button)?this:nullptr;
   }
   
   void set(Stufe *stufe, unsigned analogPin)
   {
     if(stufe==this)
     {
      analogWrite(analogPin,speed);
      digitalWrite(led,1);
     } else digitalWrite(led,0);
   }

};

Stufe stufen[] {  // button, led, analog
                 {       2,  13,    100 },  
                 {       4,  12,    127 },  
                 {       3,  11,    255 },  
               };


void machDieStufenAbhandlung()
{
   Stufe *ptr {nullptr};
   for(Stufe &s:stufen) if((ptr = s.check())) break; 
   if(ptr) for(Stufe &s:stufen) s.set(ptr,analogPin);          
}

void setup() 
{
 // analogWriteResolution(10);
  for(Stufe &s:stufen) s.init();
}

void loop() 
{
   machDieStufenAbhandlung();
}

Da kann schon mal 'ne Klammer verrüttelt werden :blush:

Ich sitze hingegen am ruhigen Schreibtisch und hätte da noch die gegenüber combie einfache OOP-Variante, unübersehbar abgeleitet aus #2. Getestet mit Mega2560 (ohne DAC!):

const byte motorPin = 13;  // 66;
const bool gedrueckt = LOW; // Pegel bei dem erkannt wird, das die Taste gedrückt wurde

class Taster
{
    const byte button;
    const byte led;
    const int16_t pwm;
  public:
    Taster(	const byte button, const byte led, const uint16_t pwm ) : button(button), led(led), pwm(pwm)
    {}
    void init()
    {
      pinMode(button, INPUT_PULLUP);
      pinMode(led, OUTPUT);
    }

    int16_t run()
    {
      int16_t rueck = -1;
      if (digitalRead(button) == gedrueckt)
      {
        rueck = pwm;
      }
      return rueck;
    }

    void ledAus()
    {
      digitalWrite(led, LOW);
    }

    void ledEin()
    {
      digitalWrite(led, HIGH);
    }
};

Taster taster[] =
{
  //button, led, pwm
  {44, 30,  100},
  {45, 22,  200},
  {42, 33,  300},
  {43, 31,  400},
  {40, 32,  500},
  {41, 28,  600},
  {38, 26,  700},
  {39, 29,  800},
  {36, 24,  900},
  {37, 27, 1000},
  {34, 23,   10},
  {35, 25, 1023}
};

void setup()
{
  for (auto &t : taster) t.init();
  //analogWriteResolution(10);
}

void loop()
{
  int16_t p = 0;
  for (auto &t : taster)
  {
    p = t.run();
    if (p > 0)
    {
      for (auto &l : taster) l.ledAus();
      t.ledEin();
      analogWrite(motorPin, p / 4);  // Mega2560 0 bis 255
    }
  }
}
1 Like

Vielen herzlichen Dank. Funktioniert einwandfrei, und ich glaube auch, dass ich es verstehe.
Auch vielen Dank an alle für die schnelle Hilfe, bringt mich sehr schnell weiter bei meinem Projekt.
Anbei noch ein Foto von der Steuerung:

Was sind das für Taster, kann man die beschriften?

Das sind Eaton Q18D und ja man kann das Vorderteil öffnen und auf Klarsichtfolie Beschriftung anbringen und einlegen. Hinten am Schalter kann man dann entweder Öffner oder Schließer anbringen, gibt zwei Steckplätze für Schalter.
Sind neu relativ teuer, aber gibt es oft in der Bucht sehr günstig. Habe für 20 Taster + Schalter gerade mal 12€ bezahlt. Danach noch Kontakte gereinigt und dann lief alles wieder 1A.

1 Like

Du hasst recht. Ich hatte das nicht aufmerksam genug gelesen und die LED sollte in meiner Version nur solange leuchten wie der Taster gedrückt war.
Grüße Uwe

1 Like

Da schaue ich wahrscheinlich eine andere Bucht an ich finde sie nicht unter 4,9€ (druckteil ohne Kontakte)

Grüße Uwe

Neu.
Die gebrauchten sind schon weg.
Die Zeiten sind andere :wink:

Ich hab Mega2560-embed für 7 Eur bekommen. Jetzt bekomm ich selbst zum doppelten Preis nicht einen... :cry:

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