Darn millis()

So I'm trying to make a code using millis(). When a button is pressed and held, a led stars blinking, when released the led stops. Im having a problem where the code isn't reading the button instantly, so there is the same delay, as the led blinking delay in my button reading. I have been tring to solve this thing for too long now. Could some legend give me a hint about the mechanism? Do I need to use arrays or what? thanks
40 Replies
Maverick
Maverick2mo ago
There is an example you can access in the Arduino IDE called BlinkWithoutDelay.
TheStudier
TheStudierOP2mo ago
I know how to blink without delays but adding the button there I just can't get it
Maverick
Maverick2mo ago
You can use a boolean, for example buttonHeld.
TheStudier
TheStudierOP2mo ago
interesting i'll try that oh so its just a true false holder thing
Maverick
Maverick2mo ago
Yes, so if you're using the INPUT_PULLUP pin mode for the button, you can use buttonHeld = !digitalRead(buttonPin);. This means buttonHeld is true when the pin is connected to ground via the button.
TheStudier
TheStudierOP2mo ago
but I can do the same with IF?
Maverick
Maverick2mo ago
You would then use IF like so:
c++
if (buttonHeld) {
// Blink LED
} else {
// LED off
}
c++
if (buttonHeld) {
// Blink LED
} else {
// LED off
}
TheStudier
TheStudierOP2mo ago
but the problem is: how can I connect the two: Blink without delay and start the blinking when button is held? I know how to do both on their own, but I just can't connect them
Maverick
Maverick2mo ago
Just put your blinking code where the // Blink LED comment is.
TheStudier
TheStudierOP2mo ago
I forgot how can I print in code form here ´´´ide awea but this is the code: v v currentMillis = millis(); if (currentMillis - previousMillis1 >= 10000) { previousMillis1 = currentMillis; ledState = !ledState; } if (val1 == LOW) { digitalWrite(yLed, ledState); } else { digitalWrite(yLed, LOW); } When I press the button, the led goes to ledState, that can be LOW OR HIGH at the moment, so that is the problem when the button is pressed, it would always need to put the led high and then start blinking
Maverick
Maverick2mo ago
Just read the button pin in loop(). The code you have should be fine.
TheStudier
TheStudierOP2mo ago
Isn't it in the loop already?
Maverick
Maverick2mo ago
It's not there at all. I assume you just missed it when copy / pasting. You want the LED to blink at 10 second intervals? You want it to go high immediately when the button is pressed? I'm not clear on what the problem is.
TheStudier
TheStudierOP2mo ago
Is there any chance, that you could try to do a code blinks led when button is pressed? I would like to see If you run into the same problem as I I can't explain it really well, maybe youll understand it If you get the same problem Im going crazy here its been 5 hours no sleep
Maverick
Maverick2mo ago
If you want the LED to start it's blinking HIGH every time, you need a second boolean to keep track of the button state. If the button changes state from not pressed to pressed, set the ledState variable to HIGH and reset the millis counter for the blinking.
c++
if (currentMillis - previousMillis1 >= 10000) {
previousMillis1 = currentMillis;
ledState = !ledState;
}

if (val1 == LOW) {
if (!buttonState) {
previousMillis1 = currentMillis - 15000;
ledState = false;
}
buttonState = true;
digitalWrite(yLed, ledState);
} else {
buttonState = false;
digitalWrite(yLed, LOW);
}
c++
if (currentMillis - previousMillis1 >= 10000) {
previousMillis1 = currentMillis;
ledState = !ledState;
}

if (val1 == LOW) {
if (!buttonState) {
previousMillis1 = currentMillis - 15000;
ledState = false;
}
buttonState = true;
digitalWrite(yLed, ledState);
} else {
buttonState = false;
digitalWrite(yLed, LOW);
}
TheStudier
TheStudierOP2mo ago
I'll look into this tomorrow thanks so much angel from the sky I was wondering, in the code you have if (!buttonState) {} that what does this mean? I thought if statement should have == or > or something like that
AnonEngineering
AnonEngineering2mo ago
! means logical NOT so if buttonState is false, !buttonState is true
TheStudier
TheStudierOP2mo ago
oh okay but when would the buttonState be false and when would it be true Can the buttonState be an int?
AnonEngineering
AnonEngineering2mo ago
int buttonState = digitalRead(BTN_PIN);
TheStudier
TheStudierOP2mo ago
oh Im dumb
AnonEngineering
AnonEngineering2mo ago
whether it ends up being true or false when pushed depends on how you wired it
TheStudier
TheStudierOP2mo ago
alrgiht tysm this helps
AnonEngineering
AnonEngineering2mo ago
btw, you might wonder why it isn't boolean, but Arduino uses int for pin states 🤷‍♂️
TheStudier
TheStudierOP2mo ago
if (currentMillis - previousMillis1 >= 10000) { previousMillis1 = currentMillis; ledState = !ledState; } if (val1 == LOW) { if (!buttonState) { previousMillis1 = currentMillis + 15000; ledState = false; } buttonState = true; digitalWrite(yLed, ledState); } else { buttonState = false; digitalWrite(yLed, LOW); } this is stil too complicated for me I cant understand it I give up too much time on this same problem
Maverick
Maverick2mo ago
You didn't get it to work? The code I posted is nearly the entire thing.
TheStudier
TheStudierOP2mo ago
yes it worked, but I dont understand the code, thats important, right? this was something I didnt quite grasp previousMillis1 = currentMillis + 15000; what does this thing do in your code?
Maverick
Maverick2mo ago
Yes. That line makes this if statement true the next time loop() is called, which happens immediately.
c++
if (currentMillis - previousMillis1 >= 10000) {
previousMillis1 = currentMillis;
ledState = !ledState;
}
c++
if (currentMillis - previousMillis1 >= 10000) {
previousMillis1 = currentMillis;
ledState = !ledState;
}
So, since previousMillis is set to currentMillis + 15000, the difference between the two is greater than 10000. That resets the timer, starting the blink pattern from the beginning. It also causes ledState to be set to true. So, the LED lights up and begins blinking at the regular interval.
TheStudier
TheStudierOP2mo ago
damn dude thanks you so much I finally understands this! took me a while, but maybe it s worth it. Do you think It is worth it to spend many hours trying to figure out how a code works?
Maverick
Maverick2mo ago
If you enjoy doing so, yes. Also, each time you do this, the amount of time it takes to understand will be less. You will solve problems like this in minutes, but you will also take on more complex problems which take hours, potentially months or years depending on what you get into.
TheStudier
TheStudierOP2mo ago
surely that's true, if I get far, I'll thank you
Reeshav_Ghosh200
@TheStudier have you set the buttonPin as INPUT_PULLUP or used an external resistor on the button?
TheStudier
TheStudierOP2mo ago
INPUT_PULLUP was used how so?
Reeshav_Ghosh200
INPUT_PULLUP will use the arduino's internal pullup resistor. This will prevent the buttonState from being in a 'floating' state where it constantly keeps changing its values
TheStudier
TheStudierOP2mo ago
yes indeed thank you nvm damnt it I'm not sure how this works so this here: previousMillis1 = currentMillis + 15000; sets the previousMillis bigger than the currentMillis So this is not true then: if (currentMillis - previousMillis1 >= 10000)
Maverick
Maverick2mo ago
Sorry. I made a mistake. It should be previousMillis1 = currentMillis - 15000; You want the if statement to be true. You could also just set previousMillis1 to zero. As long as the if statement is true, it will work.
TheStudier
TheStudierOP2mo ago
alright thanks a lot
Maverick
Maverick2mo ago
The original method of adding 15000 works because subtracting a number from currentMillis that is greater than itself would have a negative result, causing the value to wrap around to an extremely large number that is always greater than 10000. So, it also works but was not intentional and I would never do it that way on purpose.
TheStudier
TheStudierOP2mo ago
alright , I wondered why it worked glad I looked at It a little more carefully
Maverick
Maverick2mo ago
Sorry for the confusion caused by my mistake.
TheStudier
TheStudierOP2mo ago
np

Did you find this page helpful?