Blink LED without using delay in the main loop

Hi, I want to add blinking to my led, without using delay that will interrupt the overall system. The main loop has delay 3s, which will read temperature from sensor every 3s. I had try using example of "led blinking without delay", it was able to blink, but the blinking interval is not correct, it follows main loop delay, which not what I want.

I want the led to blink every 100ms in the 3s delay main loop. Any ideas?

//declare variables
int buzzer = 5;
int yellow1 = 3;  //warning temp
int red1 = 4; // overtemp 
int red = 2;  // red led indicate flame
float tempC;
float voltage;
int tempPin =0; // Temp sensor plugged analog pin 0
int flamePin= 1;

// write setup function 

void setup()
{
  Serial.begin(9600);// open serial port to communicate with the temp sensor
  pinMode(red1, OUTPUT);
  pinMode(yellow1, OUTPUT);  
  pinMode (red, OUTPUT);
  pinMode (buzzer, OUTPUT);

}

//write loop that will control what we want the arduino to do with the sensor readout

void loop()
{
  tempC = analogRead(tempPin); // taking the temp pin reading and setting it equal to tempC variable
  tempC = (5.0*tempC*100.0)/1024.0; // will convert the analog input to a temperature in celcius
  Serial.print((byte)tempC); //will output the converted temperature to pc
  Serial.println("02");  //xbee 2
  
  voltage = analogRead(flamePin);
  voltage = (5.0*voltage)/1023.0;
  Serial.print("0");
  Serial.print((byte)voltage);
  Serial.println("04"); //flame sensor from xbee2
  
      
    

////////////////////////////////////////////////////////////    
  
  if (tempC>34)  //overtemp
  {
     if (voltage <= 3)  //there is flame and temp >40, give fire alert!
     {
    digitalWrite (red1, HIGH);  //overtemp 
    digitalWrite (yellow1, LOW);  //overtemp     
    digitalWrite (red, HIGH);  //flame detected
    digitalWrite (buzzer, HIGH); //give alert
    }
    else  //temp>40, but no flame, possibility of false alarm
    {
    digitalWrite(red, LOW); //RED led, no flame alert
    digitalWrite (yellow1, LOW);  //overtemp 
    digitalWrite (red1, HIGH);  //high temp alert
    digitalWrite (buzzer, LOW);   //no alert   
    }
 

  }    
 ////////////////////////////////////////////////////////////// 
  
  
  else if ((tempC > 30) && (tempC <= 34))  //warning temp range
 {
  if (voltage <= 3)  //there is flame and temp n warning range
     {
    digitalWrite (yellow1, HIGH);  //overtemp 
    digitalWrite (red1, LOW);  //overtemp 
    digitalWrite (red, HIGH);  //flame detected
    digitalWrite (buzzer, HIGH); //give alert
    }
    else  //warning temp, but no flame, possibility of false alarm
    {
    digitalWrite(red, LOW); //RED led, no flame alert
    digitalWrite (yellow1, HIGH);  //high temp alert
    digitalWrite (red1, LOW);  //overtemp 
    digitalWrite (buzzer, LOW);   //no alert   
    }

}    
    else  //not in warning range and no flame
    {
    digitalWrite(red, LOW);  //RED led, no flame alert
    digitalWrite (yellow1, LOW);  //YELLOW led, no high temp alert    
    digitalWrite (red1, LOW);  //overtemp 
    digitalWrite (buzzer, LOW);   //no alert
    }
  

  delay(3000);
}

Hi, have you read and understood the "Blink Without Delay" example sketch?

Paul

Ah, you edited your original post while I was replying...

The point of the BWD sketch is the principal of checking if a desired period has passed and taking an action when it has. In your case you have 2 desired periods: one of 3 secs and the other of 100ms. You have to keep track separately of the time each of those two periods began, and test separately for the end of either/both periods.

Post your sketch with the attempt to use the BWD principle.

below is use the principle of blink without delay.. I know somewhere wrong but no ideas how to correct it.. because it involve two timing.. it can blink but blink with the delay in main loop. Any ideas? I just try it on yellow led only.

//declare variables
int buzzer = 5;
int yellow1 = 3;  //warning temp
int red1 = 4; // overtemp 
int red = 2;  // red led indicate flame
float tempC;
float voltage;
int tempPin =0; // Temp sensor plugged analog pin 0
int flamePin= 1;

int yellow1state = LOW;
long previousMullis = 0;
long interval = 100;
// write setup function 

void setup()
{
  Serial.begin(9600);// open serial port to communicate with the temp sensor
  pinMode(red1, OUTPUT);
  pinMode(yellow1, OUTPUT);  
  pinMode (red, OUTPUT);
  pinMode (buzzer, OUTPUT);

}

//write loop that will control what we want the arduino to do with the sensor readout

void loop()
{
  tempC = analogRead(tempPin); // taking the temp pin reading and setting it equal to tempC variable
  tempC = (5.0*tempC*100.0)/1024.0; // will convert the analog input to a temperature in celcius
  Serial.print((byte)tempC); //will output the converted temperature to pc
  Serial.println("02");  //xbee 2
  
  voltage = analogRead(flamePin);
  voltage = (5.0*voltage)/1023.0;
  Serial.print("0");
  Serial.print((byte)voltage);
  Serial.println("04"); //flame sensor from xbee2
  
      
    

////////////////////////////////////////////////////////////    
  
  if (tempC>34)  //overtemp
  {
     if (voltage <= 3)  //there is flame and temp >40, give fire alert!
     {
    digitalWrite (red1, HIGH);  //overtemp 
    digitalWrite (yellow1, LOW);  //overtemp     
    digitalWrite (red, HIGH);  //flame detected
    digitalWrite (buzzer, HIGH); //give alert
    }
    else  //temp>40, but no flame, possibility of false alarm
    {
    digitalWrite(red, LOW); //RED led, no flame alert
    digitalWrite (yellow1, LOW);  //overtemp 
    digitalWrite (red1, HIGH);  //high temp alert
    digitalWrite (buzzer, LOW);   //no alert   
    }
 

  }    
 ////////////////////////////////////////////////////////////// 
  
  
  else if ((tempC > 30) && (tempC <= 34))  //warning temp range
 {
  if (voltage <= 3)  //there is flame and temp n warning range
     {
    digitalWrite (yellow1, HIGH);  //overtemp 
    digitalWrite (red1, LOW);  //overtemp 
    digitalWrite (red, HIGH);  //flame detected
    digitalWrite (buzzer, HIGH); //give alert
    }
    else  //warning temp, but no flame, possibility of false alarm
    {
    digitalWrite(red, LOW); //RED led, no flame alert

    ///////////////////////////// yellow1 start blink

    unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis > interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;  

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

    // set the LED with the ledState of the variable:
    digitalWrite(yellow1, yellow1State);
  }


    ////////////////////////////////
    digitalWrite (red1, LOW);  //overtemp 
    digitalWrite (buzzer, LOW);   //no alert   
    }

}    
    else  //not in warning range and no flame
    {
    digitalWrite(red, LOW);  //RED led, no flame alert
    digitalWrite (yellow1, LOW);  //YELLOW led, no high temp alert    
    digitalWrite (red1, LOW);  //overtemp 
    digitalWrite (buzzer, LOW);   //no alert
    }
  

  delay(3000);
}

Your post subject says "without using delay in main loop". So you already know what you need to do. There must be a reason why you have not done it, can you explain please?

Also I can see a spelling error in that sketch, it cannot have been tested.

I do not see any code there for testing if 3 seconds has passed and it is time to read your sensors again.

okok.. I know what you means.. :cold_sweat: My title should "Blink LED without using delay in a delay main loop"....

I don't want to delete the delay in main loop.. :~

Sorry my mistake on the typo in the sketch, here it is. No error detected.

//declare variables
int buzzer = 5;
int yellow1 = 3;  //warning temp
int red1 = 4; // overtemp 
int red = 2;  // red led indicate flame
float tempC;
float voltage;
int tempPin =0; // Temp sensor plugged analog pin 0
int flamePin= 1;

int yellow1State = LOW;
long previousMillis = 0;
long interval = 100;
// write setup function 

void setup()
{
  Serial.begin(9600);// open serial port to communicate with the temp sensor
  pinMode(red1, OUTPUT);
  pinMode(yellow1, OUTPUT);  
  pinMode (red, OUTPUT);
  pinMode (buzzer, OUTPUT);

}

//write loop that will control what we want the arduino to do with the sensor readout

void loop()
{
  tempC = analogRead(tempPin); // taking the temp pin reading and setting it equal to tempC variable
  tempC = (5.0*tempC*100.0)/1024.0; // will convert the analog input to a temperature in celcius
  Serial.print((byte)tempC); //will output the converted temperature to pc
  Serial.println("02");  //xbee 2
  
  voltage = analogRead(flamePin);
  voltage = (5.0*voltage)/1023.0;
  Serial.print("0");
  Serial.print((byte)voltage);
  Serial.println("04"); //flame sensor from xbee2
  
      
    

////////////////////////////////////////////////////////////    
  
  if (tempC>34)  //overtemp
  {
     if (voltage <= 3)  //there is flame and temp >40, give fire alert!
     {
    digitalWrite (red1, HIGH);  //overtemp 
    digitalWrite (yellow1, LOW);  //overtemp     
    digitalWrite (red, HIGH);  //flame detected
    digitalWrite (buzzer, HIGH); //give alert
    }
    else  //temp>40, but no flame, possibility of false alarm
    {
    digitalWrite(red, LOW); //RED led, no flame alert
    digitalWrite (yellow1, LOW);  //overtemp 
    digitalWrite (red1, HIGH);  //high temp alert
    digitalWrite (buzzer, LOW);   //no alert   
    }
 

  }    
 ////////////////////////////////////////////////////////////// 
  
  
  else if ((tempC > 30) && (tempC <= 34))  //warning temp range
 {
  if (voltage <= 3)  //there is flame and temp n warning range
     {
    digitalWrite (yellow1, HIGH);  //warning on 
    digitalWrite (red1, LOW);  //overtemp off
    digitalWrite (red, HIGH);  //flame detected
    digitalWrite (buzzer, HIGH); //give alert
    }
    else  //warning temp, but no flame, possibility of false alarm
    {
    digitalWrite(red, LOW); //RED led, no flame alert

    ///////////////////////////// yellow1 start blink

    unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis > interval) 
  {
    // save the last time you blinked the LED
    previousMillis = currentMillis;  

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

    // set the LED with the ledState of the variable:
    digitalWrite(yellow1, yellow1State);
  }


    ////////////////////////////////
    digitalWrite (red1, LOW);  //overtemp 
    digitalWrite (buzzer, LOW);   //no alert   
    }

}    
    else  //not in warning range and no flame
    {
    digitalWrite(red, LOW);  //RED led, no flame alert
    digitalWrite (yellow1, LOW);  //YELLOW led, no high temp alert    
    digitalWrite (red1, LOW);  //overtemp 
    digitalWrite (buzzer, LOW);   //no alert
    }
  

  delay(3000);
}

PaulRB:
I do not see any code there for testing if 3 seconds has passed and it is time to read your sensors again.

Sorry sir, what you means? I have delay at the last line "delay(3000)" in the main loop to read sensor every 3s.

The reason PaulRB suggested using "blink without delay" is that the delay() function holds up the program for the length of the delay. No other processing gets done! So while your code is in the delay(3000), it cannot blink the LED.

You need to remove the delay(3000) and add code to measure 3 seconds using the same technique as flashing the LED. Then check your sensors each time the 3 seconds ends.

Sorry sir, what code should I add to replace the delay(3000)?

yee0722:
I don't want to delete the delay in main loop.. :~

Why?

If you must keep that delay, you could replace your 3s delay with a loop that repeats 15 times. Inside the loop, swich your led on, delay for 100ms, switch your led off and delay another 100ms.

ok sir, I know what you means.. i need do something on the main loop to read the sensor every 3s without using delay. Can you give me some hints on how to modify my sketch?

Can you give me some hints on how to modify my sketch?

In the IDE there's an example called "blink without delay".
Read it, play with it, understand it.
And don't be blinkered by the word "blink" - the action could be anything.

yee0722:
Can you give me some hints on how to modify my sketch?

I already did in my second post above.

Please don't call me sir...

ok. thank you so much! I did it. I will upload my sketch after finish edit. Thanks again for helping.

//declare variables
const int buzzer  = 5;
const int yellow1 = 3;      // warning temp
const int ovr_tmp = 4;      // overtemp 
const int flm_ind = 2;      // flame led indicate flame

float tempC;
float voltage;
int tempPin =0;             // Temp sensor plugged analog pin 0
int flamePin= 1;

int warnState    = LOW;     // initialise the LED
int ovr_State    = LOW;
int flm_State    = LOW;
boolean _warning = false;   // condition reports
boolean _ovr_tmp = false;
boolean _flame   = false;

unsigned long warn_cnt = 0; // will store last time LED was updated
unsigned long over_cnt = 0;
unsigned long flame_cnt = 0;
unsigned long poll_cnt = 0; // Last time sensors polled


// Have we completed the specified interval since last confirmed event?
// "marker" chooses which counter to check 
boolean timeout(unsigned long *marker, unsigned long interval) {
  if (millis() - *marker >= interval) { 
    *marker += interval;    // move on ready for next interval
    return true;       
  } 
  else return false;
}


// write setup function 
void setup()
{
  Serial.begin(9600);// open serial port to communicate with the temp sensor
  pinMode (ovr_tmp, OUTPUT);
  pinMode (yellow1, OUTPUT);  
  pinMode (flm_ind, OUTPUT);
  pinMode (buzzer,  OUTPUT);

}

//write loop that will control what we want the arduino to do with the sensor readout

void loop()
{
  if (timeout(&poll_cnt, 3000UL )) {  // Execute each 3 seconds
    tempC = analogRead(tempPin);      // taking the temp pin reading and setting it equal to tempC variable
    tempC = (5.0*tempC*100.0)/1024.0; // will convert the analog input to a temperature in celcius
    Serial.print((byte)tempC);        // will output the converted temperature to pc
    Serial.println("02");             // xbee 2

    voltage = analogRead(flamePin);
    voltage = (5.0*voltage)/1023.0;
    Serial.print("0");
    Serial.print((byte)voltage);
    Serial.println("04");             // flame sensor from xbee2

    ////////////////////////////////////////////////////////////    
    if (tempC>34)  // over temp
    {
      if (voltage <= 3)              // there is flame and temp >40, give fire alert!
      {
        _flame = true;               // flame detected
        digitalWrite (buzzer, HIGH); // give alert
      }
      else                           // temp>40, but no flame, possibility of false alarm
      {
        _flame = false;              // no flame detected
        digitalWrite (buzzer, LOW);  // no alert
      }
      _ovr_tmp = true;               // over temp 
      _warning = false;              // not required     
    }    

    ////////////////////////////////////////////////////////////// 
    else if ((tempC > 30) && (tempC <= 34))  //warning temp range
    {
      if (voltage <= 3)              //there is flame and temp in warning range
      {
        _flame = true;               // flame detected
        digitalWrite (buzzer, HIGH); // give alert
      }
      else  //warning temp, but no flame, possibility of false alarm
      {
        _flame = false;              // no flame detected
        digitalWrite (buzzer, LOW);  // no alert   
      }
      _ovr_tmp = false;              // not strictly over temp 
      _warning = true;               // give warning
    }    
    else  //not in warning range and no flame
    {
      _flame = false;                // no flame detected
      _warning = false;              // no panic
      _ovr_tmp = false;              // not over temp 
      digitalWrite (buzzer, LOW);    // no alert
    }

  } // End 3 second procedures

  // Perform the indications
  if (timeout(&warn_cnt, 2000UL )) {
    if (_warning) {
      if (warnState == LOW) warnState = HIGH;
      else warnState = LOW; 
    }
    else warnState = LOW;
    digitalWrite(yellow1, warnState);
  } 

  if (timeout(&over_cnt, 1000UL )) {
    if (_ovr_tmp) {  
      if (ovr_State == LOW) ovr_State = HIGH;
      else ovr_State = LOW; 
    }
    else ovr_State = LOW; 
    digitalWrite(ovr_tmp, ovr_State);
  } 

  if (timeout(&flame_cnt, 400UL )) {
    if (_flame ) {    
      if (flm_State == LOW) flm_State = HIGH;
      else flm_State = LOW; 
    }
    else flm_State = LOW;
    digitalWrite(flm_ind, flm_State);
  } 
}

You may wish to alter the blink times I have picked. :smiley:

FIrst, this is sooooo awesome! Thank you so much help me make my project look much better!

I still very much to learn in Arduino. Thank you again!

So I would really appreciate it if you could tell me how you fare with that code.

I presume you have your rig already set up to test it; I am reasonably sure about the parts I have put in, but don't know how the parts to do with your Xbee and such work. :smiley:

Yess I tested it and it works perfect. haha. The XBee that I set is just an offset to be differentiate between two Xbee in Labview..

The code you written is much advanced for me. :smiley: Seems I need dig some coding book to understand more. :slight_smile: