Anfängerfrage; LED umschaltung per Taster

Hi, ich habe heute meinen Arduino bekommen und hab mit den ersten LED schaltungen aus dem Buch "Arduino Physical Computing..." begonnen. Ich habe eine Schaltung gebaut, bei der ich, wenn ich einen Taster betätige von einer roten auf eine grüne LED umschalten kann. Sobald der Taster nicht mehr betätigt wird springt sofort wieder die Rote LED an. Jetzt hab ich mir gedacht, das man den Taster im Prinzip auch zum Schalten benutzen können müßte und habe versucht das Programm dafür zu schreiben, jedoch hänge ich mittlerweile 4 Stunden an dem Problem und finde einfach keine lösung für dieses meiner Meinung nach eigentlich recht einfache Problem. Ich hoffe ihr könnt mir einen Tipp geben wo ich einen Denkfehler hab.

int ledPin1 = 13;
int ledPin2 = 12;
int Schalter = 2;

void setup () 
{
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(Schalter, INPUT);
  digitalWrite(Schalter, HIGH);
}


void loop()
{
  
  int Status = HIGH;
  Start:
  int val = digitalRead(Schalter);  
  if (val == LOW) {                 
    if (Status == HIGH) {
      int Status = LOW;
    }
    else {
      int Status = HIGH;
    }
    delay (200);
   }
   else {
     int Status = Status;
   }
  

 if (Status == HIGH){
   digitalWrite(ledPin1, HIGH);
   digitalWrite(ledPin2, LOW);
 }
 else {
   digitalWrite(ledPin1, LOW);
   digitalWrite(ledPin2, HIGH);
 }
 goto Start;

  
}

Ich hab es auch schon mit einer For schleife versucht, jedoch bin ich damit auch nicht zum gewünschten ergebnis gekommen.

Ich bin über jede Hilfe dankbar.

mfg Gul Dukat

Goto ist NOGO :wink:

Hänge um die Funktion eine Bedigung die immer erfüllt ist, also zB (1<2) und du hast die gewünschte Endlosschleife.

So beim drüberfliegen entdeckt

Uah, Ihr seid beide so grausam!! :)

Definiere Status außerhalb der loop() und lass den goto weg. loop() ist schon von Haus aus eine Endlosschleife, daher auch der Name! ;)

Danke für eure Antworten, das hab ich jedoch alles schon versucht. Der Wert den Status hat ändert sich nicht. Definiere ich den Staus am Anfang auf HIGH bleibt die rote LED an egals wie lange oder oft ich auf den Taster drücke und bei LOW halt die güne.

Deine Integer-Deklarierung ("int Status" etc.) hat in der loop() nichts zu suchen. Variablen solltest du [u]einmal[/u] deklarieren... Noch dazu sollte Status doch vom Typ Boolean sein?!

Ok, dann probier das mal, so oder so ähnlich sollte es eigentlich tun:

#define LED1 13
#define LED2 12
#define SCHALTER 2

void setup ()
{
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(SCHALTER, INPUT);
  digitalWrite(SCHALTER, HIGH);

  digitalWrite(LED1, HIGH);
}

boolean status, firstLed;

void loop()
{
  int val = digitalRead(SCHALTER);
  if (status != val) { // Aenderung am Schalter?
    if (val) { // gedrueckt
      digitalWrite(LED1, firstLed); // Die eine leuchtet
      digitalWrite(LED2, !firstLed); // und die andere nicht...
      firstLed = !firstLed; // ...welche das ist wird abgewechselt.
    }
    status = val; // Merken
    delay (50); // Debounce
  }
}

Wie immer unterm Tag kann ichs hier nicht testen (nichtmal compilieren, um genau zu sein) und daher ohne Gewähr. ;)

Danke für dein Beispielcode Joghurt, der tut das was ich wollte. Ich verstehe ihn zwar noch nicht ganz, aber da komm ich schon hoch hinter :)

Vielleicht hilft Dir das weiter:

[u]define:[/u] Wichtig zu Wissen ist dass der Precompiler jeweils alle Stellen im Code, and denen der erste Teil, der hinter define steht, steht, durch den zweiten Teil ersetzt. Quasi also alle Stellen, an denen im Editor PIN1, PIN2 oder SCHALTER steht steht intern beim compilieren die Zahl und wird keine Variable verwendet, was Platz spart und trotzdem bleibt das Ganze sehr leicht änderbar.

[u]boolean etc.:[/u] Und dann ist es wichtig zu wissen, dass boolean*s ohne eine Zuweisung von Haus aus *LOW sind. Soweit ich mal wo gelesen habe ist der Knackpunkt aber, dass, wenn man eine explizite Zuweisung angibt, und sei sie LOW (oder 0 bei *int*s), diese auf jeden Fall im Code hinterlegt wird, was nicht passiert, wenn man das wegläßt (wobei die Variable aber trotzdem initialisiert wird). Auch das spart Platz. (An dieser Stelle möge man mich berichtigen, falls das Arduino-Framework eine Initialisierung mit dem Basiswert sowieso rauskürzt oder was anderes an meiner Behauptung nicht stimmt! Würde mich im Zuge von Optimierungsmaßnahmen wirklich interessieren!)

[u]Überprüfung von boolean*s in einer *if:[/u] Wird ein Vergleich weggelassen, so entspricht das einer " == HIGH"-Überprüfung.

Vielen dank für deine erklärungen, das hilft mir weiter.

Frage zum Boolean: Was heisst: "spart Platz"? Platz wofür/wovon?

Wenn man Variablen nicht mehr initialisiert um "Platz zu sparen" ists wohl Zeit die HardWare zu wechseln.

Kommt vermutlich drauf an um wieviel Platz es geht. :)

Bei meinem aktuellen Projekt bin ich sowohl was das RAM angeht als auch von der Sketchgröße am Anschlag meines Arduino Pro Mini, und mit etwas sparen (byte statt int, Strings ins PROGMEM und so) kann ich die restlichen Features, die ich mir so vorstelle, trotzdem noch unterbringen. Zwar mit etwas mehr Aufwand, aber es geht. ;)

Ich hab das mit der Initialisierung nur mal angeschnitten, damit er das im Hinterkopf behält für den Fall, dass er das Problem auch mal bekommt...

Platz sparen ist doch ein Zeichen einer effektiven Programmierung. ;) Die Initialisierung findet ja trotz alledem statt, wenn man das als reine Typendeklaration sieht. Nur auf die Zuweisung eines Anfangswertes wird verzichtet, weil das (scheinbar) immer konstant LOW bzw. 0 ist. Das könnte man ja durchaus mal testen, indem man ein Trivialprogramm schreibt, dass eine Variable deklariert und ihren Wert unmittelbar über die serielle Schnittstelle ausgibt. Über ein Terminalprogramm schaut man dann, ob Zufallswerte erscheinen oder eben (wie vermutet) die Null als Ergebnis erscheint.