what am i doing wrong?

I wish someone can help me because i am going crazy with this.

I have made this code based on 2 sketchs that work great seperated but when i get them toguether... it goes crazy.

it is a menu with 3 items and a coundown timer ( for now it has fixed time hardcoded).

When i select 5m ( the only option i coded ) it blinks ( and for a split second i can see the countdown starting) and it returns to the main menu.

So... no countdown :frowning:

What the hell am i doing wrong?

thank you all

/***********************************************************
Curing/Washing Box 1.01
by Xmodpt 
Last update @ 08/04/2020

****** Version Control *******
1.0 - Countdown tested and working with relay and stepper
1.01 - Added menu with 3 options
***********************************************************/

#include <Arduino.h>
/****** U8G2 LIB *********/
#include <U8g2lib.h>
/***** U8G2 settings *****/
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif

/********STEPPER LIB *****************/
#include <AccelStepper.h> // stepper motor lib 
AccelStepper stepper; // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5

/**** U8G2 Display settings *****/
//U8G2_SH1106_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

/********* Timer Settings ******************/
// 10000ul =   10 sec
// 30250ul =   30 sec
// 60500ul =   1 min
// 302500ul =  5 min
// 605000ul = 10 min
// 907500ul = 15 min
#define COUNTDOWN_TIME  10000ul // Set timer

char
    szString[20];
byte
    mins, secs;
       
unsigned long
    timeTemp,
    timeNow,
    timeStart,
    timeElapsed,
    timeLeft;   


// End of constructor list

const char *string_list = 
  "05 min\n"
  "10 min\n"
  "15 min\n"
  "\n"
  "About";

uint8_t current_selection = 1;


void setup(void) {
 //  stepper.setMaxSpeed(1000);
 //  stepper.setSpeed(50);  
 // RELAY SETTINGS 
//     pinMode(pinRele, OUTPUT);
     
   // Rotary encoder or buttons
    u8g2.begin(/*Select=*/ A2, /*Right/Next=*/ A4, /*Left/Prev=*/ A5, /*Up=*/ A0, /*Down=*/ A1, /*Home/Cancel=*/ A3); // Arduboy DevKit
  // Font Type config 
    u8g2.setFont(u8g2_font_6x12_tr);
    u8g2.clearDisplay();
    Serial.begin(9600); 
    timeStart = millis();
    mins = 1;
    secs = 1;
  
}


void loop(void) {

  current_selection = u8g2.userInterfaceSelectionList(
    "Curing Station V1.0",
    current_selection, 
    string_list);

  if ( current_selection == 1 ) {
   DoCountdown();
     }
  
  if ( current_selection == 2 ) {
 
  }
  if ( current_selection == 3 ) {

  }
  if ( current_selection == 5 ) {
    u8g2.userInterfaceMessage(
  "About:", 
  "Curing system",
  "design by Xmodpt",
  "ver: 1.0");
    }
}
void DoCountdown()
{
   //u8g2.clearBuffer();
    static unsigned long
        lastTimeNow = 0;
    static byte
        lastsecs = 1;
       
    timeNow = millis();
    timeElapsed = timeNow - timeStart;
   
    if( mins == 0 && secs == 0 )
        return;
       
    timeLeft = COUNTDOWN_TIME - timeElapsed;

    mins = (byte)(timeLeft / 60000ul);
    timeTemp = timeLeft - (mins * 60000);
    secs = (byte)(timeTemp / 1000ul);
    timeTemp = timeTemp - (secs * 1000ul);

    if( mins == 0 && secs == 0 )
    {
        return;      
    }
    else if( secs != lastsecs )
    {
        lastsecs = secs;
        u8g2.setCursor( 20,45 );
        sprintf( szString, "%02d:%02d", mins, secs );
        Serial.println( szString ); 
        u8g2.clearBuffer(); 

        u8g2.print( szString );
     }
   
   u8g2.sendBuffer();

}

I don't know the library you're using for your menu, so I may be wrong, but it looks like when you call countdown, you're having it return when the mins and secs remaining reach zero. Trouble is, it returns at the end of the function anyway.

So unless the menu code sends it to countdown again, it will go there once and be done. I think you need to loop in countdown until time is up.

Also, I suspect that time start should be set when countdown starts, not when the program does.

Thank you for the reply

wildbill:
I don't know the library you're using for your menu, so I may be wrong, but it looks like when you call countdown, you're having it return when the mins and secs remaining reach zero. Trouble is, it returns at the end of the function anyway.

the idea is click on a menu option (5min)-> the countdown starts (and show the countdown) and in the en the countdown has a text that shows DONE
If i execute just the countdown code, it counts and in the end shows DONE and it stays there.
as it is it does nothing :frowning:

The lib id the U8G2 ( because i couldn't find a simple exemple using Adafruit lib )

wildbill:
Also, I suspect that time start should be set when countdown starts, not when the program does.

That is the $100000000000 question... how to do it ...

XModpt

any ideas ?

By initializing it to the current time, somewhere near the start of DoCountdown().

Hello m8

How do i do that ?
Please note: i am not using a RTC with this.

Thk u

This is too mundane a question for me to write code for. I respectfully suggest that you focus your efforts on simpler sketches. It would greatly improve your comprehension if you started to write your own programs from scratch, too. Merging two sketches that you don't really understand is not the way to learn anything, and it often lands new programmers in deep trouble.

Alldo i don't like your awnser, i have to agree with you. start simple and go from there.
the reason i asked for help was that i have a peace of code that i am just starting to comprehend i hit a wall that i can't see.

It is nor was my intention to ask anyone to code for me... what i ask is someone that knows to show me where i am wrong so i can learn.

I have to admit i am not a programer and i have done the basics... tutorials, read exemples, go to google and youtube but that brickwall is there.

in other words... show me not how to use the hammer but where to hit ... :wink:

never the less thankyou for your coment.

regards
Xmodpt

@aarg

Please do not be offended with my last post. it is not my intent.

again
Ty

I can't really understand why you can't work with reply #4. Recording the time is done in other places in the sketch so you know how to do that. The beginning of DoCountdown() is not hard to find. If you examine that part of the code, you really can't figure out how to do that?

Partly, I don't want to hand out code without understanding your entire scheme. You already set timeNow = millis(). Later you reference 'timeStart' as if it has the same meaning as 'timeNow'. Perhaps that is a sufficient clue?

hello m8 thank you for the hint however it still blinks and doen't show the countdown... i really am dum:(

xmodpt:
hello m8 thank you for the hint however it still blinks and doen't show the countdown... i really am dum:(

What is "it"? If you have modified your code from the code that you originally posted, please give us an update by posting it in a new reply.

As peer my original post, my problem is "When i select 5m oprion on the menu, the counder does not start ( meeneing, it blinks from 5m to countdown) and in 1 sec gets back to the main menu and nothing happens.

Hoever if i execute just the menu it works great as is and if i just ececute the countdown ( seperate sketch) it runs semodly.

i have checked your hint and i found i had to calls to the same "time" in the DoCountdown(). even if i coment part of the code it(the code) still blinks and nothing happens and that is why i asked for help ;).

here is the code for the menu + countdowd with the change in the DoCountdown():

/***********************************************************
Curing/Washing Box 1.01
by Xmodpt 
Last update @ 08/04/2020

****** Version Control *******
1.0 - Countdown tested and working with relay and stepper
1.01 - Added menu with 3 options
***********************************************************/

#include <Arduino.h>
/****** U8G2 LIB *********/
#include <U8g2lib.h>
/***** U8G2 settings *****/
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif

/********STEPPER LIB *****************/
#include <AccelStepper.h> // stepper motor lib 
AccelStepper stepper; // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5

/**** U8G2 Display settings *****/
//U8G2_SH1106_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

/********* Timer Settings ******************/
// 10000ul =   10 sec
// 30250ul =   30 sec
// 60500ul =   1 min
// 302500ul =  5 min
// 605000ul = 10 min
// 907500ul = 15 min
#define COUNTDOWN_TIME  10000ul // Set timer

char
    szString[20];
byte
    mins, secs;
       
unsigned long
    timeTemp,
    timeNow,
    timeStart,
    timeElapsed,
    timeLeft;   


// End of constructor list

const char *string_list = 
  "05 min\n"
  "10 min\n"
  "15 min\n"
  "\n"
  "About";

uint8_t current_selection = 1;


void setup(void) {
 //  stepper.setMaxSpeed(1000);
 //  stepper.setSpeed(50);  
 // RELAY SETTINGS 
//     pinMode(pinRele, OUTPUT);
     
   // Rotary encoder or buttons
    u8g2.begin(/*Select=*/ A2, /*Right/Next=*/ A4, /*Left/Prev=*/ A5, /*Up=*/ A0, /*Down=*/ A1, /*Home/Cancel=*/ A3); // Arduboy DevKit
  // Font Type config 
    u8g2.setFont(u8g2_font_6x12_tr);
    u8g2.clearDisplay();
    Serial.begin(9600); 
    timeStart = millis();
    mins = 1;
    secs = 1;
  
}


void loop(void) {

  current_selection = u8g2.userInterfaceSelectionList(
    "Curing Station V1.0",
    current_selection, 
    string_list);

  if ( current_selection == 1 ) {
   DoCountdown();
     }
  
  if ( current_selection == 2 ) {
 
  }
  if ( current_selection == 3 ) {

  }
  if ( current_selection == 5 ) {
    u8g2.userInterfaceMessage(
  "About:", 
  "Curing system",
  "design by Xmodpt",
  "ver: 1.0");
    }
}
void DoCountdown()
{
   //u8g2.clearBuffer();
//    static unsigned long
//        lastTimeNow = 0;
    static byte
        lastsecs = 1;
       
    timeNow = millis();
    timeElapsed = timeNow - timeStart;
   
    if( mins == 0 && secs == 0 )
        return;
       
    timeLeft = COUNTDOWN_TIME - timeElapsed;

    mins = (byte)(timeLeft / 60000ul);
    timeTemp = timeLeft - (mins * 60000);
    secs = (byte)(timeTemp / 1000ul);
    timeTemp = timeTemp - (secs * 1000ul);

    if( mins == 0 && secs == 0 )
    {
        //return;      
    }
    else if( secs != lastsecs )
    {
        lastsecs = secs;
        u8g2.setCursor( 20,45 );
        sprintf( szString, "%02d:%02d", mins, secs );
        Serial.println( szString ); 
        u8g2.clearBuffer(); 

        u8g2.print( szString );
     }
   
   u8g2.sendBuffer();

}

and this is the code for just the countdown sketch

/****

******/ 

/****** U8G2 LIB *********/
#include <U8g2lib.h>
/***** U8G2 settings *****/
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
/*************************/
#include <AccelStepper.h> // stepper motor lib 


AccelStepper stepper; // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5
/**** U8G2 Display settings *****/
//U8G2_SH1106_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
/********************************/

/** ADAFRUITE Display settings **/
//#define OLED_ADDR       0x3C //Oled address
//#define OLED_RESET -1 // Oled reset
//    Adafruit_SH1106 display(OLED_RESET); //Oled config type
/*********************************/

/****** Time config list ********/
// 10000ul =   10 sec
// 30250ul =   30 sec
// 60500ul =   1 min
// 302500ul =  5 min
// 605000ul = 10 min
// 907500ul = 15 min
#define COUNTDOWN_TIME  10000ul // Set timer
#define pinRele 6        //Set relay Pin  
#define nivelRele HIGH   //Relay logic

char
    szString[20];
byte
    mins, secs;
       
unsigned long
    timeTemp,
    timeNow,
    timeStart,
    timeElapsed,
    timeLeft;   

void setup()
{  
   stepper.setMaxSpeed(1000);
   stepper.setSpeed(50);  
 // RELAY SETTINGS 
     pinMode(pinRele, OUTPUT);
     digitalWrite(pinRele, !nivelRele);
 // initialize and clear display
    u8g2.begin(/*Select=*/ A2, /*Right/Next=*/ A4, /*Left/Prev=*/ A5, /*Up=*/ A0, /*Down=*/ A1, /*Home/Cancel=*/ A3); // Arduboy DevKit
    u8g2.setFont(u8g2_font_helvB24_tf );
    u8g2.clearDisplay();
  
   Serial.begin(9600);
    timeStart = millis();
    mins = 1;
    secs = 1;
}
void loop()
{  
   DoCountdown();
   stepper_motor();
   relay_action();
}

/****** VOIDS ********/
void stepper_motor()
{  
   if ( mins == 0 && secs == 0 ) { 
    
       stepper.stop();
      
   } else {
       stepper.runSpeed();
   }
}
void relay_action(){
  
  if ( mins == 0 && secs == 0 ) { 
    
      digitalWrite(pinRele, nivelRele);
      
   } else {
      digitalWrite(pinRele, !nivelRele);
   }
  
  }

void DoCountdown()
{
   //u8g2.setFont(u8g2_font_helvB24_tf );
   //u8g2.clearBuffer();
//    static unsigned long
//        lastTimeNow = 0;
    static byte
        lastsecs = 1;
       
    timeNow = millis();
    timeElapsed = timeNow - timeStart;
   
    if( mins == 0 && secs == 0 )
        return;
       
    timeLeft = COUNTDOWN_TIME - timeElapsed;

    mins = (byte)(timeLeft / 60000ul);
    timeTemp = timeLeft - (mins * 60000);
    secs = (byte)(timeTemp / 1000ul);
    timeTemp = timeTemp - (secs * 1000ul);

    if( mins == 0 && secs == 0 )
    {
        u8g2.clearDisplay();
        u8g2.setCursor( 15, 45 );
        sprintf( szString, "DONE" );
        u8g2.print( szString );
        Serial.println( szString );       
    }
    else if( secs != lastsecs )
    {
        lastsecs = secs;
        u8g2.setCursor( 20,45 );
        sprintf( szString, "%02d:%02d", mins, secs );
        Serial.println( szString ); 
        u8g2.clearBuffer(); 
        //u8g2.clearDisplay();
        u8g2.print( szString );
     }
   
   u8g2.sendBuffer();
   //display.display();
}

One last think that could help or not in finding the issue

I am using a rotary endoder and when i press it to start the countdown ( select option ) i get a glimps (blink) of the countdown starting and it gets back to the main menu, if i press it again, again i can have a glimps of the countdown and the overall time i droping
Exemple

select 5m -> click to select -> blinks countdown 00:10-> returns to main menu -> click again -> blinks countdown 00:09 -> back to main menu -> and so on ... till it ends but i never get to see a full countdown nor the "DONE" message in the end.

TY

Xmodpt

just found out something that is getting me more crazy and dum...

using my 1st sketch or the changed version... i turned on the serial monitor and found aldo i don't clik anything the counting started allredy ( as is booted ) and i found that the count is countingdown from 158:00 -> 157:59 -> 157:58.... etc ... :disappointed_relieved:

i am >:( with myselft

after some testing i found that my countdown starts as soon as the arduino boots.

then

i made some changes to the code e mover the millis() config to the void DoCountDown insted of beeing in the void setup and now aldow i still cant see the countown, now it statrs only if i press the rotary encoder.

code as is

/***********************************************************
Curing/Washing Box 1.01
by Xmodpt 
Last update @ 08/04/2020

****** Version Control *******
1.0 - Countdown tested and working with relay and stepper
1.01 - Added menu with 3 options
***********************************************************/

#include <Arduino.h>
/****** U8G2 LIB *********/
#include <U8g2lib.h>
/***** U8G2 settings *****/
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif

/********STEPPER LIB *****************/
#include <AccelStepper.h> // stepper motor lib 
AccelStepper stepper; // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5

/**** U8G2 Display settings *****/
//U8G2_SH1106_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

/********* Timer Settings ******************/
// 10000ul =   10 sec
// 30250ul =   30 sec
// 60500ul =   1 min
// 302500ul =  5 min
// 605000ul = 10 min
// 907500ul = 15 min
#define COUNTDOWN_TIME  10000ul // Set timer

char
    szString[20];
byte
    mins, secs;
       
unsigned long
    timeTemp,
    timeNow,
    timeStart,
    timeElapsed,
    timeLeft;   


// End of constructor list

const char *string_list = 
  "05 min\n"
  "10 min\n"
  "15 min\n"
  "\n"
  "About";

uint8_t current_selection = 1;


void setup(void) {
 //  stepper.setMaxSpeed(1000);
 //  stepper.setSpeed(50);  
 // RELAY SETTINGS 
//     pinMode(pinRele, OUTPUT);
     
   // Rotary encoder or buttons
    u8g2.begin(/*Select=*/ A2, /*Right/Next=*/ A4, /*Left/Prev=*/ A5, /*Up=*/ A0, /*Down=*/ A1, /*Home/Cancel=*/ A3); // Arduboy DevKit
  // Font Type config 
    u8g2.setFont(u8g2_font_6x12_tr);
    u8g2.clearDisplay();
    Serial.begin(9600); 

  
}


void loop(void) {

  current_selection = u8g2.userInterfaceSelectionList(
    "Curing Station V1.0",
    current_selection, 
    string_list);

  if ( current_selection == 1 ) {
    timeStart = millis();
    mins = 1;
    secs = 1;
   //u8g2.clearDisplay();
   //u8g2.clearBuffer(); 
      DoCountdown();
   //u8g2.sendBuffer();

     }
  
  if ( current_selection == 2 ) {
 
  }
  if ( current_selection == 3 ) {

    DoCountdown();
  }
  if ( current_selection == 5 ) {
    u8g2.userInterfaceMessage(
  "About:", 
  "Curing system",
  "design by Xmodpt",
  "ver: 1.0");
    }
}
void DoCountdown()
{

   //u8g2.clearBuffer();
    static unsigned long
        lastTimeNow = 0;
    static byte
        lastsecs = 1;
       
    timeNow = millis();
    timeElapsed = timeNow - timeStart;
   
    if( mins == 0 && secs == 0 )
        return;
       
    timeLeft = COUNTDOWN_TIME - timeElapsed;

    mins = (byte)(timeLeft / 60000ul);
    timeTemp = timeLeft - (mins * 60000);
    secs = (byte)(timeTemp / 1000ul);
    timeTemp = timeTemp - (secs * 1000ul);

    if( mins == 0 && secs == 0 )
    {
        //return;      
    }
    else if( secs != lastsecs )
    {
        lastsecs = secs;
        u8g2.setCursor( 20,45 );
        sprintf( szString, "%02d:%02d", mins, secs );
        Serial.println( szString ); 
        u8g2.clearBuffer(); 

        u8g2.print( szString );
     }
   
   u8g2.sendBuffer();

}

You still need a loop in DoCountdown.

A loop IN the countdown?!?! Is it possible? How do I do that?

Ty
Xmodpt

Use a while loop. Just to get the idea, try while(min>0)

It will have to be something like

While (min>0){
DoCountdown();
}

And I place the while loop in the button call?