Whats the difference between millis and delay?

Is there a difference in between using a delay and millis

Delay is blocking, millis() is non-blocking. That is all I can tell you, I'll leave the rest up to others, as I am still learning about this myself.

is there a good example of using millis for moving servo motors.

Still kinda new

Can the more experienced forum users help here please?

delay is: do nothing for X amount of time, then resume the program

millis is: note the time, continue looping through the program, check the time every pass through the loop, and when X amount of time has passed, return to the task that called the millis and finish that task

2 Likes

how would that be written into the sketch when programming. A example for moving servo motors for X time events. Could you give a sample

There's many example's involving servo motors out there, but most people would recommend you first look into a "blink without delay" example to understand how millis() based delays actually work. Tutorial 16: Blink an LED Without using the delay() Function - Programming Electronics Academy

Way up top:

#define packetSendInterval 60 // Packet Send Interval in seconds unsigned long currentMillis = 0; // start packet timer unsigned long priorPacket = 0; // last time a packet was sent unsigned long now = millis(); // Timer: Auxiliary variables

the function:

void packetSendTimer() // send LoRa packets at intervals set in packetSendInterval { now = millis(); //start packetSendTimer if (startTimer && (now - priorPacket) > (packetSendInterval * 1000)) { currentMillis = millis(); sendLoRaPacket(); Serial.println("------- Timed LoRa Packet Sent -------"); Serial.println(); } }

void sendLoRaPacket()
{
Serial.print("+++++++ FSB "); Serial.print(FSBID); Serial.println(" LoRa Packet Send +++++++");
LoRaPacket = String(FSBID) + "#" + (readingID) + "/" + (alarmStatus) + "!" + (1.8 * bme.readTemperature() + 32) + "F" +
((bme.readPressure() / 100.0F) / 33.863886666667) + "P" + (bme.readHumidity()) + "%";
readingID++; /// roll over to zero at midnight
Serial.print("Sending packet: ");
LoRa.beginPacket();
LoRa.print(LoRaPacket);
LoRa.endPacket();
Serial.println(LoRaPacket);
now = millis();
priorPacket = (now);
startTimer = true;
}

the project: a driveway traffic sensor. it also has a weather sensor, to function as a heartbeat to let me know it's working

this code does two things:

  • void packetSendTimer() sends weather data every minute;
  • void sendLoRaPacket() sends weather data when called by void packetSendTimer(),
    and it sends alarm data when called by void alarmHandler() ( not shown )

The sketch below contains a couple of examples... once you understand the technique you can use it for all timing related stuff your program needs to do.

unsigned long startTime1 = millis();
unsigned long startTime2 = millis();

void setup()
{}

void loop()
{
  unsigned long currentTime = millis();


  // Do something once every 5 seconds.
  if (currentTime - startTime1 > 5000)
  {
    startTime1 = currentTime;
    
    // Do something.
  }


  // Do something that lasts for 10 seconds after startTime2, then stops.  
  if (currentTime - startTime2 < 10000)
  {
    // Do something
  }


  // Do stuff here every loop

}

This allows you to essentially do lots of things in parallel because none of the code "blocks"... it is all just "check the time"... and do something if the time is right. Rather than delay which effectively is "wait for the delay to be over" then continue the rest of the code.

1 Like

how do i send a example code for some odd reason its not reading what i wrote?

Perhaps "yet another" explanation will help.

  • All processors execute each instruction one at a time, and very quickly.
  • If you wrote a program that simply turned an LED on then off. With no timing limitation. The LED would be switched so fast it will look like it is on dim, you will not be able to see the full ON and full OFF.

OK...

  • a delay instruction like "delay(2000)" will stop the program when the delay code is executed. During this time the processor will be doing nothing **.

  • millis() will increment a variable, also named millis() once every millisecond ( 1/1000 seconds).

  • millis() doesn't do anything else in your code.

HOWEVER

  • You can use millis() like an alarm clock in your code. If you want to toggle the LED on and off every 2.5 seconds you can use the millis() to tell you when the 2.5 second occurs.
  • This is done by count the millis() until the millis() changes by 2500 counts (remember each count of millis is 1/1000 of a second.
  • By doing this you can do other things while waiting for the 2.5 seconds to come around, like measure a sensor and display the reading etc.
  • If you use the delay(2500) to toggle the LED, because the processor is "stopped" you will not be able to measure your sensor etc.

I tried to make this explanation as basic as possible. Please let me know if there is still something you can't quite "see"

** Some folks will say the do nothing is an over simplification. So when this happen don't get sucked in to minute details that can only make the explanation confusing.

1 Like

#include <Servo.h>

//Create a for loop

// Add the servo library.

#include<Servo.h>

//Define the 5 servo motors

Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;

unsigned long startTime1 = millis();
unsigned long startTime2 = millis();
unsigned long startTime3 = millis();
unsigned long startTime4 = millis();
unsigned long currentTime = millis();

void setup() {
// define the servo signal inputs ( digital PMW 3,5,6,9,10)

servo1.attach(3);
servo2.attach(5);
servo3.attach(6);
servo4.attach(9);
servo5.attach(10);

}

void loop();
{

<<<servo1.write(0);>>>
<<<if (currentTime - startTime1 > 1000);>>>

<<<servo2.write(45);>>>
<<<if (currentTime - startTime2 > 2000);>>>

<<<servo3.write(90);>>>
<<< if (currentTime -starTime3 > 3000);>>>

<<<servo4.write(135);>>>

<<<if (currentTime - startTime4 > 4000);>>>

}

for some reason its showing up a error.

Study the example code more closely… you have a lot of mistakes.

Just get one servo working before adding the others.

It would help if you posted the error. Please embed the error in code tags using the </> button.

Your topic does not seem to have anything to do with Avrdude, stk500 or Bootloader and hence has been moved to a more suitable location on the forum.

1 Like

Start by removing the ";" at the end of loop()

I don't know what these things ( "<<<" ">>>" ) are and I don't have any experience with servo's. However, I have edited your sketch and placed it into a simulation, with 4 LED's, controlled by 4 independant millis based delay.

You will observe that the red LED turns on after 1 second from boot, and then turns off after another second has elapsed, and then repeats this cycle forever. The green LED turns on after 2 second's from boot, and then turns off after another 2 seconds has elapsed, and then repeats this cycle forever. And so on...

unsigned long startTime1 = 0;
unsigned long startTime2 = 0;
unsigned long startTime3 = 0;
unsigned long startTime4 = 0;

int ledState1 = LOW;
int ledState2 = LOW;
int ledState3 = LOW;
int ledState4 = LOW;

void setup() {

pinMode(13, OUTPUT);
pinMode(12, OUTPUT);
pinMode(11, OUTPUT);
pinMode(10, OUTPUT);
}

void loop()
{
  
unsigned long currentTime = millis();

if (currentTime - startTime1 > 1000){
  startTime1 = millis();

    // if the LED is off turn it on and vice-versa:
    if (ledState1 == LOW) {
      ledState1 = HIGH;
    } else {
      ledState1 = LOW;
    }

    // set the LED with the ledState of the variable:
    digitalWrite(13, ledState1);
}


if (currentTime - startTime2 > 2000){
  startTime2  = millis();
     // if the LED is off turn it on and vice-versa:
    if (ledState2 == LOW) {
      ledState2 = HIGH;
    } else {
      ledState2 = LOW;
    }

  digitalWrite(12, ledState2);
}


if (currentTime -startTime3 > 3000){
  startTime3  = millis();
     // if the LED is off turn it on and vice-versa:
    if (ledState3 == LOW) {
      ledState3 = HIGH;
    } else {
      ledState3 = LOW;
    }

  digitalWrite(11, ledState3);
}

if (currentTime - startTime4 > 4000){
  startTime4  = millis();
     // if the LED is off turn it on and vice-versa:
    if (ledState4 == LOW) {
      ledState4 = HIGH;
    } else {
      ledState4 = LOW;
    }

  digitalWrite(10, ledState4);
}

}



2 Likes

They shouldn't be there for sure.

The millis() is a ready made function/routine like delay() function. These functions have been written by somebody else and has made them available to us for use in our programs.

When we call delay(1000) function to blink Led1 of Fig-1, the MCU remains blocked for 1-sec time and it has no chance to do any other tasks. There is no problem to use this function to insert time delay in a program as long as the MCU has no other task to do.

If the MCU has two tasks to perform simultaneously (time sharing) like to refresh a multiplexed display unit (Fig-1) and also to blink LED11 (Fig-1) at 1-sec interval, then the delay(1000) cannot be used to insert time delay. If the delay() function is used, the display unit will be frozen to a single digit -- a fact that can be easily verified using the setup of Fig-1. Here, the millis() function helps us to perform the said two tasks simultaneously.

When we call millis() function, it returns the content of the millisCounter in units of ms (milli second). The millisCounter is a 32-bit counter inside the MCU, which accumulates every elapsed 1-ms time. The millisCounter starts with initial value of 0 once the uploading of the sketch is finished. The 1 ms TimeTick is provided by Timer-0 of the MCU in the background on interrupt basis. The execution of the following codes shows the number of ms that has elapsed since the sketch is uploaded (the program execution has begun).

unsigned long presentMillis = millis();
Serial.println(prsentMillis, DEC);   //shows total elapsed time

7segTwoLed1Sw1
Figure-1:

Sketch for Multi-tasking (Blinking LED1 at 1-sec interval and refreshing display)

#define LED1 4
unsigned long presentMillis = 0;
bool statusLED1 = HIGH;

void setup()
{
  Serial.begin(9600);
  pinMode(LED1, OUTPUT);
}

void loop()
{
  digitalWrite(LED1, statusLED1);  //task-1
  presentMillis = millis();
  while (millis() - presentMillis < 1000)
  {
    refreshDisplay(); //task-2
  }
  statusLED1 = !statusLED1;   //inverting the current state (ON/OFF) of LED1
}

void refreshDisplay()
{
  //insert codes or ask for codes
}

1 Like

And maybe add one more TIMER.

Switch closed the 1st time, LED on a pin toggles state every 1 second.
Switch closed the 2nd time, LED on that pin stops toggling, and goes off.
etc.

2 Likes