Timer Problem

I'm trying to run a simple timer but it doesnt seem to want to work. Its going to go in a much bigger project but want to get it working before i port it over to the project.

unsigned long time;
unsigned long TIMEA = 12000;
unsigned long TIMEB = 0;
int button = 0;
int buttonc = 0;
int Timer = 0;

void setup(){
  Serial.begin(9600);
  pinMode(A5, INPUT_PULLUP);  //Button
  pinMode(9, OUTPUT);
}
void loop(){

button = digitalRead(A5);

if (button == LOW) {
  if (buttonc == 0){
    buttonc = 1;
    Timer = 1;
  Serial.print("Time Start: ");
  time = millis();
  //prints time since program started
  Serial.println(time);
  TIMEB = time + TIMEA;
  Serial.print("Time Off: ");
  Serial.println(TIMEB);
  digitalWrite(9, HIGH);}
}
else {
  buttonc = 0;
}

if (Timer == 1){
 if (TIMEB == time){
   Serial.print("Time Stop: ");
   Serial.println(time);
   digitalWrite(9, LOW);
   Timer = 0;
 }
}

The last part is the part i cannot get to work. (if (TIMEB == time) onwards)

Anyone that can help me would be good.

What happens?

Have you tried ">=" instead?

I have tried both >= and >.

Nothing happens the LED i have connected to pin 9 stays on.

if i make it <= it turns the LED off stright away

You have serial output. Can you please post a dump of that?

aarg:
You have serial output. Can you please post a dump of that?

Serial output would be

Time Start: 5201
Time Off: 17201

then i get nothing out after that

if i press the button again after the 12 seconds i would get

Time Start: 21582
Time Off: 33582

as for me

main error is (TIMEB == time), where time is not refreshed with millis() value.

also :

  1. trigger on push button is not accurate => may execute several time start (one for each two loop)
  2. use millis() absolute value leads to roll over pb. correct use is (millis() - start > duration)

When you can get the code you posted to compile, get back to us.

Because neither of these two variables are changed or updated in loop, once the timer sequence starts.

   if (TIMEB == time)

Your formatting is garbage. Here, I had to fix it just so I could stand to read it:

unsigned long time;
unsigned long TIMEA = 12000;
unsigned long TIMEB = 0;
int button = 0;
int buttonc = 0;
int Timer = 0;

void setup()
{
  Serial.begin(9600);
  pinMode(A5, INPUT_PULLUP);  //Button
  pinMode(9, OUTPUT);
}

void loop() {

  button = digitalRead(A5);

  if (button == LOW) 
  {
    if (buttonc == 0)
    {
      buttonc = 1;
      Timer = 1;
      Serial.print("Time Start: ");
      time = millis();
      //prints time since program started
      Serial.println(time);
      TIMEB = time + TIMEA;
      Serial.print("Time Off: ");
      Serial.println(TIMEB);
      digitalWrite(9, HIGH);
    }
  }
  else
  {
    buttonc = 0;
  }

  if (Timer == 1)
  {
    if (TIMEB == time)
    {
      Serial.print("Time Stop: ");
      Serial.println(time);
      digitalWrite(9, LOW);
      Timer = 0;
    }
  }
}

bricoleau:
main error is (TIMEB == time), where time is not refreshed with millis() value.

Now i get where the problem is Thank

After if (Timer ... i need to refresh time.

bricoleau:

  1. trigger on push button is not accurate => may execute several time start (one for each two loop)

i am using this part of the code to stop the loop

if (buttonc == 0){
buttonc = 1;

Why so complicated?

unsigned long intervalStart;
const unsigned int duration = 12000;
bool idle = true;

void setup() {
  Serial.begin(115200);
  pinMode(A5, INPUT_PULLUP);  //Button
  pinMode(9, OUTPUT);
}

void loop()
{
  if (idle) {
    if (!digitalRead(A5)) {
      Serial.print("Time Start: ");
      intervalStart = millis();
      Serial.println(intervalStart);
      Serial.print("Time Off: ");
      Serial.println(intervalStart + duration);
      digitalWrite(9, HIGH);
      idle = false;
    }
  } else if (millis() - intervalStart >= duration) {
    Serial.print("Time Stop: ");
    Serial.println(millis());
    digitalWrite(9, LOW);
    idle = true;
  }
}

just tested it and work fine amended code here

unsigned long time;
unsigned long TIMEA = 12000;
unsigned long TIMEB = 0;
int button = 0;
int buttonc = 0;
int Timer = 0;

void setup()
{
  Serial.begin(9600);
  pinMode(A5, INPUT_PULLUP);  //Button
  pinMode(9, OUTPUT);
}

void loop() {

  button = digitalRead(A5);

  if (button == LOW)
  {
    if (buttonc == 0)
    {
      buttonc = 1;
      Timer = 1;
      Serial.print("Time Start: ");
      time = millis();
      //prints time since program started
      Serial.println(time);
      TIMEB = time + TIMEA;
      Serial.print("Time Off: ");
      Serial.println(TIMEB);
      digitalWrite(9, HIGH);
    }
  }
  else
  {
    buttonc = 0;
  }

  if (Timer == 1)
  {
    time = millis();
    if (TIMEB == time)
    {
      Serial.print("Time Stop: ");
      Serial.println(time);
      digitalWrite(9, LOW);
      Timer = 0;
    }
  }
}

I would certainly change this if (TIMEB >= time)

Replace (button == LOW) by (button == LOW && Timer == 0)

And then, buttonc is useless

I hope your program won't need to run for more than 49 days (millis() roll over)

bricoleau:
I hope your program won't need to run for more than 49 days (millis() roll over)

Why?

For example :

  • loop() duration = 10 ms with other stuff
  • TimeB set to 2^32 - 5 after something like 49 days running

stop condition like (TimeB <= millis()) may be never achieved

Right code should be something like :

void loop()
{
  static bool idle = true;
  static unsigned long start;
  const unsigned long duration = <whatever>;

  if (idle)
  {
    ...
    if (<start condition>)
    {
      start = millis();
      idle = false;
      ...
    }
  }
  else if (millis() - start >= duration)
  {
    idle = true;
    ...
  }
  ...
}

bricoleau:
Right code should be something like :

That is the framework of the working version I already posted in #11

bricoleau:
For example :

  • loop() duration = 10 ms with other stuff
  • TimeB set to 2^32 - 5 after something like 49 days running

stop condition like (TimeB <= millis()) may be never achieved

I'm not sure I'm following your argument here.