In Module 2, Unit #6 – I was doing the “Blinking an LED with millis()” sketch. The LED blinks every second, as it is suppose to. When using the millis, does it always have to be at the top of the void loop? or can it be any where in the program? What if there was another section in the void loop that had a delay function which was longer than the millis timer, and it was before the millis function in the program.
Hi Ron, I recently when through the lesson. I’m not sure what you are trying to accomplish, but it is important to think of millis() as just a clock, currentMillis just stores the starting point, and the “timer” is really the if statement following that compares previousMillis to currentMillis to see if you reached your interval. The benefit is that your loop can run 000’s of times doing other productive stuff. Only when you reach interval time will you reset your “timer” (previousMillis = currentMillis) and perform your action (in this example, invert the LED state).
To directly answer your question, though — if you had a delay function before you establish your starting point, then naturally that delay will happen first and chew up time (when NOTHING ELSE can happen, either); then you’ll set your start time, and your if statement will be “true” on the first loop (i.e., comparing to previousmillis = 0) and you’ll set previousmillis = currentmillis. On the second and subsequent loops, the delay will chew up the interval, your elapsed time will be greater than your interval (as you propose), so your if statement will be true EVERY time. That would defeat the function and goal of using millis() as a non-blocking timer, i.e. to free up loop cycles to do other important stuff.
Changing things around and testing out your own logic can really help how you think about it. Using serial.print really helps you debug what is going on. I suggest you become familiar with interrupts and asynchronous logic (later in the lessons), and they’ll help you appreciate why using delay() isn’t recommended for single-threaded coding design.
Thanks for the explanation. I’m still in the old Arduino world, where lots of us use delays for everything not thinking about how all those tiny little delays add up to seconds. I thought it sounded silly to put some delays in the void loop where the millis would have to wait until the delays were done before it got to the lines of code with the millis in them. Can’t wait to try a program where I use no delays, but only Millis.
I am not using the Arduino, but I suspect the recommendation is the same with respect to using delay() with that hardware…check out this article: https://randomnerdtutorials.com/why-you-shouldnt-always-use-the-arduino-delay-function
In general, with microcontroller programming, we are writing code that is very much tied to the hardware, and it’s helpful to think of the loop() function as a low-level polling operation, and therefore any blocks in the loop are going to make your code very inefficient.