Ich habe mich etwas mit dem Arduino beschäftigt und auch gleich eine Frage mitgebracht.
Ich möchte durch einen Button realisieren, dass die delayzeit geändert wird. Das funktioniert auch super. Leider wird dies allerdings erst aktiv wenn der aktuelle Vorgang durchgelaufen ist. D.h. wenn die LED0 brennt und ich den Button drücke, brennt die LED0 trotzdem weiter weil die 10 Sekunden noch nicht vorbei sind. Erst bei der nächsten LED wird der neue Wert beachtet. Was auch logisch ist bei der iterativen Ausführung. Allerdings dauert mir das zulange. Bei einem delay von bsp. 100000000 will ich nicht warten Ich möchte das die Änderung sofort eintritt und ich nicht erst warten muss bis die aktuelle Zeit durchgelaufen ist. Da dachte ich es wäre praktisch wenn die loop Funktion einfach neu startet bzw. so etwas wie GOTO verwendet wird.
Finger weg vom goto. Des weiteren solltest du lernen, für solche Zeiten kein delay zu nutzten. Für kurzes Tasterentprellen (20 - 50ms) manchmal ganz okay. Aber für solche Sachen wie in deinem Beispiel nicht. -> blinkWithoutDelay
Variablen die innerhalb und außerhalb von ISRs verwendet werden müssen als "volatile" deklariert werden! Sonst kann der Compiler nicht wissen wie diese aufgerufen werden und optimiert sie eventuell weg. Außerdem werden sie dadurch immer neu aus dem RAM ausgelesen und nicht u.U. aus Registern, wodurch sichergestellt wird dass der Zustand konsistent ist.
Ansonsten sind Interrupts hier keine gute Wahl. Der Controller ist schnell genug, dass man das durch ständiges abfragen erledigen kann. In deinem Fall willst du wahrscheinlich Interrupts verwenden um während des Delays noch den Zustand ändern zu können. Aber da verwendet man besser millis(). Dann blockiert das Programm nicht und man kann mehrere Dinge quasi-gleichzeitig tun.
sschultewolter:
Finger weg vom goto. Des weiteren solltest du lernen, für solche Zeiten kein delay zu nutzten. Für kurzes Tasterentprellen (20 - 50ms) manchmal ganz okay. Aber für solche Sachen wie in deinem Beispiel nicht. -> blinkWithoutDelay
Dann brauchst du auch keine Interrupts mehr.
Wenn man kein delay für blinken benutzen soll, warum wird das immer in den ganzen Tutorials gezeigt? ^^
Weil blinken das erste Programm ist, was man mit dem Arduino meist realisiert. Und was passiert, wenn man delays nutzt, hast du doch gemerkt. delay lässt den Controller an der Stelle im Code einfach nur doof warten.
Tutorials dienen nicht zwingend dazu, den Nutzer die gute Programmiertechnik beizubringen. Nur Tutorials ist auch nicht die Lösung. Sinnvoller wären neben irgendwelchen Online Tutorials mindestens ein C oder Arduino-C Buch. (z.B. Kochbuch aus dem OReiley Verlag)
Habe soeben das Beispiel mal ausporbiert, aber es macht doch keinen Unterschied wie ich das löse. Außer vllt. das es sinnvoller ist diese Methode zu nutzen. Warten muss ich trotzdem bis die LED einmal durch ist und der neue Wert bei der nächsten Ausführung greift. Wenn der interval auf 1000000 kann ich zwar die variablen ändern, leider geht die LED deshalb trotzdem nicht schneller aus.
Also in dem ersten Bereich wird doch die Wartezeit berechnet oder nicht?
Angenommen die LED steht für 10 Minuten auf HIGH (variable entsprechend groß), wie unterbreche ich das denn deiner Meinung nach damit sie sofort ausgeht bzw. den neuen variablen Wert sofort annimmt?
if(currentMillis - previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis; //Wartebereich
//LED an / aus nach dem Wartebereich
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
digitalWrite(ledPin, ledState);
}
Ich habs jetzt hinbekommen, allerdings etwas anders.
int peak = 0;
int blink[] = {200, 500, 10000};
void loop()
{
unsigned long currentMillis = millis();
buttonState = digitalRead(buttonPin);
if(buttonState == LOW)
{
interval = blink[peak];
peak++;
delay(300);
if(peak > 2)
{
peak = 0;
}
}
if(currentMillis - previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
digitalWrite(ledPin, ledState);
}
}
Allerdings habe ich da wieder ein delay drin, aber dies nutze ich nur für die Buttonabfrage falls man zulange drückt und da das Array zu weit durchlaufen wird. Hoffe das ist ok?
if (buttonState == HIGH) {
// if the current state is HIGH then the button
// wend from off to on:
buttonPushCounter++;
Serial.println("on");
Serial.print("number of button pushes: ");
Serial.println(buttonPushCounter);
}