Timer on delay?

hello guys/girls,

I'm having some difficulty understanding the Arduino Uno timer. i have a program right now where it takes a temperature reading and relates it to an LED. If the temperature exceeds 32 a red LED turns on and starts blinking. the part i am stuck on is after 10 seconds of the LED blinking an alarm is supposed to sound. I can get the alarm to sound i just do not know how to go about delaying it 10 seconds. whenever i have tried it it delays my LED flashing too.(under //red LED in code)

any help is much appreciated

Thanks

here is my program:

// constants won't change
const int bluePin = 10;
const int greenPin = 11;
const int redPin = 9;
const int speakerPin = 5;
const int motorPin = 6;
const int temperaturePin = 0;

// Variables will change:
int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0; 
long interval = 100;

void setup ()
{
  pinMode(bluePin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(redPin, OUTPUT);
  pinMode(speakerPin, OUTPUT);
  pinMode(motorPin, OUTPUT); 
  pinMode(temperaturePin, INPUT);
  
  Serial.begin(9600);  //Start the serial connection with the copmuter
                       //to view the result open the serial monitor 
                       //last button beneath the file bar (looks like a box with an antenae)
}
 
void loop()                     // run over and over again
{
 float temperature = getVoltage(temperaturePin);  //getting the voltage reading from the temperature sensor
 temperature = (temperature - .5) * 100;          //converting from 10 mv per degree wit 500 mV offset
                                                  //to degrees ((volatge - 500mV) times 100)
 Serial.println(temperature);                     //printing the result
 delay(500);                                      //waiting a second
 
//blue LED 
    if (temperature <= 20){                              
      analogWrite(bluePin, 127.5);
      analogWrite(greenPin, 0);
      analogWrite(redPin, 0);
      analogWrite(motorPin, 0);
     }
    else if (temperature > 20 && temperature <= 23){
      analogWrite(bluePin, 191);
      analogWrite(greenPin, 0);
      analogWrite(redPin, 0);
      analogWrite(motorPin, 0);
    }
    else {
      analogWrite(bluePin, 255);
      analogWrite(greenPin, 0);
      analogWrite(redPin, 0);
      analogWrite(motorPin, 0);
    }
//green LED    
    if (temperature > 26 && temperature <= 30){  
      if (temperature > 26 && temperature <= 27.3){      
          analogWrite(bluePin, 0);
          analogWrite(greenPin, 127.5);
          analogWrite(redPin, 0);
          analogWrite(motorPin, 127);
           }
       else if (temperature > 27.5 && temperature <= 28.5){
          analogWrite(bluePin, 0);
          analogWrite(greenPin, 191);
          analogWrite(redPin, 0);
          analogWrite(motorPin, 127);
          }  
        else {
          analogWrite(bluePin, 0);
          analogWrite(greenPin, 255);
          analogWrite(redPin, 0);
          analogWrite(motorPin, 127);
        }
  }
//red LED    
    if (temperature > 30 && temperature <= 32){          
      analogWrite(bluePin, 0);
      analogWrite(greenPin, 0);
      analogWrite(redPin, 255);
      analogWrite(motorPin, 255);
     }
    else if (temperature > 32){
      analogWrite(bluePin, 0);
      analogWrite(greenPin, 0);
      
        //led flash     
        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 (ledState == LOW)
        ledState = HIGH;
        else
        ledState = LOW;

        // set the LED with the ledState of the variable:
        digitalWrite(redPin, ledState);
        }
        
  analogWrite(motorPin, 255);
  
  if (temperature > 32){
    beep (200);
  }
  
     
 }
}
void beep(unsigned char delayms){
  analogWrite(speakerPin, 20);      // Almost any value can be used except 0 and 255
                           // experiment to get the best tone
  delay(delayms);          // wait for a delayms ms
  analogWrite(speakerPin, 0);       // 0 turns it off
  delay(delayms);          // wait for a delayms ms   
}
/*
 * getVoltage() - returns the voltage on the analog input defined by
 * pin
 */
float getVoltage(int pin){
 return (analogRead(pin) * .004882814); //converting from a 0 to 1023 digital range
                                        // to 0 to 5 volts (each 1 reading equals ~ 5 millivolts
}

Study the BlinkWithoutDelay example? Using delay() is not compatible with doing two things simultaneously - you don't want the delay for one task to hold up the other - so you don't delay() you check the time everything round the loop(). Each task's code looks out for its own timeouts each time loop() goes round...

I've done more than study it, thats how the LEDs blink in the code.. i just copied and pasted it from that example. I need the alarm to tuen on after 10 seconds of the LED blinking. i have no problem with the LED

for starters, change this...

float temperature = getVoltage(temperaturePin);  
 temperature = (temperature - .5) * 100;         
 Serial.println(temperature);                   
 delay(500);

to this (declare tempdelay as an unsigned long):

if (millis() - tempdelay >= 500){
  tempdelay = millis();
  float temperature = getVoltage(temperaturePin);   
  temperature = (temperature - .5) * 100;         
  Serial.println(temperature);
}

I'm sure you can figure out the rest 8)

Can you explain what is happening when you suggest a change to my program. I have barely been taught this in school, mostly learning as i go even though this is a school project. i do not have a lot of knowledge and an explanation would be appreciated.

i did the change declared the tempdelay as you requested and now temperature is not declared.

"tempDelay" is the timestamp of the last time you printed. You might want to change the name to reflect that -- perhaps "lastPrintTime." So, when you subtract the current time from the last time you printed, you'll get the elapsed time since you last printed. The code then tests to see if the elapsed time is greater than 500, meaning that half a second passed. If it's greater, it prints the variable. Otherwise, it doesn't do anything until the code loops around again so it can check once more.

This really can't be "taught in school," it's all just logic. Understand what each function does (millis(), -, >= and if) and then write it down in english like this:
"If the current time minus the last time is more than 500, print the variables."
Once the syntax leaves and you don't need to stop to remember what everything does, it's all logical.

For the specific error about temperature not being declared, look up variable scope. This is essentially a syntax issue.

Thanks for the explanation, but do i really need to change this part of the code? It works fine the way it was before, i have no problem writing and viewing the temperature

my main goal is to get the alarm on after 10 seconds of the red led flashing

Yes, you do. If you spend your life thinking and concentrating about absolutely nothing but breathing (kind of like your arduino does when you use delay), you'll need to change something that works (breathing) in order to accommodate other activities.

my main goal is to get the alarm on after 10 seconds of the red led flashing

You need to realize that using delay() prevents the arduino from doing anything else. It will not be able to turn on an LED in 10 seconds because it is doing nothing when it's in a delay(). First thing is to get rid of the delay() so the Arduino is available to do something else. Hence my first suggestion...

Once you get that running, write down exactly what you want your program to do. Something like this:

  • when the red LED starts flashing, remember the time
  • Check to see how much time has elapsed since the red LED started flashing
  • if it has been more than 10 seconds since red LED started flashing, turn on buzzer.

You will have to figure out how to determine when the red LED started flashing, instead of when it is flashing.

ok i did what you said and i understand what is going on now. so thank you for the explanation. i have made the changes and have got them to work. I am using the tone() noTone() I/O control.

else if (temperature > 32){
      analogWrite(bluePin, 0);
      analogWrite(greenPin, 0);
      
      //alarm 10 sec delay
      if (millis() - checktime >= 10000){
        checktime = millis();
        tone(speakerPin, 200);
      }

i wrote that //alarm part in my code just under the else if as shown. the only difficulty i am having is that it is delayed by 10 seconds but makes a single beep every ten seconds. but tone() alone makes a solid tone (but has a clicking sound when the LED is blinking)

checktime is declared as unsigned long. i must be missing one simple thing. and i dont know how to check if an LED is blinking (im just going with if the temp is >32 right now)

temp is >32 is the condition that says the LED is on.

What you might do is this -

add another variable like to your variable declarations --

int LEDFlag =0;  LEDFlag = 1

and modify your other code like this -It is a more general purpose approach.
You might want to look at checktime to make sure it is set correctly, and not reset

else if (temperature > 32){
      analogWrite(bluePin, 0);
      analogWrite(greenPin, 0);
      LEDFlag = 1;
    }
    else {
   LEDFlag =0;
   tone(speakerPin, 0);
   }
   if (LEDFlag){
      //alarm 10 sec delay
      if (millis() - checktime >= 10000){
        checktime = millis();
        tone(speakerPin, 200);
       }
   }

i changed the code like you wrote it, there were errors when it was compiled but fixed them. Had to move your code around a bit to make it all work. everything is working right except for the time. does not do a full 10 seconds, only approx 3 max

this is my whole program but the problem lies with the //alarm 10 sec delay i believe

// constants won't change
const int bluePin = 10;
const int greenPin = 11;
const int redPin = 9;
const int speakerPin = 5;
const int motorPin = 6;
const int temperaturePin = 0;


// Variables will change:
int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0; 
long interval = 100;
unsigned long tempdelay;
unsigned long checktime;
long temperature;

void setup ()
{
  pinMode(bluePin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(redPin, OUTPUT);
  pinMode(speakerPin, OUTPUT);
  pinMode(motorPin, OUTPUT); 
  pinMode(temperaturePin, INPUT);
  
  Serial.begin(9600);  //Start the serial connection with the copmuter
                       //to view the result open the serial monitor 
                       //last button beneath the file bar (looks like a box with an antenae)
}
 
void loop()                     // run over and over again
{
 if (millis() - tempdelay >= 500){
  tempdelay = millis();
  float temperature = getVoltage(temperaturePin);   
  temperature = (temperature - .5) * 100;         
  Serial.println(temperature);
                                    //waiting a second
 
//blue LED 
    if (temperature <= 20){                              
      analogWrite(bluePin, 127.5);
      analogWrite(greenPin, 0);
      analogWrite(redPin, 0);
      analogWrite(motorPin, 0);
     }
    else if (temperature > 20 && temperature <= 23){
      analogWrite(bluePin, 191);
      analogWrite(greenPin, 0);
      analogWrite(redPin, 0);
      analogWrite(motorPin, 0);
    }
    else {
      analogWrite(bluePin, 255);
      analogWrite(greenPin, 0);
      analogWrite(redPin, 0);
      analogWrite(motorPin, 0);
    }
//green LED    
    if (temperature > 26 && temperature <= 30){  
      if (temperature > 26 && temperature <= 27.3){      
          analogWrite(bluePin, 0);
          analogWrite(greenPin, 127.5);
          analogWrite(redPin, 0);
          analogWrite(motorPin, 127);
           }
       else if (temperature > 27.5 && temperature <= 28.5){
          analogWrite(bluePin, 0);
          analogWrite(greenPin, 191);
          analogWrite(redPin, 0);
          analogWrite(motorPin, 127);
          }  
        else {
          analogWrite(bluePin, 0);
          analogWrite(greenPin, 255);
          analogWrite(redPin, 0);
          analogWrite(motorPin, 127);
        }
  }
//red LED    
int LEDFlag =0;  LEDFlag = 1;

    if (temperature > 30 && temperature <= 32){          
      analogWrite(bluePin, 0);
      analogWrite(greenPin, 0);
      analogWrite(redPin, 255);
      analogWrite(motorPin, 255);
      LEDFlag =0;
     }
    else if (temperature > 32){
      analogWrite(bluePin, 0);
      analogWrite(greenPin, 0);
      LEDFlag = 1;
     
    
     
     //alarm 10 sec delay
   if (LEDFlag = 1){
      if (millis() - checktime >= 10000){
        checktime = millis();
        tone(speakerPin, 200);
       }
   }
      
     
        //led flash     
        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 (ledState == LOW)
        ledState = HIGH;
        else
        ledState = LOW;

        // set the LED with the ledState of the variable:
        digitalWrite(redPin, ledState);
        }
        
  analogWrite(motorPin, 255);
  
  
   }
 else {
     LEDFlag =0;
     noTone(speakerPin);
     }
 }
}

/*
 * getVoltage() - returns the voltage on the analog input defined by
 * pin
 */
float getVoltage(int pin){
 return (analogRead(pin) * .004882814); //converting from a 0 to 1023 digital range
                                        // to 0 to 5 volts (each 1 reading equals ~ 5 millivolts
}

The Alarm seems to activate at different times whenever the LED starts to flash. I just need help with that timer and im done. Please and thank you

Any help is greatly appreciated as this is due tomorrow. ive been playing around with this thing for hours trying to figure out the problem

Not really checked this code but why have you, in this part of the code

//red LED    
int LEDFlag =0;  LEDFlag = 1;

    if (temperature > 30 && temperature <= 32){          
      analogWrite(bluePin, 0);

got this line

int LEDFlag =0;  LEDFlag = 1;

Why not just

int LEDFlag = 0;

or

int LEDFlag = 1;

or even

int LEDFlag;

in the comments above thats how it was suggested to be declared i have changed it to LEDFlag = 1 or LEDFlag = 0 nothing has worked

it seems to only count for 8 seconds the 1st time its called, after the temperature goes down then back up its hit or miss. could be 8 seconds again, could be instant. i need it for 10 :confused: