Brauche Hilfe beim Countdowntimer ohne delay.

Hallo Leute, ich versuche einen countdowntimer sketch zu schreiben. Die schaltung besteht aus einer 7 Segment LED Anzeige und einer Blauen LED. Der Countdown soll bei 3 min losgehen, während der 3 min soll die LED blinken (am besten sollte sie immer schneller blinken desto näher sie an die 0 kommt). Wenn der Timer bei 0 min angekommen ist soll die Blaue LED konstant leuchten.
Bis jetzt habe ich schonmal mit diesem countdown sketch gearbeitet, leider komme ich nicht weiter.

// 

const int LedA = 5;
const int LedB = 2;
const int LedC = 3;
const int LedD = 4;
const int LedBl = 1;

int count = 9;

void setup()
{
  // Configure the pins connected to the 4511 as outputs
  pinMode(LedA, OUTPUT);
  pinMode(LedB, OUTPUT);
  pinMode(LedC, OUTPUT);
  pinMode(LedD, OUTPUT);
  pinMode(LedBl, OUTPUT);
}

void loop()
{
  Display(count);  // Displays the current count value

  // Count from 0 to 9 every half second
  count = count - 1;

  if (count < 0)
  {
     count = 9;
  }

  delay(1000);
}

// This function outputs the supplied value to the display.
void Display(int n)
{
  // Start with a range check - remember we can only display
  // from 0 to 9! :) 

  if ( n > 9 )
  {
    n = 9;
  }

  if ( n < 0 )
  {
    n = 0;
  }

  // The rest from here is basic decimal to binary conversion

  if ( n / 8 == 1 )
  {
    digitalWrite(LedD, HIGH);
  }
  else
  {
    digitalWrite(LedD, LOW);
  }

  n = n % 8;

  if ( n / 4 == 1 )
  {
    digitalWrite(LedC, HIGH);
  }
  else
  {
    digitalWrite(LedC, LOW);
  }

  n = n % 4;

  if ( n / 2 == 1 )
  {
    digitalWrite(LedB, HIGH);
  }
  else
  {
    digitalWrite(LedB, LOW);
  }
  n = n % 2;

  if ( n == 1 )
  {
    digitalWrite(LedA, HIGH);
  }
  else
  {
    digitalWrite(LedA, LOW);
  }
}

Hallo,
hab mir gerade mal ein paar Gedanken gemacht, aber ohne Gewähr, nicht getestet:
so könntest du die blaue LED ansprechen:
hab den Code entfernt, unter der läuft

zur Erläuterung mit startzeit wird die Zeit gesetzt wenn du startest
über aktuell berechne ich eine Variable, die alle 30 Sek eins höher wird.
Bei 180 Sek von 0 bis 6
in der Schleife berechnet man einen Wert (6-aktuell)*100),
heißt am Anfang 600millisec, bis zum Schluß 100millisec, so lange brennt die LED

Das ist jetzt auf die Schnelle, ob ich richtig gedacht weiß ich nicht, werde ich heute abend mal testen.
gruß

so habs noch mal überarbeitet und getestet, jetzt funktioniert es

long startzeit, start;
int aktuell;
boolean flag, onoff;
#define LedA 8
void setup(){
 Serial.begin(9600);
  pinMode(LedA, OUTPUT);
  startzeit=millis(); // setzt die Startzeit
}
void loop(){
 aktuell = ((millis()-startzeit)/30000); // alle 30 Sekunden wird aktuell von Null aus um 1 erhöht, also wird alle 30 Sek Blinkfrequenz höher
 if(aktuell < 6)  {
   if (flag){
    flag=false;start=millis();
   }
   if (millis()-start < (6-aktuell)*100){
    if (onoff)
      digitalWrite(LedA,HIGH);
     else  
      digitalWrite(LedA,LOW);
   }
   else{
    onoff = !onoff; flag=true;
  }
 }
 else
 digitalWrite(LedA,HIGH);
}
}

Hallo maverick1509,

danke für die schnelle Hilfe, ich werds morgen mals ausprobieren.

Gruß Mischa

Hallo maverick1509, mal ne frage. Da ich ein Anfänger bin kann ich bis jetzt noch nicht beide sketche zusammen fügen sodaß wiegesagt die 7 Segment Anzeige von 3 min runter Zählt und während dessen die Led ja schneller wird. Ich habe dein Sketch ausprobiert, hat toll funktioniert, es war nur ein } zuviel am Ende vom sketch.

Gruß Mischa

Hallo Mischa,
ich kenne die 7-Segment Anzeige nicht. Wenn ichs richtig verstehe zeigt dein erster Sketch Zahlen zwischen
1 und 9 auf der Anzeige????? Richtig??
Wenn ja was soll er jetzt bei den 3 Min machen? Was genau soll angezeigt werden, das versteh ich noch nicht.
Gruß
Bernward

Hallo Bernward, mein Fehler die 9 sollte eine 3 sein. Meine Idee war es die 7 Segment Anzeige die über 4 Digi Outs vom Arduino Uno über ein CD4511 anzusteuern. Während die Segment-Anzeige von 3 minuten runter zählt (3,2,1,0) sollte die LED gleichzeitig blinken und immer schneller werden.

Gruß Mischa

Hallo Mischa,
ich geh mal davon aus, das die Prozedur aus deinem ersten Beitrag zur Ausgabe auf dem Display richtig ist,
dann sollte es so gehen:
Falls nicht, oder bei Unklarheiten zum Code einfach fragen, dafür gibt es das Forum :-))
Gruß
Bernward

#define LedA 5
#define LedB 2
#define LedC 3
#define LedD 4
#define LedBl 1
long startzeit, start;
long aktuell, minute, letzteminute, wiederholung;
long intervall = 240;
boolean flag, onoff;
//--------------------------------------------------------------
void setup(){
 pinMode(LedA, OUTPUT);
 pinMode(LedB, OUTPUT);
 pinMode(LedC, OUTPUT);
 pinMode(LedD, OUTPUT);
 pinMode(LedBl, OUTPUT);
 startzeit = millis(); // setzt die Startzeit
}
//--------------------------------------------------------------
void Display(int n){
 if ( n > 9 ) n = 9;
 if ( n < 0 ) n = 0;
 // The rest from here is basic decimal to binary conversion
  if ( n / 8 == 1 )
   digitalWrite(LedD, HIGH);
  else
   digitalWrite(LedD, LOW);
 n = n % 8;
  if ( n / 4 == 1 )
   digitalWrite(LedC, HIGH);
   else
   digitalWrite(LedC, LOW);
 n = n % 4;
  if ( n / 2 == 1 )
   digitalWrite(LedB, HIGH);
  else
   digitalWrite(LedB, LOW);
 n = n % 2;
  if ( n == 1 )
   digitalWrite(LedA, HIGH);
  else
   digitalWrite(LedA, LOW);
}
//--------------------------------------------------------------
void loop(){
 if (wiederholung < intervall){
  wiederholung =(millis()/1000) - (startzeit/1000); 
  aktuell = ((millis()-startzeit)/30000); // alle 30 Sekunden wird aktuell von Null aus um 1 erhöht, also wird alle 30 Sek Blinkfrequenz höher
  minute = 3-(((millis()-startzeit)/60000)); // ergibt den Minutenanteil, der ab Start vergangen ist
  if(minute != letzteminute){
    if (minute >= 0) Display(minute);
   letzteminute = minute;  
  } 
  if(aktuell < 6)  {
   if (flag){
    flag = false; start = millis();
   }
   if (millis() - start < (6 - aktuell) * 100){
    if (onoff)
      digitalWrite(LedBl,HIGH);
     else  
      digitalWrite(LedBl,LOW);
    }
    else{
     onoff = !onoff; flag=true;
   }
  }
  else{
   digitalWrite(LedBl,HIGH);
  }
 }
 else{
  wiederholung = 0; startzeit = millis();
 }
}

Gude Bernward, der code Funktioniert, es ist für mich ein bischen kompliziert alles nach zu vollziehen, ich habe mal ein bisschen mit dem Sketch gespielt um ihn zu verstehen. Nur habe ich fest gestellt das das die 7 Segment-Anzeige auf 1 stehen bleibt nach 3 minuten (die LED bleibt wie gewollt nach 3 min stehen). Ich hab mal nachgemessen die Anzeige geht erst ab 4 min auf 0. Ich habe mal mit Serialprint die "letzteminute" angeschaut, diese geht nach 3 min auf 0. Ich verstehs nicht...

Was müste ich machen das nach einer geraumen Zeit (ca 1 min) der 3 min rythmus wieder von vorn los geht?

Gruß Mischa

Hallo Mischa,
das kriegen wir auch noch hin :slight_smile:
Heute Abend hab ich aber keine Zeit mehr, ich nehm mir das ganze morgen früh noch mal vor.

Und wie gesagt, wenn was unklar ist fragen, nur so lernt man es, ging mir am Anfang nicht anders.

Gruß
Bernward

Cool, danke nochmals!

mfg Mischa

Hallo Mischa,
so ich habs noch mal überarbeitet. Damit es hier nicht zu lang wird hab ich den Sketch jetzt unter Post #8
einfach ausgetauscht Ich habe eine Variable "intervall" eingefügt, da kannst du nach Belieben jetzt die Gesamtzeit
eintragen, nach der sich der Rhythmus wiederholt, ich hab mal 240 Sek vorbesetzt.
Gruß
Bernward

Hallo Bernward,

der Sketch funktioniert wunderbar, habs noch ein bisschen verändert mit 2 schalter Funktionen und einem Buzzer. Danke dir nochmals für die Unterstützung.

Gruß Mischa

Freut mich, das ich helfen konnte.
gruß
Bernward

Hallo Bernward,

ich habe nochmals mit dem Sketch rum gespielt um noch eine 2. LED blinken zu lassen nach den 180 sekunden. Ich habe den Befehl :

 [b]if(aktuell > 6)[/b]  {
   if (flag){
    flag = false; start = millis();
   }
   if (millis() - start < (6 - aktuell) * 100){
    if (onoff)
      digitalWrite(LedYe,HIGH);
     else  
      digitalWrite(LedYe,LOW);
    }
    else{
     onoff = !onoff; flag=true;
   }
  }
  else{
   digitalWrite(LedYe,HIGH);
  }
 }
 else{
  wiederholung = 0; startzeit = millis();
 }
}

Ich dachte das nach den Intervall 6 die 2. Led anfängt zu Blinken aber irgendwie fängt sie erst bei Aktuell 7 oder 8 an. Ich bin auch noch nicht dahinter gekommen wie der Code :
(millis() - start < (6 - aktuell) * 100) funktioniert!

Gruß Mischa

Hallo Mischa,
wenn die LED erst bei 7 anfängt, dann liegt es vermutlich an der Abfrage.
Zuerst wird ja gefragt < 6, du solltest dann in deiner Abfrage schreiben
if(aktuell >= 6) oder aber if(aktuell >5) das dürfte schon reichen.

Die Zeile if (millis() - start < (6 - aktuell) * 100) liefert eigentlich nur die Blinkfrequenz der LED
Wenn das Programm startet ist aktuell 0 , also brennt die LED 6100ms und dann 6100ms nicht.
Dann wird aktuell immer eins größer, dem entsprechend wird die Blinkzeit 500ms, 400ms, 300ms, 200ms, 100ms.
Gruß
Bernward

Hallo Bernward,

das mit den runterzählen der blink freq habe ich verstanden aber für was ist die diff rechnung von millis -start? "(millis() - start < (6 - aktuell) * 100)"

Gruß Mischa

Hallo,
also am Anfang wird die variable start auf den aktuellen Wert von millis() gesetzt.
Bei jedem Durchlauf der Schleife (dauert ein paar Millisekunden) wird dann kontrolliert, ob die vergangene Zeit
(millis()-start) noch kleiner als die Blinkzeit ist. Falls ja bleibt alles wie es ist, falls nicht wird zwischen LED an und aus gewechselt.
Schwer zu beschreiben aber die Abfrage ist zuständig für das blinken (Wechsel zwischen LED an und LED aus).