Hallo,
Ich will eine RFID Box so programmieren das man sie 3 mal am Tag aufmachen kann. ich habe es bereits mit verschiedenen Codes ausprobiert aber nie hingekriegt.
Ich glaube das muss irgentwie mit der millis() methode machbar sein.
So sieht mein sketch aus (nur zum test, kann man drei mal eine led anschalten und dann erst wieder in 30 sek.)
//led ist an pin 13;
int led = 13;
// schalter an pin 2
int schalter = 2;
void setup() {
//schalter ist ein input
pinMode(schalter, INPUT_PULLUP);
//led ist ein ausgang
pinMode(led, OUTPUT);
}
void loop() {
unsigned int lastmillis;
int x = 0;
int Schalterz;
Schalterz = digitalRead(schalter);
//aktualisieren der gespeicherten zeit seit dem anfang
lastmillis = millis();
while(x <3){
//wen der schalter gedrückt ist
if(Schalterz == HIGH){
//led soll 1 mal an gehen unnd dann wider aus
digitalWrite(led, HIGH);
delay(1000);
digitalWrite(led, LOW);
delay(1000);
//x plus eins damit mann nach drei mal nicht mehr die led anschalten kann
x++;
}}
// wenmillisn die zeit nach dem letzten backup 1min erreicht hat dann fänngt die schleife von vorne an
if (millis() - lastmillis >= 30000){
//lastmillis wieder auf die aktuelle zeit setzen
lastmillis = millis;
}
}
Setze Deinen Code bitte in Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *).
Die unnötigen Leerzeilen kannst Du auch eintfernen und den Code ordentlich formatieren (+T in der IDE hilft Dir dabei). Dann ist er für alle besser lesbar.
Wird in loop() als ALLERERSTES ausgeführt, dabei wird die Variable lastmillis neu angelegt - ohne Initialisierung!
Die sitzt 'irgendwo im Speicher', was da zuvor Mal lag, ist unbekannt und kann ALLES gewesen sein.
Nun gut - Du durchläufst die loop(), die 30 Sekunden sind aber noch nicht um und loop() ist vorbei, die Variable lastmillis wird verworfen, da nicht mehr gebraucht - loop wird neu gestartet, die Variable 'lastmillis' wird IRGENDWO angelegt, nicht initialisiert ... Du merkst, was Da nicht passt?
Wenn Du ein 'static' vor die Definigion setzt, bleibt die Variable für loop() erhalten
static uint32_t lastmillis=millis();
(oder =0, je nach setup()-Laufzeit ist =millis() aber sinniger)
unsigned int lastmillis;
int x = 0;
int Schalterz;
Schalterz = digitalRead(schalter);
//aktualisieren der gespeicherten zeit seit dem anfang
lastmillis = millis();
while (x < 3) {
//wen der schalter gedrückt ist
if (Schalterz == HIGH) {
//led soll 1 mal an gehen unnd dann wider aus
digitalWrite(led, HIGH);
delay(1000);
digitalWrite(led, LOW);
delay(1000);
//x plus eins damit mann nach drei mal nicht mehr die led anschalten kann
x++;
}
}
// wenn millis die zeit nach dem letzten backup 30sek erreicht hat dann fänngt die schleife von vorne an
if (millis() - lastmillis >= 30000) {
//lastmillis wieder auf die aktuelle zeit setzen
static uint32_t lastmillis = millis();
}
}
static uint32_t lastmillis=millis(); //hier wird die Variable definiert
int x = 0;
int Schalterz;
Schalterz = digitalRead(schalter);
//aktualisieren der gespeicherten zeit seit dem anfang
lastmillis = millis();
while (x < 3) {
//wen der schalter gedrückt ist
if (Schalterz == HIGH) {
//led soll 1 mal an gehen unnd dann wider aus
digitalWrite(led, HIGH);
delay(1000);
digitalWrite(led, LOW);
delay(1000);
//x plus eins damit mann nach drei mal nicht mehr die led anschalten kann
x++;
}
}
// wenn millis die zeit nach dem letzten backup 30sek erreicht hat dann fänngt die schleife von vorne an
if (millis() - lastmillis >= 30000) {
//lastmillis wieder auf die aktuelle zeit setzen
lastmillis = millis(); //hier nicht, ist ja schon definiert, hier wird 'nur' der neue Wert übergeben
}
}
Gewöhne Dir an, die ganzen Leerzeilen raus zu nehmen.
Einzelne Leerzeilen können der Übersicht helfen, als Massenware stören Sie aber nur.
STRG+T in der IDE erhöht ebenfalls die Lesbarkeit, können Einem aber die eigene Formatierung versaubeuteln - selber komme ich mit SRTG-T aber ganz gut zurecht.
Diewhile (x < 3)Schleife führt dazu, dass dein Arduino ewig hängt, falls nicht direkt beim Start Schalterz auf HIGH gesetzt worden war. (Auch danach immer, wenn irgendwann mal loop() wiederholt werden sollte, muss der Taster gerade betätigt sein.)
Die Idee deines Tests habe ich evtl. nicht ganz verstanden: Bei einem Tasterdruck soll die LED einmal blinken. Wenn danach die Taste immer noch gedrückt ist oder sobald danach die Taste wieder gedrückt wird, noch (max 2) mal. Nach dem dritten Blinken soll für 30 Sekunden nichts passieren, egal was man mit der Taste anstellt (?)
Mein Tipp: wenn du schon millis() verwendest, dann ändere/vereinfache loop auch als "endlichen Automaten". loop() ist dafür gedacht, dass es so oft wie möglich drankommt und möglichst keine Zeit braucht. Dann vermeidet man auch solche Hänger.
Endlos-Schleifen innerhalb von loop() sind immer falsch, zumindest vom Design-Konzept her.
Hi danke für die vielen Antworten.
vielleicht sage ich nochmal was ich am Ende haben will,
Ich will, sozusagen als probe, das man eine Led 3 mal durch einen Taster anschalten kann und der Arduino zählt von Anfang an wie viel zeit vergangen ist und nach insgesamt nach 30 Sek. kann man die Led wieder durch drücken des Tasters anschalten.
Also nicht das nach dem letzten Knopfdruck delay(30000) ist.
//aktualisieren der gespeicherten zeit seit dem anfang
lastmillis = millis();
Das ist zwar auch nicht hilfreich, widerspricht aber deinem *static* Einwand.
Nein - aber, sobald loop() beendet wird, ist auch die aktualisierte Zeit futsch - im nächsten Durchlauf wird lastmillis neu angelegt (ohne Wert) und kurz vor Ende von loop() mit millis() gefüllt.
Denke, so war Das nicht geplant und mein static löst zumindest dieses Problem - lastmillis bleibt erhalten und sogar mit der letzten Zeit des Durchlauf.
Wenn nicht: Korrigiert mich - dafür sind wir hier im Forum und schadet ja Nichts, wenn die Info's hier korrekt sind.
...
void loop() {
unsigned int lastmillis; //<--- deklarieren von lastmillis, Wert wird keiner zugewiesen
int x = 0;
int Schalterz;
Schalterz = digitalRead(schalter);
//aktualisieren der gespeicherten zeit seit dem anfang
lastmillis = millis(); //<-- ok, Wertzuweisung erfolgt
while(x <3){
//wen der schalter gedrückt ist
if(Schalterz == HIGH){
//led soll 1 mal an gehen unnd dann wider aus
digitalWrite(led, HIGH);
delay(1000);
digitalWrite(led, LOW);
delay(1000);
//x plus eins damit mann nach drei mal nicht mehr die led anschalten kann
x++;
}} //<-- jetzt keine Klammern gezählt (die Formatierung ist hier dafür auch echt ... 'verbesserungswürdig'), würde aber raten, daß while hier zu Ende ist
// wenmillisn die zeit nach dem letzten backup 1min erreicht hat dann fänngt die schleife von vorne an
if (millis() - lastmillis >= 30000){ //<-- diese Abfrage wird wohl nie erfüllt - so lahm ist der Arduino halt nicht
//lastmillis wieder auf die aktuelle zeit setzen
lastmillis = millis; //<-- ok, dem millis fehlt ein (), ist aber hier eh egal, da lastmillis nach den zwei Klammern nicht mehr vorhanden ist
}
}
Meine Kommentare als //<--
Oder wo bin ich hier gedanklich falsch?
Die zwei von dir markierten Zeilen könnte man auch zusammenfassen
unsigned int lastmillis = millis( );
Das ist zwar Schrott, aber identisch zu vorher. Ein undefinierter Wert von lastmillis tritt nirgends auf.
Es zu trennen und die Variable static zu deklarieren hilft jedenfalls nix.