Go Down

Topic: Fade LED in & out without interruptions ? (Read 821 times) previous topic - next topic

Pauly

Hi- Another newbie question.
I want to do 2 things at once and a looking for the best wayto do this.

I have a program that gets a reading and prints it to an LCD screen.  There is then a delay so the screen can be read before it is cleared.  The process then repeats itself.

While this is going on I want to have an LED lit, to indicate everyhting is working.  I want to fade the led in and out usingthe code below.  

How do I make the LED continually fade in and out without being interrupted bythe rest of the program, such as the delay for the screen to be read?

Is this something called an interrupt?

void loop()
{
 for(value = 0 ; value <= 255; value+=5) // fade in (from min to max)
 {
   analogWrite(ledpin, value);           // sets the value (range from 0 to 255)
   delay(30);                            // waits for 30 milli seconds to see the dimming effect
 }
 for(value = 255; value >=0; value-=5)   // fade out (from max to min)
 {
   analogWrite(ledpin, value);
   delay(30);
 }  
}

MikMo

The problem is that the Delay() function is a blocking function. The processor can't do any work as long as it is in the delay function. So if you use a Delay(30) call no other parts of your program can run for those 30 mS.

Check this tutorial http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay for a possible workaround.

Grumpy_Mike

Just to add to what MikMo said, this sort of technique is known as a state machine. Which basically means you write the program or routine so that it is called and will quickly return. If a delay is needed it checks a timer to see if the time has passed if not it returns, if it has it does the next bit or state. Normally a state variable is used to keep track of where you are in the process and the function uses a case statement to funnel it into the correct section.
If you write all your functions like this then the main loop just calls them one after another and they all appear to be running at once.

It's a bit difficult to get your head round at first but is the basis of most embedded techniques where you want to make several processes appear to happen at once. Of course wimps use real time operating systems to do this.

Oracle

Quote
Of course wimps use real time operating systems to do this.


Hey now, last time I used a real time operating system, I wrote the operating system first (for amd 486 hardware).  

mem

Quote
Quote
Of course wimps use real time operating systems to do this.


Hey now, last time I used a real time operating system, I wrote the operating system first (for amd 486 hardware).  


Writing the operating system is cool.  Its using one that's wimpy  :D

Pauly

Thanks guys.  Here is my code.
I have put the fading led as the continually running code with checking for the temp as a sort of subroutine.  It should now continually fade the led in and out while periodically checking for the temperature. Did I get this right?


// LM35 Temperature Sensor and LCD 

#include <LCD4Bit.h>                                                                   // use of LCD4Bit library
                                                                             //create object to control an LCD.  
                                                                       //number of lines in display=2
LCD4Bit lcd = LCD4Bit(2);                                                       // create object to control an LCD # of lines in display=2

int inPin = 5;                                  // select the input pin for analog temp value
int inVal;                                     // integer value for input read from sensor
int i;
int samples[8];                                    // variables to make a better precision
long interval=4000;
long previousMillis =0;

void setup() {
 pinMode(13, OUTPUT);                                                              // set LED pin
 digitalWrite(13, HIGH);                                                       // light the  LED
 Serial.begin(9600);                             // set up Serial library at 9600 bps
 lcd.init();                                                                   // initialize LCD
 lcd.printIn("Welcome to my" );
 lcd.cursorTo(2, 0);                                                              // move cursor to line 2 position 0
 lcd.printIn("secret lab");
 delay(3000);
}

void loop()
{
 for(value = 0 ; value <= 255; value+=5) // fade in (from min to max)
 {
   analogWrite(13, value);           // sets the value (range from 0 to 255)
                                     // waits for 30 milli seconds to see the dimming effect
 }
 for(value = 255; value >=0; value-=5)   // fade out (from max to min)
 {
   analogWrite(13, value);
   
 }  


     void TempTake()
     {  
      if (millis() - previousMillis > interval) {
                               previousMillis = millis();
           for(i = 0;i<=7;i++){                      // gets avg of 8 samples of temperature
            samples= ( 5.0 * analogRead(inPin) * 100.0) / 1024.0;
            inVal = inVal + samples;
            }
             inVal = inVal/8.0;                  
             lcd.clear();
             char buf[12];                                                             // "-2147483648\0" set buffer for itoa
             lcd.printIn(itoa(((inVal * 9)/ 5 + 32), buf, 10));        
             lcd.printIn(" Fahrenheit");
             lcd.cursorTo(2, 0);                                  // move cursor to line 2 position 0
             lcd.printIn(itoa((inVal), buf, 10));            // convert to string
            lcd.printIn(" Celsius");                                    lcd.leftScroll(20, 30);      // scroll dis 20 chars to left, delaying 30ms each
            inVal = 0;                                                 
           }
     }
}

Grumpy_Mike

Quote
Did I get this right

Sorry no.
You are fading in and out very quickly and then taking the temperature. It's not being done at the same time.

You need to write it so that loop() finishes very quickly and just calls the temperature reading, display and fade each time round.
Then in these routines you need to implement the a state machine for each process.
The state machine in the fade routine should check the timer and if 30mS has elapsed do an analogue write with the new value and set the time for the next update to the current time plus 30mS. If the timer has not elapsed then just exit the routine.

Go Up