• Facebook
  • Twitter
  • Instagram
  • RSS
  • YouTube
  • LinkedIn
Search for:
Bald Engineer
  • Tutorials
    1. KiCad
    2. Electronics Basics
    3. Arduino
    4. millis()
    5. Microcontrollers
    6. View All
    KiCad: Connect Polygon Lines
    2022-06-09
    7+ Python Engineering Modules for Electronics Engineers
    2019-07-11
    Bit Preserve Banner Introducing Bit Preserve
    2019-06-12
    KiCon 2019 Review 6 things I learned about KiCad at KiCon 2019
    2019-05-17
    KiCon 2019 – Preserving history with KiCad
    2019-04-03
    Connect pins with KiCad Bus, Labels, and Global Labels
    2018-11-21
    KiCad Schematic Symbol Creating Custom KiCad Schematic Symbol in 5 Steps
    2018-11-14
    Mega-II Partial Symbol Drawing Apple MEGA-II Breakout in KiCad
    2018-11-01
    Low switch vs High switch Banner Low side vs. High side transistor switch
    2019-04-10
    Oscilloscope Measurements with RTM3004 Alternative Learn Six Oscilloscope Measurements with an Arduino DUT
    2018-06-13
    Picking Pull-Up Resistor Value | AO #25
    2018-05-04
    Arduino Keyboard Matrix Code and Hardware Tutorial
    2017-12-15
    Voltage Dividers as Regulators Voltage Dividers as Regulators?! | AddOhms #22
    2017-10-16
    voltage divider circuits 5 Voltage divider circuits that go beyond dividing
    2017-08-23
    Aeroscope Measuring a Fan PWM a 3-pin PC fan with an Arduino
    2017-07-05
    share projects Share projects on one of these 4 platforms
    2017-04-26
    Arduino millis banner Arduino millis() plus addition does not add up
    2018-10-10
    Arduino MKR Vidor 4000 - Blue Arduino MKR Vidor 4000 Hands-On
    2018-08-15
    Pyramiduino Turn-On Standalone Arduino Turn-On and Debug
    2018-07-09
    Arduino Math Five Arduino math fixes for when it is wrong
    2018-07-04
    Arduino EEPROM Hero 1600px Arduino EEPROM stores any datatype
    2018-06-20
    Oscilloscope Measurements with RTM3004 Alternative Learn Six Oscilloscope Measurements with an Arduino DUT
    2018-06-13
    Pyramiduino KiCad PCB Desgin DIY Arduino PCB Pryamiduino (Video)
    2018-02-28
    adafruint fona hologram mqtt Hologram.io connects Adafruit FONA
    2018-02-07
    detect short long button press using millis Detect short and long button press using millis
    2017-04-19
    Fading LED millis() Example Fading LED: analogWrite millis() Example
    2016-11-23
    Delayed Actions with Millis Use Arduino millis() with buttons to delay events
    2016-01-27
    Red Microswitch on Breadboard with debounce library Arduino: De-Bounce a Button with micros() or millis()
    2013-12-13
    Arduino: Chasing LEDs with millis()
    2013-12-12
    Arduino: Timing Code with Millis() as a Stopwatch
    2013-12-11
    Arduino: Independent On-Off Times with Millis()
    2013-12-10
    Arduino Millis() Examples
    2013-12-09
    Pyramiduino Turn-On Standalone Arduino Turn-On and Debug
    2018-07-09
    Oscilloscope Measurements with RTM3004 Alternative Learn Six Oscilloscope Measurements with an Arduino DUT
    2018-06-13
    5 common arduino programming mistakes 5 Common Arduino Programming Mistakes
    2016-08-17
    arduino bootloader Arduino Bootloader, What is it?
    2016-06-15
    proper larson scanner Proper Larson Scanner with Software PWM (Repost)
    2015-10-21
    Space Invaders on Gecko EFM32
    2015-01-16
    install arduino library from github banner Installing Arduino Library from GitHub
    2015-01-07
    Well formatted Arduino code in one click
    2014-05-16
    Difference between flux (for soldering)
    2022-08-17
    Essential Logic Families | Workbench Wednesdays #35
    2021-03-02
    Measuring A 555 On An Oscilloscope | Workbench Wednesdays #33
    2021-01-01
    Thermal Tools for Circuit Measurements | Workbench Wednesdays
    2020-02-23
    DMM Basics Video Tutorial | Workbench Wednesdays
    2020-02-23
    4-Wire Resistance Tutorial | Workbench Wednesdays
    2020-02-23
    Digilent Analog Discovery 2 Review | Workbench Wednesdays
    2019-12-29
    Function Generator Basics | Workbench Wednesdays
    2019-12-29
    Previous Next
  • Projects
    MC1377 Measurements on Mini Apple IIe Prototype video board
    2021-08-02
    Bit Preserve Banner Introducing Bit Preserve
    2019-06-12
    What is the Apple IIgs? – AddOhms Live Clip
    2018-11-19
    Mega-II Partial Symbol Drawing Apple MEGA-II Breakout in KiCad
    2018-11-01
    raspberry pi startup script Raspberry Pi Startup Script Tutorial
    2017-06-28
    RPSPC State Machine Soft Power Controller State Machine
    2017-06-21
    Raspberry Pi Soft Power Controller – The Circuit
    2017-05-03
    3 Way Camera Shoe
    2016-08-04
    proper larson scanner Proper Larson Scanner with Software PWM (Repost)
    2015-10-21
    software PWM code example line by line Arduino Software PWM with millis()
    2015-10-07
    Previous Next
  • Video
    1. Workbench Wednesdays
    2. AddOhms
    3. Twitch Channel
    4. View All
    Difference between flux (for soldering)
    2022-08-17
    Oscilloscope Trigger Primer
    2022-08-04
    How to Profile Battery Usage for IoT Devices
    2022-06-25
    Do ALL Scope Probes Need Ground?
    2022-06-24
    How Oscilloscope Acquisition Modes Work
    2022-06-23
    Hands-On with B&K Precision 9140 Power Supply | Workbench Wednesdays #53
    2022-06-22
    Three Tips to Improve Your Soldering | Workbench Wednesdays #52
    2022-03-10
    How to Measure Ripple Voltage on a Switch-Mode Power Supply | Workbench Wednesdays #51
    2022-02-28
    Arduino Uno in front of an R&S RTM3000 Learn Oscilloscope Basics with an Arduino Uno
    2018-09-03
    Arduino MKR Vidor 4000 Showcase MKR 4000 VIDOR Hands-On Video | AddOhms Live
    2018-08-14
    Pyramiduino Turn-On Standalone Arduino Turn-On and Debug
    2018-07-09
    Adafruit Coin Acceptor Programming Adafruit Coin Acceptor on AddOhms Live
    2018-06-17
    Creating an AddOhms Animations – Behind The Scenes
    2018-05-28
    Picking Pull-Up Resistor Value | AO #25
    2018-05-04
    EAGLE 9 First Look – Couple of things I noticed
    2018-04-25
    Pyramiduino KiCad PCB Desgin DIY Arduino PCB Pryamiduino (Video)
    2018-02-28
    Previous Next
  • Reviews
    1. Books
    2. Tools
    3. Test Equipment
    4. View All
    Review of The Innovators: How a Group of Hackers, Geniuses, and Geeks Created the Digital Revolution
    2016-03-14
    the martian book review The Martian
    2015-11-12
    A Whole New Engineer A Whole New Engineer
    2015-11-02
    Eight Amazing Engineering Stories: Using the Elements to Create Extraordinary Technologies Eight Amazing Engineering Stories: Using the Elements to Create Extraordinary Technologies
    2015-01-13
    Signal and Power Integrity Cover Signal and Power Integrity – Simplified (2nd Edition)
    2014-12-29
    How to Profile Battery Usage for IoT Devices
    2022-06-25
    Do ALL Scope Probes Need Ground?
    2022-06-24
    How Oscilloscope Acquisition Modes Work
    2022-06-23
    Hands-On with B&K Precision 9140 Power Supply | Workbench Wednesdays #53
    2022-06-22
    DIY Solder-In Oscilloscope Probes | Workbench Wednesdays #50
    2022-02-02
    Instrument Basics: Logic Probe | Workbench Wednesdays #27
    2020-08-13
    Spectrum Analyzer Basics | Workbench Wednesdays
    2019-10-16
    Measuring ESR with the PEAK ESR70 | Workbench Wednesdays Review
    2019-06-26
    How to Profile Battery Usage for IoT Devices
    2022-06-25
    Do ALL Scope Probes Need Ground?
    2022-06-24
    How Oscilloscope Acquisition Modes Work
    2022-06-23
    Hands-On with B&K Precision 9140 Power Supply | Workbench Wednesdays #53
    2022-06-22
    DIY Solder-In Oscilloscope Probes | Workbench Wednesdays #50
    2022-02-02
    Instrument Basics: Logic Probe | Workbench Wednesdays #27
    2020-08-13
    Spectrum Analyzer Basics | Workbench Wednesdays
    2019-10-16
    Tenma 72-2660 Portable Hand Held Supply | Workbench Wednesdays
    2019-05-13
    Digilent Analog Discovery 2 Review | Workbench Wednesdays
    2019-12-29
    DCA Pro Transistor Tester Review | Workbench Wednesdays
    2019-08-07
    Hakko FX-888D Review
    2019-07-03
    Measuring ESR with the PEAK ESR70 | Workbench Wednesdays Review
    2019-06-26
    Penguin Bot Black Red and Clear Penguin Bot from elegoo hands-on review of the kit build
    2018-09-19
    EAGLE 9 First Look – Couple of things I noticed
    2018-04-25
    R&S FPC1500 Review FPC1500 Review, a Rohde & Schwarz Spectrum Analyzer
    2018-04-04
    Adafruit Feather Banner Adafruit Feather Review and Selection Guide
    2018-01-24
    Previous Next
  • Contact
  • Live Streams
  • About
blink without delay tutorial
Arduino

Blink without delay() explained line-by-line

By James Lewis 2015-08-05 6 Mins Read
Making the move to millis()-based code can be daunting. You have to rethink your logic, implement flags, program a state machine — and more importantly, start using millis(). Generally in forums and on IRC people will just point to the “blink without delay” example, hoping the commented code is enough for a new user. It’s not enough. I have a growing list of millis()-based tasks posted in my millis() cookbook. But sometimes that those examples might be too simple or not close enough to your project’s end target. That got me thinking about different ways to help explain how millis() works. I thought “wow, you need to understand every line of an example” which leads me to: line-by-line. Give this “blink without delay line by line” tutorial a shot if you’ve had trouble understanding other millis() examples. If you aren’t familiar with the blink without delay example, here is a stripped-down version.

const int ledPin =  13;
int ledState = LOW;
unsigned long previousMillis = 0;
unsigned long interval = 1000;

void setup() {
  pinMode(ledPin, OUTPUT);
} 

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;
    digitalWrite(ledPin, ledState);
  }
}

Global Variables


const int ledPin =  13;
Like many example scripts, this code uses the Arduino onboard LED. If you’re using a LaunchPad with Energia, you would want to change this to something like “GREEN_LED.” Notice that this is an integer variable type with the const. This keyword tells the compiler the value of “ledPin” cannot change. There is also some optimizations that occur with avr-gcc for variables declared as const. The difference between const and #define is defined in another post, if you want to dig a little deeper. [arduino firstline=”2″] int ledState = LOW; This state variable, or flag variable, is going to track the state of the LED. When using millis() it is pretty common to create these “state variables” to track what is happening in the code. Are you new to “flags” and “states”? Then check out this post on flag variables and this one on state machines with an enum. [arduino firstline=”3″] unsigned long previousMillis = 0; Blink without delay needs to keep track from loop-to-loop. This variable will let us know the “last” time we checked millis(). Since millis() returns an unsigned long, this variable needs the same variable type.
The biggest mistake I see people make with millis() code is defining this as an int. If you do that, you’ll have roll-over issues.
[arduino firstline=”4″] unsigned long interval = 1000; We need to wait a certain amount of time between states. Here we call the variable “interval”. Unless I am tight on RAM, I’ll define “interval” as an unsigned long, even if the number could have fit into an int. Using the same variable types avoids casting problems, or more likely, bugs because I don’t always understand how the compiler casts variables.

setup()

[arduino firstline=”6″] void setup() { pinMode(ledPin, OUTPUT); } Okay, this is more than 1 line of code. But the only thing we need to do is set our LED’s pin to OUTPUT.

loop()

[arduino firstline=”10″] void loop() { The key to remember is that code inside of loop() will run for forever. In millis()-based code, we want to write everything with the mindset: “This will run thousands of times a second.” [shareable text=”Write millis()-based code with the mindset: “This will run thousands of times a second.””]Write millis()-based code with the mindset: “This will run thousands of times a second.”[/shareable] What does that mindset mean? It means lots of if-statements and variable checks. No, not working? Okay, I’ll use an analogy to get through the rest of the code.

Sandwich example

Let’s say you order a delicious sandwich. The waiting time is 10 minutes. So you look at your watch and see that it is 12:04 pm. After sitting down you check your watch again, now it is 12:05 pm—9 minutes to go. Bored you start reading /r/funny. Now you look at your watch, and it is 12:09 pm—5 minutes to go. Wow, time is flying. At this point, you decide to see read an analysis of last week’s Mr. Robot. You check your watch, and it is 12:13 pm. Great, only one more minute. Pack up your things, look at your watch and it says 12:14 pm—0 minutes! Excellent, time to go and get your delicious sandwich. The key here is that you didn’t use a “timer” or “alarm.” Instead, while you were busy doing other things (aka multitasking) you kept checking to see how much time had passed since the start. [arduino firstline=”11″] unsigned long currentMillis = millis(); Each time loop() runs, we need to check the current time. Think of this as looking at your watch to see what time it is right now. (The very first time we go through loop(), previousMillis is still going to be set to “0”. Technically that was the FIRST time we looked at the time.) [arduino firstline=”12″] if(currentMillis – previousMillis > interval) { Here is the magic code that scares people new to millis()-based programs. This single line of code appears in more than just “blink without delay”. For example, all of my millis()-cookbook examples have this line of code . The code simply reads subtract the current time from the previous time. Then check if more than our waiting time has passed. Using subtraction like this handles the case where millis() “rolls-over” in 49 days. This post goes into detail about how to avoid millis() rollover. Most people try to reset millis(), when all you need to do is handle roll over. [arduino firstline=”13″] previousMillis = currentMillis; Here’s where we update previousMillis for the first time. Whenever our waiting period has passed, we need to reset the initial time. If your millis() code doesn’t seem to be working, check to make sure you are resetting previousMillis. [arduino firstline=”14″] if (ledState == LOW) ledState = HIGH; else ledState = LOW; Even those this isn’t a single line, the C-complier sees it as 1 line. Basically, we need to toggle the state of ledState so that it will turn ON or OFF. [arduino firstline=”18″] digitalWrite(ledPin, ledState); } } The last thing we do is set the LED to its state variable. This code is the breakdown of the example included with the Arduino(-based) IDEs. In my code, I generally leave the digitalWrite() outside of the if-statement.

Exercise for the reader

Ready to test your knowledge? Okay, add a push-button to this code to enable or disable the blinking.
What other common Arduino / Microcontroller examples do you need explained?
line-by-linemillis()
0
Author James Lewis

Fan of making things beep, blink and fly. Created AddOhms. Stream on Twitch. Video Host on element14 Presents and writing for Hackster.IO. Call sign KN6FGY.

  • Website
state-machine-with-enum-tutorial
Prev Post

Microcontroller state machine with enum tutorial

2015-07-29 5 Mins Read
Pull-Up Resistor Tutorial
Next Post

AddOhms #15: Pull-Up Resistors (and buttons)

2015-08-10 1 Min Read

Related Posts

7+ Python Engineering Modules for Electronics Engineers

2019-07-11
Arduino millis banner

Arduino millis() plus addition does not add up

2018-10-10
Arduino MKR Vidor 4000 - Blue

Arduino MKR Vidor 4000 Hands-On

2018-08-15
Pyramiduino Turn-On

Standalone Arduino Turn-On and Debug

2018-07-09

33 Comments

  1. Marcel 2 years ago Reply

    Thank you for the great explanation..

    What kinda always annoyed me as the noob i am, is that the Millis method works in reverse as presented… It starts with a LED Off state, then it counts up Millis to reach the set interval value and the LED switches On…

    Searched quite a while and even tho i wasn’t the only one complaining about it i still couldn’t find a straight foreward answer… Anyway I figured out myself to fix this issue, it actually is very simple… I changed the “unsigned long previousMillis = 0;” into a equal number as in the interval but then as a minus.

    That would be

    unsigned long previousMillis = -1000;
    unsigned long interval = 1000;

    Then it starts with a LED on and so on…

    Cheers…

    • Stefan Ludwig 2 years ago Reply

      The most easy way to do this is to assign the opposite value in the variable definition
      the given code has in line 2
      int ledState = LOW;

      and to change this to
      int ledState = HIGH;

      and you are done

      best regards Stefan

      • Marcel 2 years ago Reply

        Thank you for the fast reply…

        I think i failed to mention i was playing with an ESP8662 NodeMCU board and i already tried to change line 2 but it doesn’t work. It simply stays as is, whatever HIGH or LOW is changed..

        Till now the only way to get around it, is as what I described previously.

        Cheers..

  2. Stefan Ludwig 3 years ago Reply

    Hi I got pointed to this tutorial through a link in the Arduino-Forum. Very well explained. I don’t have an overview about your tutorials yet. Ideas about other beginners (or a bit advanced beyond beginner) might be

    – when and how to use interrupt service-routines or when to use alternatives

    . use selfexplaining names everywhere

    – PString and/or SafeString als alternatives to “String”

    – ESP826/ESP32-stuff (especially ESP-NOW)

    best regards Stefan

  3. Angel 4 years ago Reply

    Hola.
    Me podría ayudar a hacer un contador con un pulsador de por ejemplo 10 pulsos y en este pulso se me active una salida durante un tiempo predeterminado. Luego de ese tiempo desactive esa salida, ponga a cero el contador y siga contando pulsos sin que afecte a la ejecución del código independientemente de la velocidad de los pulsos

  4. Wes 4 years ago Reply

    Why not define the ledstate as byte = 0 and remove the if / else loop and replace it with ledstate = (1 – ledstate).. it saves some ram and program space and works just the same.

  5. me 4 years ago Reply

    Hi,
    Could you tell me why this program does’t show anything?
    [arduino firstline=””]
    #include <LiquidCrystal>
    lcd(7, 8, 9, 10, 11, 12);
    int buzzer = 5;
    int x = 1;
    unsigned long past = 0;
    unsigned long s11 = 150;
    unsigned long s2 = 200;
    unsigned long s22 = 250;
    unsigned long s3 = 300;
    unsigned long s4 = 400;
    unsigned long s5 = 500;
    unsigned long s7 = 700;

    void setup() {

    lcd.begin(16, 2);
    pinMode(buzzer, OUTPUT);

    }

    void loop() {
    unsigned long c = millis();
    if (c == 1000)
    {
    lcd.print("Happy birthday");
    lcd.setCursor(0, 1);
    lcd.print(" to you!");
    }

    if (c == 3000);
    lcd.clear();
    if (c == 3500)
    {
    lcd.print("Happy birthday");
    lcd.setCursor(0, 1);
    lcd.print(" to you!");
    }
    if (c == 6500)
    lcd.clear();
    if (c == 7000)
    {
    lcd.print("Happy birthday");
    lcd.setCursor(0, 1);
    lcd.print("dear…");
    }
    if (c == 11000)
    lcd.clear();
    if (c == 11500)
    {
    lcd.print("Happy birthday");
    lcd.setCursor(0, 1);
    lcd.print(" to you!");
    }

    }
    [/arduino]

    • me 4 years ago Reply

      Avoid those variables from the begining :))

    • James Lewis Post Author 4 years ago Reply

      The problem is that you are looking for an exact value of millis(). You will probably never get so lucky to be checking for a value of “1000” at the EXACT moment millis() is that value.

      The right way is to use a ranged comparison like “less than” or “greater than.” However, if you just change the code to be: if (millis() >= 1000) then once millis() is more than 1000, it’ll always print that statement. That means you need to add some flags.

      In a case like this where you are trying to print a sequential message, you could just use a variable to sequence.

      [arduino firstline=”1″]
      int statement = 0;
      if ((millis() >= 1000) && (statement == 0)) {
      statement = statement + 1; // increment the statement variable
      // print whatever
      }
      [/arduino]

      Then on your next check you would do:

      [arduino firstline=”10″]
      if ((millis() >= 3000) && (statement == 1)) {
      statement = statement + 1; // increment the statement variable
      // print whatever
      }
      [/arduino]
      and so on.

  6. Dan 4 years ago Reply

    Hi There, great line by line, really helped me understand better.

    Do you think a logical AND (&&) can be added to your 1st IF statement to check for time but also a button state ? I need to turn “blink” a remote relay via Xbee but check that the user pushed a button to activate it 1st. Basically the relay will blink a light attached to it, but the user needs to have switched on the light to have it blink, otherwise it should just be off.

    Thanks

    • James Lewis Post Author 4 years ago Reply

      Yes.

    • James Smirniotopoulos 4 years ago Reply

      Dan: Did you implement the button, and if it worked, could you post your sketch?

  7. simon 5 years ago Reply

    Hi James, I love your tutorials. My problem is:
    From “Master-Slave” coding to light on/off a LED with “H” and “L” chars sent to a Serial Monitor, I try ADDING code to also start and stop Stepper motor to that LED lightning .
    What avenue could be best for me to do that?
    I try code in loop…and code in Function….no success.
    Thanks.
    Simon.

    • James 5 years ago Reply

      I’m not able to help debug code (especially when I can’t see it.) I would suggest posting your question, along with code, on the Arduino Programming Forum. That way others can help.

  8. Prao 5 years ago Reply

    Hi James! Thanks a lot for the line-by-line explanation.

    I need to keep the LED on for 1s and then keep it off for the next 3 seconds and so on. Could you please help me how to do this ?

    Thanks

    • James Lewis Post Author 5 years ago Reply

      Independant on-off tutorial.

  9. Salvador 5 years ago Reply

    I would like to know how to blink an LED twice or three time in per second. I am new to Arduino and found your site most informative in my learning Arduino Coding.

    • James Lewis Post Author 5 years ago Reply

      Change the interval. 250ms would be twice per second. 166ms would be (about) 3 times per second.

  10. Ron Kierstead 6 years ago Reply

    Thanks James, I stumbled on this while trying to figure out why my code wasn’t multitasking.

    I really appreciate the line-by-line explanation.

  11. Mike 7 years ago Reply

    Hello,
    Great write up – the line by line was very helpful for beginners like myself. I need some further advice on how to do the following:

    1- Always be “looking” for a switch
    2- When the switch is closed sweep a servo (I have this part of the code working nicely)
    3- Wait some amount of time when the sweep is complete to start “looking” for the switch being closed again. So even if the switch is held closed or closed again during this time frame the servo will not sweep.

    It seems I need to somehow use the Millis() command and perhaps some type of flag/states as in your example code in the comments below. I’m just not sure how to tie them together and any help is much appreciated as I mentioned I’m new to the Arduino/coding world.

    Thanks!

  12. Fernando 7 years ago Reply

    Hi! I need to use the Millis() command while reading data from the HX711 ADC. Do you happen to have any tutorial about how to program any ADC (such as the HX711), please? Thank you!

  13. anupam 7 years ago Reply

    hi
    i am working on a project theft intimation of vehicles using gsm and tracking it by gps.
    here i am getting stuck with the infinite loop used in gps as it is continuously sending the lattitude and longitude. i also have to check 4 ir sensors and a pir sensor continuously.
    please help me urgently for how am i going to use two loops in a program, out of which one is infinite loop.
    the codes i am using are

    (code removed)

    please reply as soon as posible
    thank you

    • James Lewis Post Author 7 years ago Reply

      Since this is so urgent, it is probably better to post on a public forum. I suggest the “Project Guidance” section of the Arduino.cc forums.

  14. Ainsley Swartwout 7 years ago Reply

    Hi,
    I’m trying to figure out how to print a statement after a certain amount of time after a button is pushed and held down. Millis() starts at the beginning of when the program starts and I want it after the button is pushed. Any suggestions?

    • James Lewis Post Author 7 years ago Reply

      Just like all of the other millis() examples I have. Record the time at which the event occurs, then compare to the previous time. Use flags to control when the message goes out.

      Something like this:
      [arduino firstline=””]
      //Global Variables
      unsigned long buttonPushedMillis;
      unsigned long delayInterval = 2500; // 2500ms or 2.5 second
      bool messageReady = false; // flag for when button is let go

      void setup() {
      Serial.begin(9600);
      pinMode(2, INPUT_PULLUP);
      }

      void loop() {
      unsigned long currentMillis = millis(); // record what time it is

      // this code will work with a pushbutton using the internal pull-up
      // the variable "buttonPushedMillis" will get updated each iteration of loop, or
      // while the button is held down. when released, buttonPushedMillis has the "last"
      // value of millis
      if (digitalRead(2) == LOW) {
      buttonPushedMillis = currentMillis;
      messageReady = true;
      }

      // make sure this code isn’t checked until after button has been let go
      if (messageReady) {
      //this is typical millis code here:
      if ((unsigned long)(currentMillis – buttonPushedMillis) >= delayInterval) {
      // okay, enough time has passed since the button was let go.
      Serial.println("Message");
      // wait for next button press
      messageReady = false;
      }
      }
      }
      [/arduino]

      • Ainsley Swartwout 7 years ago Reply

        Thanks, this was very helpful. Also, I am so going to tweet your quote thousands of times.

        • Ainsley Swartwout 7 years ago Reply

          🙂

  15. Chris 7 years ago Reply

    Hey James-

    I have been trying to wrap my brain around the millis() concept and i seem to be missing something. I have read your posts roughly 5-6 times each. I just can’t grasp the concept. I have the below code that currently is running and working just fine. I am looking to add a string of Neopixel code to run while the linear actuator is moving both up or down, but only then. Think of it like a warning light while the actuator is moving. I understand the delay() function literally stops the whole void loop() and nothing else can be done, but I just can’t apply the millis() concept. If you have time I would appreciate you taking a look at my code and seeing if you can point me in a direction. I am fairly new to the Arduino world, and while I am enjoying myself I find moments like these frustrating. I appreciate your help in advance.

    The Neopixel code would go where I’ve marked it below:
    [arduino collapse=”true”]
    //2015 TV Stand and Controller Control
    const int Relay1 = 7;
    const int Relay2 = 6;
    const int Relay3 = 5;
    const int Relay4 = 4;

    int Relay1a = 8;
    int Relay2a = 9;
    int Relay3a = 10;
    int Relay4a = 11;

    const int buttonPin0 = 0;
    const int buttonPin1 = 1;
    const int buttonPin2 = 2;
    const int buttonPin3 = 3;

    int buttonState0 = 0;
    int buttonState1 = 0;
    int buttonState2 = 0;
    int buttonState3 = 0;

    // the setup routine runs once when you press reset:
    void setup() {

    pinMode(buttonPin0, INPUT);
    pinMode(buttonPin1, INPUT);
    pinMode(buttonPin2, INPUT);
    pinMode(buttonPin3, INPUT);

    pinMode(Relay1, OUTPUT);
    pinMode(Relay2, OUTPUT);
    pinMode(Relay3, OUTPUT);
    pinMode(Relay4, OUTPUT);
    pinMode(Relay1a, OUTPUT);
    pinMode(Relay2a, OUTPUT);
    pinMode(Relay3a, OUTPUT);
    pinMode(Relay4a, OUTPUT);

    }

    void loop () {
    buttonState0 = digitalRead(buttonPin0);//Keyfob D
    buttonState1 = digitalRead(buttonPin1);//Keyfob C
    buttonState2 = digitalRead(buttonPin2);//Keyfob B
    buttonState3 = digitalRead(buttonPin3);//Keyfob A

    if (buttonState3 == HIGH) {

    //Neopixel code runs here until the 22 seconds to lift the actuator are up and then they would stop

    digitalWrite(Relay1,HIGH);//Actuator up segment
    delay(22000);
    digitalWrite(Relay1,LOW);
    }

    if (buttonState3 == LOW){
    }

    if (buttonState2 == HIGH) {

    //Neopixel code would run here until the 23 seconds to close the actuator are up and then stop

    digitalWrite(Relay2,HIGH);//Actuator down segment
    delay(23000);
    digitalWrite(Relay2,LOW);
    }

    if (buttonState2 == LOW);{
    }

    if (buttonState1 == HIGH) {

    digitalWrite(Relay1a, HIGH);//XBox Controller Tray
    delay(1000);
    digitalWrite(Relay1a, LOW);
    delay(10000);
    digitalWrite(Relay2a, HIGH);
    delay(1000);
    digitalWrite(Relay2a,LOW);
    }

    if (buttonState0 == HIGH){

    digitalWrite(Relay3a, HIGH);//Remote Control Tray
    delay(1000);
    digitalWrite(Relay3a, LOW);
    delay(10000);
    digitalWrite(Relay4a, HIGH);
    delay(1000);
    digitalWrite(Relay4a, LOW);
    }
    }[/arduino]

    • James Lewis Post Author 7 years ago Reply

      The changes you need to make aren’t difficult, but will require rethinking the code. Your code can’t have sequential steps. Instead, you need to build “states”. This lets the code decide what the next step will be. For example, once a button is pressed set a flag to high. if that flag is high and relay1’s initial state is 0, then turn it on and “wait.” once that time is over, make relay1’s state be equal to 1 for the off time and “wait.” once that is done set your relay1 state flag back to 0 and start the process with relay2.

      More than I can explain in comments here. I’d suggest you post your code and request on the arduino programming forum [forum.arduino.cc]. Feel free to provide the link once you do, and I’ll try to answer there.

      In the mean time, 3 things I noticed:

      1) based on the code, you need to make sure you are using pull-down resistors with your buttons. Otherwise, you’ll get false reads.

      2) your variable names aren’t very helpful. instead of “button2” make it “red lights” or whatever it controls. It is very easy to get confused between the numbers you make up, the pin numbers on the arduino, and pin numbers on the device when reading through code.

      3) I would avoid using D0 and D1, since those conflict with serial. So if you want to do any debugging, that is going to be very difficult.

  16. Mark Schilke 8 years ago Reply

    Thanks, James, for another excellent post! You might consider, however, revising it to keep the line numbers of the extracted lines consistent with the line numbers of the complete program.

    • James Lewis Post Author 8 years ago Reply

      I’ve updated the lines with matching numbers. Thanks for the great suggestion.

      • NoobieDrew 2 years ago Reply

        Having some trouble, I can get the led to stay on instead of off. Which I need, so i need it to blink with a momentary toggle. Press on Blink,press again Blink off but Led stays on. How can I implement the toggle button code into this?

        Thank you!

        • Stefan Ludwig 2 years ago Reply

          Not sure what you want to achieve. Do you mean having a button to start/stop the blinking?
          1st short button-press blinking starts
          2nd short button-press blinking stops
          3rd short button-press blinking starts
          etc. etc.
          ?

          This is done by using another boolean variable that you must define
          take a name that is selfexplaining

          “blinkingRun”
          so each button-press sets blinkingRun to the inverted state
          blinkingRun= !blinkingRun; // “!” is the not-operator

          and then there is a condition
          if (blinkingRun) {
          //blinking-code here
          }

          I got the impression that you did NOT yet understand how it works
          so write a first attempt how you thinkit might work

          best regards Stefan

Write A Comment Cancel Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  • AddOhms Discord
  • Most Popular Posts
    • mqtt tutorial
      MQTT Tutorial for Raspberry Pi, Arduino, and ESP8266
    • millis() Tutorial: Arduino Multitasking
    • Positive Voltages with a P-Channel MOSFET Tutorial
      P-Channel MOSFET Tutorial with only Positive Voltages
    • MSGEQ7 Simple Spectrum Analyzer
    • The 4 best transistors to keep in your parts kit
    • Arduino: How do you reset millis() ?
    • Low switch vs High switch Banner
      Low side vs. High side transistor switch
    • 5 Myths Everyone Believes about Arduino (that aren’t true)
    • Arduino Millis() Examples
    • Arduino: Independent On-Off Times with Millis()
  • Become a Bald Engineer Patreon
  • Most Recent Posts
    • Difference between flux (for soldering)
      Workbench Wednesdays
    • Oscilloscope Trigger Primer
      Workbench Wednesdays
    • How to Profile Battery Usage for IoT Devices
      Workbench Wednesdays
    • Do ALL Scope Probes Need Ground?
      Workbench Wednesdays
  • Facebook
  • Twitter
  • Instagram
  • RSS
  • YouTube
  • LinkedIn

© 2023 Bald Engineer Media, LLC.

Top
  • Tutorials
    • KiCad
    • Electronics Basics
    • Arduino
    • millis()
    • Microcontrollers
  • Projects
  • Video
    • Workbench Wednesdays
    • AddOhms
    • Twitch Channel
  • Reviews
    • Books
    • Tools
    • Test Equipment
  • Contact
  • Live Streams
  • About
Like other websites, this one uses cookies to remember things. Mostly, I use Google Analytics to know how many people come here. ¯\_(ツ)_/¯
By clicking “Accept”, you consent to the use of ALL the cookies.
.
Cookie SettingsAccept
Manage consent

Privacy Overview

This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necessary
Always Enabled
Necessary cookies are absolutely essential for the website to function properly. These cookies ensure basic functionalities and security features of the website, anonymously.
CookieDurationDescription
cookielawinfo-checkbox-advertisement1 yearSet by the GDPR Cookie Consent plugin, this cookie is used to record the user consent for the cookies in the "Advertisement" category .
cookielawinfo-checkbox-analytics11 monthsThis cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Analytics".
cookielawinfo-checkbox-functional11 monthsThe cookie is set by GDPR cookie consent to record the user consent for the cookies in the category "Functional".
cookielawinfo-checkbox-necessary11 monthsThis cookie is set by GDPR Cookie Consent plugin. The cookies is used to store the user consent for the cookies in the category "Necessary".
cookielawinfo-checkbox-others11 monthsThis cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Other.
cookielawinfo-checkbox-performance11 monthsThis cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Performance".
CookieLawInfoConsent1 yearRecords the default button state of the corresponding category & the status of CCPA. It works only in coordination with the primary cookie.
viewed_cookie_policy11 monthsThe cookie is set by the GDPR Cookie Consent plugin and is used to store whether or not user has consented to the use of cookies. It does not store any personal data.
Functional
Functional cookies help to perform certain functionalities like sharing the content of the website on social media platforms, collect feedbacks, and other third-party features.
CookieDurationDescription
languagesessionThis cookie is used to store the language preference of the user.
Performance
Performance cookies are used to understand and analyze the key performance indexes of the website which helps in delivering a better user experience for the visitors.
Analytics
Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics the number of visitors, bounce rate, traffic source, etc.
CookieDurationDescription
_ga2 yearsThe _ga cookie, installed by Google Analytics, calculates visitor, session and campaign data and also keeps track of site usage for the site's analytics report. The cookie stores information anonymously and assigns a randomly generated number to recognize unique visitors.
_ga_LHR6J24XSY2 yearsThis cookie is installed by Google Analytics.
_gat_gtag_UA_42726312_11 minuteSet by Google to distinguish users.
_gid1 dayInstalled by Google Analytics, _gid cookie stores information on how visitors use a website, while also creating an analytics report of the website's performance. Some of the data that are collected include the number of visitors, their source, and the pages they visit anonymously.
browser_id5 yearsThis cookie is used for identifying the visitor browser on re-visit to the website.
CONSENT2 yearsYouTube sets this cookie via embedded youtube-videos and registers anonymous statistical data.
Advertisement
Advertisement cookies are used to provide visitors with relevant ads and marketing campaigns. These cookies track visitors across websites and collect information to provide customized ads.
CookieDurationDescription
VISITOR_INFO1_LIVE5 months 27 daysA cookie set by YouTube to measure bandwidth that determines whether the user gets the new or old player interface.
YSCsessionYSC cookie is set by Youtube and is used to track the views of embedded videos on Youtube pages.
yt-remote-connected-devicesneverYouTube sets this cookie to store the video preferences of the user using embedded YouTube video.
yt-remote-device-idneverYouTube sets this cookie to store the video preferences of the user using embedded YouTube video.
yt.innertube::nextIdneverThis cookie, set by YouTube, registers a unique ID to store data on what videos from YouTube the user has seen.
yt.innertube::requestsneverThis cookie, set by YouTube, registers a unique ID to store data on what videos from YouTube the user has seen.
Others
Other uncategorized cookies are those that are being analyzed and have not been classified into a category as yet.
SAVE & ACCEPT
Powered by CookieYes Logo