Umschaltung realisieren mit Schalter von Led1 auf Led2

Hallo Zusammen

Habe mich gerade neu angemeldet, mein Name ist Thomas und erfreue mich mal mehr mal weniger an den Tücken eines µC und dessen Programmierung.

Wo liegt mein Problem…

Funktion die ich realiseren möchte ist eigentlch recht einfach und schnell erklärt…es mag aber einfach nicht so wie ich es gerne hätte.

Schalter…ist dieser betätigt soll Led1 angehen. Schalter aus—Led1 aus.
Schalter erneut betätigt soll nun Led2 angehen. Schalter aus—Led2 aus.
Schalter erneut betätigt…wieder Led1 an us usw

Es geht um eine Umschaltung…ich bekomme es ohne Hilfe einfach nicht hin.

Hier mein Code…mal schalten die Led,s wie gewünscht…mal geht mehrmals immer nur die gleiche Led an…dann gehts mal wieder für 2-3 wie gewünscht

Ich bin im Moment leider etwas überfordert

#include <Bounce2.h>  //kommt später zum Entprellen


#define Schalter 2      // Schalter PIN definieren
#define LED_ONE 3       // Schütz 1
#define LED_TWO 13      // Schütz 2

//boolean Umschalt = false;    // Hier speichern wir, welche LED angesteuert werden soll
boolean SchalterState = false; // Hier speichern wir den momentanen Button Zustand


void setup()
{
  //Serial.begin(9600);
  pinMode(Schalter, INPUT);      // PINs als Aus-/Eingänge setzen
  digitalWrite(Schalter, HIGH);  //interner Pullup, Schalter schaltet gegen Masse auf LOW
  pinMode(LED_ONE, OUTPUT);
  pinMode(LED_TWO, OUTPUT);
 
 
}

void Motorenaus(){
   
    digitalWrite(LED_ONE, LOW);     //mal sehen für was es gut sein könnte
    digitalWrite(LED_TWO, LOW);
  }

void loop()
{
   
  if(digitalRead(Schalter) == LOW && SchalterState == false)
  {
    delay(200);                      //entprellen für Arme
    //Umschalt =! Umschalt;          // Die leuchtende LED wechseln   
    digitalWrite(LED_ONE, HIGH);
    //SchalterState = true;          // buttonState auf true setzen
  }

  else  {
    //delay(50);
    digitalWrite(LED_ONE, LOW);
    SchalterState = true;
  }


  if(digitalRead(Schalter) == LOW && SchalterState == true)
  {
    delay(200);
    //Umschalt =! Umschalt;          // Die leuchtende LED wechseln 
    digitalWrite(LED_TWO, HIGH);
    //SchalterState = false;         // buttonState auf true setzen

  }

  else{
    //delay(50);
    digitalWrite(LED_TWO, LOW);
    SchalterState = false;
  }
    //Serial.println(SchalterState);
}

Zuerst mal der übliche Hinweis: Code bitte in Code Tags </> einschließen, Du kannst das auch nachträglich in Deinem Posting ändern (Quick Edit…).

Am einfachsten dürfte so eine Steuerung mit einem Automaten werden, d.h. eine Statusvariable mit den Zuständen Aus1, LED1an, Aus2, LED2an. Diese Variable wird weitergezählt wenn die Taste gedrückt wird - nicht wenn sie gedrückt ist! Nach dem letzten Zustand wird sie wieder auf den Anfangswert gesetzt. Danach z.B. in einem switch Statement die LEDs schalten.

Hallo

Ich sollte noch erwähnen das ich in Sachen Programmierung noch nicht so standfest bin.

Dank dir für die Anregung, auch wenn ich sie noch nicht so recht nachvollziehen kann.

Also eine Statusvariable mit 4 Zuständen, diese Variable soll weiter gezählt werden wenn der Schalter (ich habe keine Taster) schaltet und nicht wenn er geschaltet hat

Sorry....das habe ich nicht verstanden

Gruß Thomas

Der Code scheint sehr undurchsichtig...lass mich raten, was passiert: Schalter nicht betätigt: beide LEDs aus; Schalter betätigt, beide LEDs an (wobei eine 0,2s nach der Betätigung angeht, die Andere nach 0,4s)...liege ich da richtig?

Was ich auf den ersten Blick erkennen kann: die Entprellung funktioniert so nicht. Beim Entprellen fragt man den Schalterzustand ab, wartet eine sehr kurze Zeit, und fragt den Schalterzustand erneut ab....sind beide Zustände gleich, kann weiter verfahren werden

Dein Sketch etwas abgespeckt:

#define Schalter 2      // Schalter PIN definieren
#define LED_ONE 3       // Schütz 1
#define LED_TWO 13      // Schütz 2

boolean umschalt = false;    // Hier speichern wir, welche LED angesteuert werden soll
boolean aktState, altState; // Hier speichern wir den momentanen Button Zustand


void setup()
{
  //Serial.begin(9600);
  pinMode(Schalter, INPUT);      // PINs als Aus-/Eingänge setzen
  digitalWrite(Schalter, HIGH);  //interner Pullup, Schalter schaltet gegen Masse auf LOW
  pinMode(LED_ONE, OUTPUT);
  pinMode(LED_TWO, OUTPUT);
  aktState = digitalRead(Schalter);
  altState = aktState;
}

void loop()
{
  aktState = digitalRead(Schalter);
  delay(20);                       //entprellen für Arme
  if (altState && !aktState)
  {
    digitalWrite(LED_ONE, !umschalt);
    digitalWrite(LED_TWO, umschalt);
    umschalt = !umschalt;
  }
  altState = aktState;
  if (aktState)
  {
    digitalWrite(LED_ONE, LOW);
    digitalWrite(LED_TWO, LOW);
  }
}

Hallo

Das Entprellen wollte ich später per Bounce2 realisieren.

Mit deiner Einschätzung liegt nicht richtig…die LED,s schalten nicht nacheinander u. zeitversetzt ein. Mal funktioniert die Umschaltung, mal wird mehrmals immer die gleiche LED eingeschaltet, dann gehts wieder x male.

Ich weis das am Code was faul ist, alleine schon die false und true Zuweisung in der else, das kann eigentlich so nicht klappen, aber weiter bin ich nicht gekommen

Gruß Thomas

Mit deiner Einschätzung liegt nicht richtig.....die LED,s schalten nicht nacheinander u. zeitversetzt ein. Mal funktioniert die Umschaltung, mal wird mehrmals immer die gleiche LED eingeschaltet, dann gehts wieder x male.

-->passiert beim Überfliegen, habe ausserdem die Auskommentierung weggelassen^^
Da passiert Folgendes: im betätigten Zustand geht es ja noch, eine LED wird stets angeschaltet, die andere abgeschaltet. Ist der Schalter offen, geht er in Deine erste If-Anweisung in den Else-Zweig, setzt den SchalterState auf true, dann geht er direkt danach in die zweite If-Anweisung (wieder den Else-Zweig), und setzt den SchalterState auf false. SchalterState wechselt innerhalb der loop() also ständig. Deshalb ist es sozusagen Zufall, welche LED angeht, sobald der Schalter betätigt wird.

Am einfachsten merkst Du Dir den Zustand des Schalters. Wenn der alte und neue Zustand unterschiedlich ist, dann soll was passieren (Zustand erhöhen...). Etwa so:

if (aktState != altState) {
  if (millis()-lastMillis > Delay) {
    altState = aktState;
    if (++state > MaxState) state = 0;
    switch (state) { ... }
  }  else
    lastMillis = millis();
}

@DrDiettrich: Müßte es nicht größer-gleich anstelle größer heißen? Habe ich mir das falsch gemerkt?

Beim Delay-Vergleich macht das keinen großen Unterschied. Beim state Vergleich wird mit ++state erst erhöht, dann verglichen. Pre-Inkrement bei ++state, im Gegensatz zu Post-Inkrement mit state++.

Hallo

Ihr seid gut, wirklich gut.....kompetente und zeitnahe Unterstützung, feines Forum....besten Dank.

Ich dachte es handle sich um eine einfache, triviale Sache, Schalter ein Led1 ein, Schalter nach aus erneut ein und Led2 sollte kommen...weit gefehlt. Wenn ich mir die Vorschläge so anschaue....mit Schul Arduino Kentnissen kommt man da nicht weit.

Das Beispiel von agmue Funktioniert problemlos. habe mir alles schön kopiert

Das kam hinzu:

boolean umschalt = false;
boolean aktState, altState;

Das steht in der setup, kenne ich so auch nicht ein digitalRead(x), zumal es auch noch in der loop steht

aktState = digitalRead(Schalter);
altState = aktState;

Hier in der loop wird es Interessant, Schalter wurd gelesen, kleine Pause, nun "alterStatus und nicht aktuellerStatus"
tu was....schalte Led1 nicht false also true u. schalte Led2 false...interpretiere ich mit High und Low (1 und 0)
Hmm...was nun....false= True??. umschalt ist ja weiter oben als fasle definiert

aktState = digitalRead(Schalter);
delay(20); //entprellen für Arme
if (altState && !aktState)
{
digitalWrite(LED_ONE, !umschalt);
digitalWrite(LED_TWO, umschalt);
umschalt = !umschalt;
}

Gruß Thomas

wbmnano:
boolean umschalt = false; // welche LED an, welche aus
boolean aktState, altState; // "Am einfachsten merkst Du Dir den Zustand des Schalters. "

wbmnano:
aktState = digitalRead(Schalter);
altState = aktState;

Verhindert, daß gleich beim Programmstart was passiert.

wbmnano:
umschalt ist ja weiter oben als fasle definiert

Das ist eine Variable, der ein Anfangswert zugewiesen wurde. Bleibt aber variabel.

Netterweise wird true=HIGH und false=LOW interpretiert, so daß man diese Zustände mischen darf.

wbmnano:
Ich dachte es handle sich um eine einfache, triviale Sache, Schalter ein Led1 ein, Schalter nach aus erneut ein und Led2 sollte kommen...weit gefehlt. Wenn ich mir die Vorschläge so anschaue....mit Schul Arduino Kentnissen kommt man da nicht weit.

Im Prinzip ist das ja auch genau so einfach wie Du es beschreibst:

Funktion die ich realiseren möchte ist eigentlch recht einfach und schnell erklärt....es mag aber einfach nicht so wie ich es gerne hätte.

Schalter...ist dieser betätigt soll Led1 angehen. Schalter aus---Led1 aus.
Schalter erneut betätigt soll nun Led2 angehen. Schalter aus---Led2 aus.
Schalter erneut betätigt...wieder Led1 an us usw

Deine Beschreibung entspricht im Endeffekt einem "endlichen Zustandsautomaten" (Finite State Machine) mit vier verschiedenen Zuständen:

Taster 0x gedrückt ==> alles aus
Taster 1x gedrückt ==> erste LED an
Taster 2x gedrückt ==> alles aus
Taster 3x gedrückt ==> zweite LED an

Und beim weiteren Drücken des Tasters wiederholt es sich, d.h. "Taster 4x gedrückt" entspricht dann wieder "Taster 0x gedrückt" dem Ausgangszustand.

Pseudo-Logik für die loop-Funktion

int state;
void loop()
{
  if (buttonPressed()) state++;
  if (state>=4) state=0;
  digitalWrite(LED_ONE, (state==1));   // erste LED ein bei state==1, sonst aus
  digitalWrite(LED_TWO, (state==3))); // zweite LED ein bei state==3, sonst aus

}

Da brauchst Du nur eine buttonPressed-Funktion, die immer true zurückliefert, wenn der Button gedrückt wurde.

Da brauchst Du nur eine buttonPressed-Funktion, die immer true zurückliefert, wenn der Button gedrückt wurde.

Das "nur" ist natürlich eine Falle :wink:
Die Funktion muss sich merken, ob sie schonmal true zurückgeliefert hat für diesen Tastendruck und beim nächsten Aufruf false zurückliefern, selbst wenn der Taster immer noch gedrückt ist oder noch prellt.

Wer überall Endliche Automaten sieht, sieht hier wieder einen 8)

wbmnano:
Schalter...ist dieser betätigt soll Led1 angehen. Schalter aus---Led1 aus.
Schalter erneut betätigt soll nun Led2 angehen. Schalter aus---Led2 aus.
Schalter erneut betätigt...wieder Led1 an us usw

jurs:
Taster 0x gedrückt ==> alles aus
Taster 1x gedrückt ==> erste LED an
Taster 2x gedrückt ==> alles aus
Taster 3x gedrückt ==> zweite LED an

Das ist logisch nicht gleich. Die LEDs sollen beim Loslassen ausgehen, nicht beim erneuten Drücken. Also so:

Taster 0x gedrückt ==> alles aus
Taster 1x gedrückt ==> erste LED an
Taster losgelassen ==> alles aus
Taster 2x gedrückt ==> zweite LED an
Taster losgelassen ==> alles aus

Als Sketch:

#define Schalter 2      // Schalter PIN definieren
#define LED_ONE 3       // Schütz 1
#define LED_TWO 13      // Schütz 2

enum {LED1AN, LED1AUS, LED2AN, LED2AUS};
byte zustand = LED2AUS;    // Hier speichern wir, welche LED angesteuert werden soll
boolean aktState, altState, weiter; // Hier speichern wir den momentanen Button Zustand


void setup()
{
  //Serial.begin(9600);
  pinMode(Schalter, INPUT);      // PINs als Aus-/Eingänge setzen
  digitalWrite(Schalter, HIGH);  //interner Pullup, Schalter schaltet gegen Masse auf LOW
  pinMode(LED_ONE, OUTPUT);
  pinMode(LED_TWO, OUTPUT);
  aktState = digitalRead(Schalter);
  altState = aktState;
}

void loop()
{
  aktState = digitalRead(Schalter);
  delay(20);                       //entprellen für Arme
  if (altState && !aktState) weiter = true;
  altState = aktState;
  switch (zustand) {
    case LED1AN:
      if (aktState) {
        zustand = LED1AUS;
        digitalWrite(LED_ONE, LOW);
        digitalWrite(LED_TWO, LOW);
      }
      break;
    case LED1AUS:
      if (weiter) {
        zustand = LED2AN;
        digitalWrite(LED_ONE, LOW);
        digitalWrite(LED_TWO, HIGH);
      }
      break;
    case LED2AN:
      if (aktState) {
        zustand = LED2AUS;
        digitalWrite(LED_ONE, LOW);
        digitalWrite(LED_TWO, LOW);
      }
      break;
    case LED2AUS:
      if (weiter) {
        zustand = LED1AN;
        digitalWrite(LED_ONE, HIGH);
        digitalWrite(LED_TWO, LOW);
      }
      break;
  }
  weiter = false;
}

Bei Sketchen, die auf eine Bildschirmseite passen, bin ich mit Funktionen etwas zurückhaltend, ist ein Schwierigkeitsgrad mehr.

Hallo Zusammen

Zum besseren Verständnis. Der Code soll zum steuern zweier Pumpen dienen. Geschaltet wird mit insgesammt 3 Tauchschaltern. Diese Tauschalter werden als Dauerkontaktgeber eingesetzt mit einstellbarer Hysterese.

Der untere Tauchschalter schaltet die Pumpen im Wechsel ein und aus. Mal die linke mal die rechte Pumpe, oder erste und zweite.

Ein weiter Tauschalter übernimmt eine Alarmfunktion...Wasserstand zu hoch falls eine der beiden Pumpen ausfallen sollte.

Ein dritter Tauschalter übernimmt die Spitzenlastfunktion...beide Pumpen sollen eingeschaltet werden,

Als Option eventuell angedacht:

Laufzeitüberwachung
4 Tauchschalter als Trockenlaufschutz
täglicher Probelauf

Gruß Thomas