RFID Box

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;
    
    }
}

Danke für antworten
Joel

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.

Tschuldigung war mein erster Post.

Lies Dir das mit den Codetags und der Formatierung nochmal durch.

Gruß Tommy

Dann mache es nochmal richtig, nicht zur Strafe, nur zur Übung :-]

Die überzähligen (leeren) Codebereiche löschen. Den Code im Editor markieren, dann </> anklicken.

Hi

unsigned int lastmillis;

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)

MfG

Danke, also dann so?

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();

  }


}

Ich kriege da immer eine fehlermeldung

HI

Fast :wink:

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.

MfG

BlackRaven05:
Ich kriege da immer eine fehlermeldung

Welche Fehlermeldung ?

jetzt nicht mehr
aber die led blink trotzdem nur. :confused:

BlackRaven05:
jetzt nicht mehr
aber die led blink trotzdem nur. :confused:

Ohhhh toll.
Und wozu brauchst du die "while-Schleife" ?

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.

@postmaster-ino:
hast du das übersehen

  //aktualisieren der gespeicherten zeit seit dem anfang
  lastmillis = millis();

Das ist zwar auch nicht hilfreich, widerspricht aber deinem static Einwand.

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.

LG Joel

Also nicht das nach dem letzten Knopfdruck delay(30000) ist.

Natürlich nicht.
Das geht besser ganz ohne delay(). Dafür mit Zustandsvariablen:

  • Wann war der erste Tastendruck?
  • Wie oft blinkt es schon?
  • Seit wann läuft der aktuelle Blinkvorgang?
    Diese Variablen merkst du dir über viele loop Durchläufe, entweder als static oder als globale Variable.

Hi

michael_x:
@postmaster-ino:
hast du das übersehen

  //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.

MfG

kurz vor Ende von loop() mit millis() gefüllt

nö. ...bei der ersten Verwendung...
damit ist nicht nur static , sondern die ganze Verwendung (als Zustandsvariable) sinnlos.

Hi

Nur loop():

...
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?

Dann sind wir uns ja eigentlich einig.

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.