buttons in reihenfolgespeichern

hallo allerseits,

ich hab ein kleines programmierproblem.
und zwar habe ich 3 buttons und 3 leds und möchte das die leds in der reihenfolge leuchten in der ich die buttons drücke und gedrückt halte.
Wenn ich dann einen button loslasse soll der Wert aktualisiert werden.

z.B. ich drücke button 2 dann 1 dann 3 dann soll erst die led 2 dann 1 dann 3 leuchten.
Lass ich nun button 1 los dann sollen nur die Led 2 dann 3 leuchten. Drück ich dann wieder den button 1 dann sollen die Leds 2 dann 3 dann 1 leuchten.

Eigentlich dachte ich dass das ziemlich einfach mit arrays gehen sollte, jedoch komm ich da einfach nicht weiter.

Wäre für ideen und ratschläge sehr dankbar.

greetz Julia

Ich bin ziemlicher Neuling, deshalb gibts wahrscheinlich deutlich bessere Lösungen als meine.

Ich habe das für einen Knopf mal mit einer Whileschleife in Verbindung mit millis() (gibt zurück wie lange das Arduino schon an ist.) gemacht.

In loop() prüfen ob knopf gedrückt wird. die Zeit wann der knopf gedrückt wird in eine variable speichern .

long timerStart=millis();

Dann "While" knopf gedrückt solange in schleife bleiben und nix tun. bis knopf losgelassen wird.

jetzt die dauer speichern.

long timerZeit=millis() - timerStart;

Dann kannst du ja ne sek, warten um zu gucken ob weitere knöpfe gedrückt werden. Wenn du auch gleichzeitig Knöpfe drücken willst musst du in der Whileschleife noch prüfen ob andere Knöpfe gedrückt werden und separate Timer nutzen.

Um die Led dann die Zeit leuchten zu lassen kannst du dann z.b.

eine Led solange in einer while schleife leuchten lassen bis die leuchtdauer = der timerZeit ist.

Aber wie gesagt. Vermutlich gehts auch noch deutlich einfacher.

gruß.

z.B. ich drücke button 2 dann 1 dann 3 dann soll erst die led 2 dann 1 dann 3 leuchten.

Hälst Du 2 gedrückt, wenn Du 1 drückst? Hälst Du 2 und 1 gedrückt, wenn Du 3 drückst?

Lass ich nun button 1 los dann sollen nur die Led 2 dann 3 leuchten.

Hälst Du denn Button2 und 3 weiterhin gedrückt?

Wie gross soll die Verzögerung sein zwischen LED an/aus und Button gedrückt/losgelassen?

Hast Du nur 3 Buttons oder werden es später mehr?

Betrachten wir mal als Datenstruktur ein Array mit drei Positionen:

Im ersten Feld steht der erste Button, der gedrückt wurde, im zweiten Feld der zweite Button und im dritten Feld der dritte Button.
Für Dein Beispiel:
2 gedrückt, dann 1 gedrückt, dann 3 gedrückt:
[2,1,3]
Dann 1 losgelassen:
[2,0,3]->sortieren->[2,3,0]
Dann 1 wieder gedrückt:
[2,3,1]

Das Programm soll regelmässig die drei Buttons abfragen und bei einer Veränderung das Array entsprechend updaten und im Anschluss die LEDs blinken lassen. Somit sind drei Programmschritte definieret.

Ich habe mal folgendes schnell zusammen gehackt, vielleicht hilft es ja:

#define Button1 2
#define Button2 3
#define Button3 4

#define LED1 11
#define LED2 12
#define LED3 13

#define BUTTON_ACTIVE_LEVEL LOW //LOW=activeLow, HIGH=activeHigh
#define LED_ACTIVE_LEVEL HIGH //LOW=activeLow, HIGH=activeHigh

uint8_t previousButtonsValue = 0;
uint8_t currentButtonsValue = 0;

uint8_t sequence[3];

void setup()
{
  pinMode(Button1, INPUT);
  pinMode(Button2, INPUT);
  pinMode(Button3, INPUT);

  //activate Pull-Up Resistors in case of activeLow buttons
  if(BUTTON_ACTIVE_LEVEL == LOW)
  {
    digitalWrite(Button1, HIGH);
    digitalWrite(Button2, HIGH);
    digitalWrite(Button3, HIGH);
  }

  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);

  //disable all LEDs
  if(LED_ACTIVE_LEVEL == LOW)
  {
    digitalWrite(LED1, HIGH);
    digitalWrite(LED2, HIGH);
    digitalWrite(LED3, HIGH);
  }

}


void loop()
{
  uint8_t z,b;

  //1. read buttons
  currentButtonsValue  = digitalRead(Button1) ;
  currentButtonsValue |= digitalRead(Button2) << 1;
  currentButtonsValue |= digitalRead(Button3) << 2;

  //invert values in case of activeLow Buttons
  if(BUTTON_ACTIVE_LEVEL == LOW)
  {
    currentButtonsValue = ~currentButtonsValue;
  }

  //2. check if buttons changed
  if(previousButtonsValue != currentButtonsValue)
  {

    for(b=0; b<3;b++)
    {
      if( (currentButtonsValue&(1<<b)) != (previousButtonsValue&(1<<b)) )//button changed
      {
        if( (currentButtonsValue&(1<<b))  )//button is pressed and was not pressed before -> add button to array
        {
          for(z=0; z<3;z++)
          {
            if(sequence[z] == 0)
            {
              sequence[z] = b+1;
              break;
            }
          }
        }
        else//button is no longer pressed -> remove (set to 0) button from array (and sort array in the same step)
        {
          for(z=0; z<3;z++)
          {
            if(sequence[z] == b+1)
            {
              if(z==0)
              {
                sequence[0] = sequence[1];
                sequence[1] = sequence[2];
                sequence[2] = 0;
              }
              else if(z==1)
              {
                sequence[1] = sequence[2];
                sequence[2] = 0;
              }
              else
              {
                sequence[2] = 0;
              }
            }
          }
        }
      }
    }



    //3. show sequence on LEDs

    //switch all LEDs off
    digitalWrite(LED1, !LED_ACTIVE_LEVEL);
    digitalWrite(LED2, !LED_ACTIVE_LEVEL);
    digitalWrite(LED3, !LED_ACTIVE_LEVEL);
    delay(200);

    for(z=0; z<3; z++)
    {
      if(sequence[z] == 1)
      {
        digitalWrite(LED1, LED_ACTIVE_LEVEL);        
      }
      else if(sequence[z] == 2)
      {
        digitalWrite(LED2, LED_ACTIVE_LEVEL);        
      }
      else if(sequence[z] == 3)
      {
        digitalWrite(LED3, LED_ACTIVE_LEVEL);        
      }
      delay(600);//wait a short time
    }
    previousButtonsValue = currentButtonsValue;
  }
}

Du solltest also
Button1 an DigitalPin 2,
Button2 an DigitalPin 3,
Button3 an DigitalPin 4,

LED1 an DigitalPin 11,
LED1 an DigitalPin 12,
LED1 an DigitalPin 13,
hängen. Mit dem kurzen Bein der LED an GND und das lange Bein mit einem Vorwiderstand an den jeweiligen Pin...
Die Schalter (bzw. Kabel) willst Du mit einem Bein an GND anschließen, das andere Ende an den jeweiligen Pin.

Ist das ungefähr das, wonach Du gesucht hast?

Du kannst auch die LEDs und Buttons in der Logik invertieren wenn das sein musst - dazu einfach LED_ACTIVE_LEVEL und BUTTON_ACTIVE_LEVEL oben im Quellcode ändern.

Andere Pins kannst Du ebenfall ganz oben im Quellcode festlegen falls Deine Anwendung das verlangt.

Das Array, in das die Reihenfolge gespeichert wird nennt sich sequence...

Die Pausezeit, die ich bei delay(600) unten im Quellcode angegeben habe erlaubt es, schön mit dem Auge zu prüfen, welche LED in welcher Reihenfolge an geht... nach jedem Buttonwechsel sind natürlich erstmal alle LEDs aus und gehen dann entsprechend der Reihenfolge an...

hey,
vielen vielen dank für die umfassende Hilde :slight_smile:

Hälst Du 2 gedrückt, wenn Du 1 drückst? Hälst Du 2 und 1 gedrückt, wenn Du 3 drückst?

ja, die tasten sollen immer gedrückt sein.
Werden später noch mehr leds, aber mir hatte komplett der Ansatz gefehlt wie man sowas umsetzt. Der Code ist ja schon fast perfekt.

Danke nochmal!

greez
Julia