Mit einem Button mehrere Lichtszenen durchwählen.

Heo, ich habe gerade eine kleine Aufgabe, die ich irgendwie nicht ganz gelöst bekomme.

Ich schaffe es wohl, mit einem Button eine LED an und aus zu schalten, aber im gegebenen Fall sollen drei verschiedene LED Leuchten durgegangen werden und beim vierten Mal dann ausgehen. Also 1, 2, 3, aus.

Ich habe es schon mit pushcounter versucht, konnte aber nie mehr als 2 LEDs wechseln lassen.

Habt ihr eine Idee, wie man das lösen kann?

Ich schaffe es wohl, mit einem Button eine LED an und aus zu schalten

Das ist schon mal gut!

Die Sequenz machst Du z.B. so:

  • bei jedem Tastendruck einen Zähler erhöhen
  • je nach Zählerstand die richtige LED einschalten und die anderen aus

Zählen wirst Du können, begrenzen auf die n-Mal kannst Du bequem per Modulo, den Status per switch case auswerten.

Und dann zeig uns den Code.

Wichtig bei dieser Aktion, den Taster entprellen und Pullup oder Pulldown einsetzen.

Dir fehlt das theoretische Konzept, ob du das programmieren kannst, ist erst in zweiter Hinsicht wichtig.

  1. simple state machine (0,1,2,3)

  2. je nach Status gibst du eine andere Szene aus, auch "AUS" bzw. Status 0 ist eine Szene.

Dazu sollten die Szene irgendwie einzeln gespeichert werden, z.B jeweils als Zeichenkette (z.B. "0110", jede Stelle für eine LED, 0 aus, 1 ein). Also: je nach Status übergibst du dann einer Ausgabe-Funktion eine solche Szenen-Beschreibung als Parameter.

Also brauchst du noch (mind.) eine Funktion, die diese Zeichenketten interpretieren kann und je nach Position und Wert der enthaltenen Stellen die jeweils zugeordnete LED schaltet.

Wenn man es richtig schön modular machen möchte, definiert man noch eine weitere Funktion, der man als Parameter die LED-Position/Nummer und den Schaltzustand (0 oder 1) übergibt ...

Der große Vorteil dieser (möglicherweise von einigen Besserwissern hier) als "umständlich" bezeichneten - Methodik ist, dass man die einzelnen Funktionen getrennt entwickeln und testen kann und das das Programm später mal problemlos verändert oder erweiteret werden kann.

Beispiel: Irgendwann möchtest du evtl. die LEDs nicht nur an/aus-schalten, sondern per PWM unterschiedlich hell leuchten lassen. Dann bräuchtest du lediglich die eine Funktion zu verändern, die die einzelnen LEDs ansteuert, und natürlich die hinterlegten Szenenbeschreibungen (z.B. statt "0110" nun eben "0F30"). Der gesamte Rest des Programmes kann unverändert bleiben.

Und auch nach einem Jahr versteht man noch, was da passiert, wenn man mal wieder in den Code guckt.

(möglicherweise von einigen Besserwissern hier)

Du meinst mich?

Habt ihr eine Idee, wie man das lösen kann?

Ja klar!

Habe sogar was fertiges in meiner Wühlkiste.
Weiß aber nicht ob dir das hilft...
Aber evtl. kannste dir was davon abschauen.

Der Taster hängt an A0 und die LEDs an den Pin 10 11 und 12 eines UNO

#include <CombiePin.h>
#include <CombieTimer.h>
#include <CombieTools.h>

using namespace Combie::Tools;
using namespace Combie::Timer;
using namespace Combie::Pin; 

using CounterType = Counter<byte>;

TasterGND<A1>     taster; // Taster gegen GND geschaltet
EntprellTimer     entprellen(20);
FlankenErkennung  flankenerkennung;
CounterType       counter;

// LEDs an Pin 10(PB2) 11(PB3) und 12(PB4) eines UNO
byte maske {_BV(PB2)|_BV(PB3)|_BV(PB4)};
byte muster[] {0,_BV(PB2),_BV(PB3),_BV(PB4)};


void ledAction(CounterType &counter) 
{
    if(counter >= (sizeof(muster)/sizeof(muster[0]))) counter.reStart();// wraparound
    PORTB =  (PORTB & ~maske)| muster[counter];
}

void setup() 
{
    taster.initPullup();
    PORTB &=~maske; // leds low setzen
    DDRB  |= maske; // leds Output setzen
    counter.onCount(ledAction);
}

void loop() 
{ 
  counter = flankenerkennung = entprellen = taster;
}

CombieLib.zip (53.9 KB)

Das sieht erst mal ok aus. Ich schaue mal, was sich damit machen lässt.

Dann ist zumindest der Grundstein zum herumcoden da.