Problem beim Countdown setzen

Bin schon fast den ganzen Tag dabei und kriege es nicht hin >:(

Ich hab da ein Countdown gebastelt und versuche mit der Menü Lib von Jomelo die Zeit einzustellen.
Mit UP/DOWN setze ich die Zeit, mit ENTER gehts zum nächsten Punkt.
Stunden kann ich UP und DOWN setzen.
Bei Minuten klappt aber nur UP. Drücke ich DOWN, verstellen sich die Minuten und Stunden mit "zufälliger" Zahl.

Kann mal jemand drüber schauen und ein paar hilfreiche Sätze dazu schreiben?!

Der CountDown:

unsigned long previousMillis = 0, Clock, R_clock;
boolean Reset = false, Stop = false;
boolean CountDownTimer()
{
  unsigned long currentMillis = millis();
  if (!Stop) {
  if (currentMillis - previousMillis >= 1000) {
    previousMillis = currentMillis;
      Clock--;
  if (Clock == 0) 
  {
    Stop = true;
    LCDML_BACK_stop(LCDML_BACKEND_heizen);
  lcd.setCursor(0, 0);
  lcd.print(F("PROGRAMM BEENDET"));
  lcd.setCursor(0, 1);
  lcd.print(F("HEIZUNG IST AUS"));
  lcd.setCursor(0, 3);
  lcd.print(F("MAX.TEMP. "));
    lcd.print((Temp_top),1);
       // LCDML.goRoot();
       }
    }
  }
  return !Stop; // return the state of the timer
}

void SetTimer( unsigned long hours,  unsigned long minutes,  unsigned long seconds)
{
   unsigned long _Sec = (seconds / 60), _Min = (minutes / 60);
  if(_Sec) minutes += _Sec;
  if(_Min) hours += _Min;

  Clock = (hours * 3600) + (minutes * 60) + (seconds % 60);
  R_clock = Clock;
  Stop = false;
}

void SetTimer( uint8_t seconds)
{
 Clock = seconds;
 R_clock = Clock;
 Stop = false;
}

void ResetTimer()         { SetTimer(R_clock);  Stop = false;}

void StopTimer()          { Stop = true;}

uint8_t ShowHours()       { return Clock / 3600;}

uint8_t ShowMinutes()     { return (Clock / 60) % 60;}

uint8_t ShowSeconds()     { return Clock % 60;}

Die Menü Steuerung:

// define global variable  
uint8_t g_setDate_cursorPos = 0;
// define help function to set the current time
void HELP_FUNC_set_dat(uint8_t l_i)
{
  switch(g_setDate_cursorPos) {
    case 0: SetTimer(ShowHours()+l_i, ShowMinutes(), ShowSeconds()); break; // hour
    case 1: SetTimer(ShowHours(), ShowMinutes()+l_i, ShowSeconds()); break; // hour 
  }
} 
// define help function to display the current clock settings
void digitalClockDisplay()
{
  // init display
  lcd.clear();  
  lcd.setCursor(3,0); 
  // display hour value
  printDigits(ShowHours());  lcd.print(F(":"));
  
  // display minute value, move output when this value is edit
  if(g_setDate_cursorPos == 1) { lcd.print(F(" ")); }
  printDigits(ShowMinutes());  lcd.print(F(":"));
  
  // display second value
  printDigits(ShowSeconds()); 
      
  // set cursor blink on the correct possion
  switch(g_setDate_cursorPos) {
    case 0: lcd.setCursor(2,0); lcd.print(F("S")); lcd.setCursor(2,0); lcd.blink(); break; //hour
    case 1: lcd.setCursor(6,0); lcd.print(F("M")); lcd.setCursor(6,0); lcd.blink(); break; //min
    default: lcd.noBlink(); break;
   }
}
// define help function to display digits in front of the value
void printDigits(uint8_t digits)
{
  // utility function for digital clock display: prints preceding colon and leading 0  
  if(digits < 10)   lcd.print(F("0"));  lcd.print(digits);
}

// *********************************************************************
void LCDML_DISP_setup(LCDML_FUNC_set_date) {digitalClockDisplay(); }
// *********************************************************************
void LCDML_DISP_loop(LCDML_FUNC_set_date)
{             
  if(LCDML_BUTTON_checkAny()) { // check if any button is presed (enter, up, down, left, right)
    if (LCDML_BUTTON_checkUp())    { HELP_FUNC_set_dat(+1); LCDML_BUTTON_resetUp(); }
    if (LCDML_BUTTON_checkDown())  { HELP_FUNC_set_dat(-1);  LCDML_BUTTON_resetDown(); }
    if (LCDML_BUTTON_checkEnter()) { g_setDate_cursorPos=(g_setDate_cursorPos+1)%2; LCDML_BUTTON_resetEnter(); }
    digitalClockDisplay();
  }   
}

void LCDML_DISP_loop_end(LCDML_FUNC_set_date) {    lcd.noBlink();  }

skorpi08:
... Kann mal jemand drüber schauen und ein paar hilfreiche Sätze dazu schreiben?! ...

Würde ich tun, wenn Du es so formatierst, dass es max. 80 Zeichen breit ist. Dann kann ich es ausdrucken und den vollständigen Code angucken, ohne scrollen zu müssen.

Gruß

Gregor

gregorss:
Würde ich tun, wenn Du es so formatierst, dass es max. 80 Zeichen breit ist. Dann kann ich es ausdrucken und den vollständigen Code angucken, ohne scrollen zu müssen.

Querformat Courier New 10 Punkt und der Text paßt auf das Papier!

Viel Spaß beim Lesen :slight_smile:

agmue:
Querformat Courier New 10 Punkt und der Text paßt auf das Papier!

Dass das passen würde, glaube ich. Ich bevorzuge halt a2ps im Hochformat.

Gruß

Gregor

Die Verwendung von HELP_FUNC_set_dat ist falsch. Zumindest passen die Parameter beim Aufruf (mit Vorzeichen) nicht zum Parametertyp (ohne Vorzeichen).

Auch die Behandlung von Überläufen in SetTimer ist nicht ganz in Ordnung.

Wie sollte es denn beim SetTimer aussehen?

Spiele einfach mal durch was passiert, wenn seconds und minutes 59 oder 60 ist.

Und sollte nicht auch ein Unterlauf berücksichtigt werden, wenn zuvor heruntergezählt wurde? Du schreibst ja, daß es da klemmt.

Das einzige was jetzt nicht passt, wenn der Counter bei 00:00:00 steht und ich DOWN drücke, springt der Counter auf 85:28:16

Das hochzählen passt, Minuten und Stunden werden richtig gesetzt.

unsigned long Clock, R_clock;
boolean Stop = false;
boolean Heizen = false;
boolean Programmlauf = false;
boolean CountDownTimer()
{
    if (Clock == 0)  {
    Stop = true;
     Programmlauf = false;
    LCDML_BACK_stop(LCDML_BACKEND_heizen);
    lcd.setCursor(0, 0);
    lcd.print(F("PROGRAMM BEENDET"));
    lcd.setCursor(0, 1);
    lcd.print(F("HEIZUNG IST AUS"));
    lcd.setCursor(0, 3);
    lcd.print(F("MAX.TEMP. "));
    lcd.print((Temp_top),1);
     }
  unsigned long previousMillis;  
  unsigned long currentMillis = millis();
  if (!Stop) {
  if (currentMillis - previousMillis >= _sekunde_) {
    previousMillis = currentMillis;
      Clock--;
     }
  }
  return !Stop; // return the state of the timer
}

void SetTimer( long hours,  long minutes,  long seconds)
{
  // This handles invalid time overflow ie 1(H), 0(M), 120(S) -> 1, 2, 0
   uint8_t _Sec = (seconds / 60), _Min = (minutes / 60);
  if(_Sec) minutes =+ _Sec;
  if(_Min) minutes -+ _Min;

  Clock = (hours * 3600) + (minutes * 60) + (seconds % 60);
  R_clock = Clock;
  Stop = false;
}

void SetTimer( uint8_t seconds)
{
 // StartTimer(seconds / 3600, (seconds / 3600) / 60, seconds % 60);
 Clock = seconds;
 R_clock = Clock;
 Stop = false;
}

void ResetTimer()         { SetTimer(R_clock);  Stop = false;}

void StopTimer()          { Stop = true;}

uint8_t ShowHours()       { return Clock / 3600;}

uint8_t ShowMinutes()     { return (Clock / 60) % 60;}

uint8_t ShowSeconds()     { return Clock % 60;}
// *********************************************************************
// Set CountDown
// *********************************************************************
 
// define global variable  
uint8_t g_setDate_cursorPos = 0;
// define help function to set the current time
void HELP_FUNC_set_dat(int8_t l_i )
{
  switch(g_setDate_cursorPos) {
    case 0: SetTimer(ShowHours()+l_i, ShowMinutes(), ShowSeconds()); break; // hour
    case 1: SetTimer(ShowHours(), ShowMinutes()+l_i, ShowSeconds()); break; // hour 
    case 2: LCDML_DISP_funcend(); break;
  }
} 
// define help function to display the current clock settings
void digitalClockDisplay()
{
  // init display
  lcd.clear();  
  lcd.setCursor(3,0); 
  printDigits(ShowHours());  lcd.print(F(":"));
  if(g_setDate_cursorPos == 1) { lcd.print(F(" ")); }
  printDigits(ShowMinutes());  lcd.print(F(":"));
  printDigits(ShowSeconds()); 
   lcd.setCursor(0,3);  lcd.print(F("Weiter mit ENTER"));
  lcd.setCursor(0,1);  lcd.print(F("Zur\201ck"));
  
    switch(g_setDate_cursorPos) {
    case 0: lcd.setCursor(2,0); lcd.print(F("S")); lcd.setCursor(2,0); lcd.blink(); break; //hour
    case 1: lcd.setCursor(6,0); lcd.print(F("M")); lcd.setCursor(6,0); lcd.blink(); break; //min
    case 2: lcd.setCursor(8,1); lcd.print(F("mit DOWN")); lcd.setCursor(0,1); lcd.blink(); break; // year
    default: lcd.noBlink(); break;
   }
}
void printDigits(uint8_t digits)
{
  if(digits < 10)   lcd.print(F("0"));  lcd.print(digits);
}

// *********************************************************************
void LCDML_DISP_setup(LCDML_FUNC_set_date) {digitalClockDisplay();}
// *********************************************************************
void LCDML_DISP_loop(LCDML_FUNC_set_date)
{         
  if(LCDML_BUTTON_checkAny()) { // check if any button is presed (enter, up, down, left, right)
    if (LCDML_BUTTON_checkUp())    { HELP_FUNC_set_dat(+1); LCDML_BUTTON_resetUp(); }
    if (LCDML_BUTTON_checkDown())  { HELP_FUNC_set_dat(-1);  LCDML_BUTTON_resetDown(); }
    if (LCDML_BUTTON_checkEnter()) { g_setDate_cursorPos=(g_setDate_cursorPos+1)%3; LCDML_BUTTON_resetEnter(); }
    digitalClockDisplay();
  }   
}
void LCDML_DISP_loop_end(LCDML_FUNC_set_date) {    lcd.noBlink();  }

Nun ja, wenn Du mir nicht glaubst und nicht machst, was man Dir sagt...

Nachdem Dein CountDownTimer jetzt garnicht mehr funktioniert, würde ich einen kompletten Neuanfang empfehlen. Möglichst so einfach und übersichtlich, daß sich die verbleibenden Fehler ohne stundenlanges Suchen finden lassen.

if(_Min) minutes -+ _Min;Den Operator -+ kenne ich nicht, was ja nichts bedeuten muß. Was macht der?

Keine Ahnung was der macht aufjedenfall wird jetzt richtig hochgezählt.
Mit =+ hatte der +2 Std gezählt wenn Minuten über 59 waren.

skorpi08:
Keine Ahnung was der macht aufjedenfall wird jetzt richtig hochgezählt.

Ich habe mir mal die Funktion SetTimer() angesehen. Da steht "This handles invalid time overflow ie 1(H), 0(M), 120(S) -> 1, 2, 0". Wenn ich das ausprobiere, bekomme ich aber 1, 2, 120.

Stimmt der Kommentar nicht oder die Funktion?

Wenn der Kommentar stimmt, dann möglicherweise so:

void setup()
{
  Serial.begin(9600);
  Serial.println("Programmanfang");
  SetTimer(1, 0, 120);
  SetTimer(1, 62, 122);
  SetTimer(1, 12, -122);
  SetTimer(1, -10, -122);
}

void SetTimer( long hours,  long minutes,  long seconds)
{
  Serial.print("hours: ");
  Serial.print(hours);
  Serial.print("  minutes: ");
  Serial.print(minutes);
  Serial.print("  seconds: ");
  Serial.print(seconds);
  Serial.print("  ->  ");
  // This handles invalid time overflow ie 1(H), 0(M), 120(S) -> 1, 2, 0
  int8_t _Sec = (seconds / 60);
  seconds = seconds % 60;
  if (seconds < 0) {
    seconds += 60;
    minutes--;
  }

  minutes += _Sec;
  int8_t _Min = (minutes / 60);
  minutes = minutes % 60;
  if (minutes < 0) {
    minutes += 60;
    hours--;
  }

  hours += _Min;

  Serial.print("hours: ");
  Serial.print(hours);
  Serial.print("  minutes: ");
  Serial.print(minutes);
  Serial.print("  seconds: ");
  Serial.print(seconds);
  Serial.println();
}

void loop()
{
}

Nun Du :slight_smile:

Danke, muß ich nicht mehr erklären, aber -+ und =+ habe ich ersetzt.

agmue:
if(_Min) minutes -+ _Min;Den Operator -+ kenne ich nicht, was ja nichts bedeuten muß. Was macht der?

Das - wird als Subtraktion interpretiert und das + als (überflüssiges) Vorzeichen

Den gleichen Effekt gibt es bei =+ statt +=