Writing Simple Loop Using Millis to Delay

Hi all,

I simply want some code that turns an LED on for a second then off for a second but use millis for a delay.

const int ledPinPower = 8; // the pin the power LED is connected to
int countMillis = 0;
int milliss = 1;

void setup() {
  pinMode(ledPinPower, OUTPUT); // Declare the power LED as an output

}

void loop() {
  if (milliss = 1) {
    digitalWrite(ledPinPower, HIGH); // Turn the power LED on
    countMillis = millis();
    while (millis() - countMillis < 1000) {
      while (true);
    }
    
    digitalWrite(ledPinPower, LOW); // Turn the power LED on
    countMillis = millis();
    while (millis() - countMillis < 1000) {
      while (true);
    }

  }
}

Above is my current code, the problem is the LED stays always on!

Any help would be great!

Thanks,

Zeb

Remove while(true).

It should be

const int ledPinPower = 8; // the pin the power LED is connected to
int countMillis = 0;
int milliss = 1;

void setup() {
  pinMode(ledPinPower, OUTPUT); // Declare the power LED as an output

}

void loop() {
  if (milliss = 1) {
    digitalWrite(ledPinPower, HIGH); // Turn the power LED on
    countMillis = millis();
    while (millis() - countMillis < 1000);

    digitalWrite(ledPinPower, LOW); // Turn the power LED on
    countMillis = millis();
    while (millis() - countMillis < 1000);

  }
}

However, this is not good practice. If you want to delay, you just need to use delay() function. If you want to blink without delay, see BlinkWithoutDelay tutorial

Excellent thank you!

Zeb

... Would it also work if you wrote :

while (millis() - countMillis < 1000){
digitalWrite(ledPinPower, LOW); 
}

Would it automatically turn the LED off afterwards?

Thanks,

Zeb

.... Ooops sorry that code is meant to be "HIGH" not "LOW"!

This is an example of how you might use millis() "properly" to blink the LED. You can add some simple logic to make it just blink once. (Compiles, not tested for bugs...)

const byte ledPinPower = 8;         // the pin the power LED is connected to

unsigned long countMillis = 0;
unsigned long countNow = 0;

bool bLEDState;

void setup() 
{
    pinMode( ledPinPower, OUTPUT ); // Declare the power LED as an output
    bLEDState = false;

}//setup

void loop() 
{
    countNow = millis();
    if( countNow - countMillis >= 1000ul )
    {
        countMillis = countNow;
        if( bLEDState == true )
        {
            bLEDState = false;
            digitalWrite( ledPinPower, LOW );
            
        }//if
        else
        {
            bLEDState = true;
            digitalWrite( ledPinPower, HIGH );
            
        }//if
                
    }//if
    
}//loop

ZebH:
Would it automatically turn the LED off afterwards?

No, once the while() ends the output is left in the last state written to it. If you want it to change state you have to explicitly make that happen.

Hi all,

Thanks for all your help!

Just a quick question Blackfin, what does the "ul" mean that is added onto the end 1000?

Thanks,

Zeb

....ah I see it turns it into a unsigned long constant!!!

I have applied Blakfin's code (Thanks Blackfin!) to this section of code in a program I am writing:

unsigned long countMillisTempDelay = 0;
unsigned long countMillisNowTempDelay = 0;
-------------------------------------------------------------------------------------------------------------
 /*TURN AIRCON ON/OFF TURN TEMPERATURE UP/DOWN*/
  countMillisNowTempDelay = millis();
  int chk = DHT11.read(DHT11PIN); //read value from temp + humidity sensor
-------------------------------------------------------------------------------------------------------------
  chk = DHT11.read(DHT11PIN); //read value from temp + humidity sensor
  if (DHT11.temperature > turnAirconOnTemp && millis() - timeSinceAirconTouched > setTimeSinceAirconTouched) { //if the temperature gets to hot and it has been over ? minutes since we have touched/controlled the aircon
    if ( countMillisNowTempDelay - countMillisTempDelay >= 1000ul ) {
      chk = DHT11.read(DHT11PIN); //read value from temp + humidity sensor
      if (DHT11.temperature > turnAirconOnTemp && millis() - timeSinceAirconTouched > setTimeSinceAirconTouched) { //if the temperature gets to hot and it has been over ? minutes since we have touched/controlled the aircon
        if ( countMillisNowTempDelay - countMillisTempDelay >= 1000ul ) {
          chk = DHT11.read(DHT11PIN); //read value from temp + humidity sensor
          if (DHT11.temperature > turnAirconOnTemp && millis() - timeSinceAirconTouched > setTimeSinceAirconTouched) { //if the temperature gets to hot and it has been over ? minutes since we have touched/controlled the aircon
            if ( countMillisNowTempDelay - countMillisTempDelay >= 1000ul ) {

              if (nCurrentThruWire > minCurrentAirconFan) { //if the aircon is on
                TempDown(); //turn the temperature down to 16°
                delay (1000);
                Mode(); //change the mode to cooling
                delay (1000);
                TempUp(); //turn the temperature upto 21°
                delay (1000);
                timeSinceAirconTouched = millis(); //remember the current millis
              }

              if (nCurrentThruWire < minCurrentAirconStandby) { //if aircon is off
                PowerButton(); //turn aircon on
                delay (1000);
                TempDown(); //turn the temperature down to 16°
                delay (1000);
                Mode(); //change the mode to cooling
                delay (1000);
                TempUp();//turn the temperature upto 21°
                delay (1000);
                timeSinceAirconTouched = millis(); //remember the current millis
              }
            }
          }
        }
      }
    }
  }

The idea is to not delay between checking the temperature.

Thanks very much,

Zeb

....Have I done this right? :slight_smile:

ZebH:
I have applied Blakfin's code

"Blackfin's" code is really just a re-statement of, but alas a backward step from, the standard blink without delay example. It's bad practice to put numbers like the 1000 in the code; the original has it handily available as a (nicely commented) variable right near the top:

const long interval = 1000;           // interval at which to blink (milliseconds)

... where it's easy to change without hunting for it.

OK thanks, I will change this ASAP!

Zeb

The demo Several Things at a Time is an extended example of BWoD and illustrates the use of millis() to manage timing without blocking. It may help with understanding the technique. It flashes 3 LEDs.

Have a look at Using millis() for timing. A beginners guide if you need more explanation.

...R

Attached is my updated code with "for loops" :slight_smile:

Thanks very much for all your help!!!

Thanks again,

Zeb

IR-Factory-Air-Con-Controller.ino (27.7 KB)

You seem have repeating patterns; e.g. TempUp()

    delayMicroseconds(64968);
    pulseIR(9240);
    delayMicroseconds(4560);
    pulseIR(600);
    ...
    ...
    delayMicroseconds(1720);
    pulseIR(600);
    delayMicroseconds(1720);
    pulseIR(600);

You can consider to store your combination of delay and pulseIR value in a struct (or class).

struct IRTIMING
{
  unsigned long delayValue;
  long pulseIrValue;
};

And create an array of those

IRTIMING temperatureUp[] = 
{
  {64968, 600},
  {4560, 600},
  ...
  ...
  {1720, 600},
  {1720, 600},
};

IRTIMING powerBTN
{
  ...
  ...
};

Next you can loop through the array

for(uint16_t cnt = 0; cnt < NUMELEMENTS(temperatureUp); cnt++)
{
  delayMicroseconds(temperatureUp[cnt].delayValue);
  pulseIR(temperatureUp[cnt].pulseIrValue)
}

NUMELEMENTS is a macro that you need to define; place the below near the top of your code

#define NUMELEMENTS(x) (sizeof(x) / sizeof(x[0]))

This will clean up your code significantly; the for-loop might however influence your timing.

Excellent thank you!

Thanks,

Zeb

P.S. Sorry for my late reply!