Millis() function not delaying like I had hoped

I want my blue LED to turn on 1 second after my clear LED by using millis() when I press two buttons at the same time. The blue comes on at the same time as the clear one unless I press the two buttons as fast as my fingers will move, in which case it has the proper 1 second delay.

I'm not starting my "current time" timer until both buttons are pressed but it's not acting like I want it to. I'm sure its acting exactly as I'm telling it to.

const int Abutton = 2;
const int Bbutton = 5;
const int cLED = 13;
const int bLED = 11;

unsigned long PT = 0;
const long interval = 1000;

void setup() {
  Serial.begin(9600);
  pinMode(Abutton, INPUT_PULLUP);
  pinMode(Bbutton, INPUT_PULLUP);
  pinMode(cLED, OUTPUT);
  pinMode(bLED, OUTPUT);
}

void loop() {

while (digitalRead(Abutton) == LOW && digitalRead(Bbutton) == LOW){

  unsigned long CT = millis();  
  digitalWrite(cLED, HIGH);

  if (CT - PT > interval) {
    PT = CT;
    digitalWrite(bLED, HIGH);
 }
}

digitalWrite(cLED, LOW);
digitalWrite(bLED, LOW);

Serial.print(digitalRead(Abutton));
Serial.print(",");
Serial.println(digitalRead(Bbutton));
delay(50);

}

When your program first starts and you press both your buttons, you assign a value to CT but you never assign a value to PT so it is 0. That will make your if() statement true immediately which turns on your blue LED.

You need to

  1. debounce your buttons. Look at the bounce2 library
  2. when you detect both buttons have been pressed (or pressed close togehter), set the clear LED on and record the time. Outside that, if the current time minus the start time is greater than your interval, set the blue led

Of that much you can be sure! Arduinos tend to do exactly what you program them to do, not always what you meant.

How are your switches wired? Does LOW mean pressed?

a7

blh64 your 2nd point was exactly what I was overlooking. Thank you, here is the code that I got to work as intended.

const int Abutton = 2;
const int Bbutton = 5;
const int cLED = 13;
const int bLED = 11;

unsigned long PT = 0;
unsigned long CT = 0;
const long interval = 1000;

void setup() {
  Serial.begin(9600);
  pinMode(Abutton, INPUT_PULLUP);
  pinMode(Bbutton, INPUT_PULLUP);
  pinMode(cLED, OUTPUT);
  pinMode(bLED, OUTPUT);
}

void loop() {

while (digitalRead(Abutton) == LOW && digitalRead(Bbutton) == LOW){
  PT = millis();
  
  while (digitalRead(Abutton) == LOW && digitalRead(Bbutton) == LOW){
    CT = millis();
    digitalWrite(cLED, HIGH);

    if (CT - PT > interval) {
      PT = CT;
      digitalWrite(bLED, HIGH);
   }
 }
}

digitalWrite(cLED, LOW);
digitalWrite(bLED, LOW);

Serial.print(digitalRead(Abutton));
Serial.print(",");
Serial.println(digitalRead(Bbutton));
delay(50);

}

Toggle Library

Here's a version that debounces both buttons and is non-blocking:

#include <Toggle.h>

const int Abutton = 2;
const int Bbutton = 5;
const int cLED = 13;
const int bLED = 11;

Toggle buttonA(Abutton);
Toggle buttonB(Bbutton);

void setup() {
  Serial.begin(9600);
  buttonA.begin(Abutton);
  buttonB.begin(Bbutton);
  pinMode(cLED, OUTPUT);
  pinMode(bLED, OUTPUT);
}

void loop() {
  buttonA.poll();
  buttonB.poll();

  if (buttonA.isPressed() && buttonB.isPressed()) {
    digitalWrite(bLED, buttonA.pressedFor(1000));
    digitalWrite(cLED, HIGH);
  } else {
    buttonA.clearTimer();
    digitalWrite(bLED, LOW);
    digitalWrite(cLED, LOW);
  }
  Serial.print(buttonA.isReleased());
  Serial.print(",");
  Serial.println(buttonB.isReleased());
  delay(50);
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.