• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

LED candle effect using PWM

Status
Not open for further replies.

MrDEB

Well-Known Member
yes I have looked at the one on the mondo site.
all it does is turn the leds on n off .
no big deal but it dosn't flicker like a real candle
I looked and pasted the PWM code from swordfish but keep hanging up on start1 or ??
need to investigate further.
my idea is to use a random num gen in conjunction with PWM
saw a video of an array of 12 LEDs that fade from 100% to 0% and back.
copied n pasted and it hanges up on the START1()
will post code later.
I am worried why my timer hasn't timed out yet?? another project.
 

3v0

Coop Build Coordinator
Forum Supporter
yes I have looked at the one on the mondo site.
all it does is turn the leds on n off .
no big deal but it dosn't flicker like a real candle.
I see this on the Mondo site:
The brightness of the lamp is controlled by doing PWM (pulse width modulation) of the power to the lamp. A random number generator controls the flickering amplitude.
 

MrAl

Well-Known Member
Most Helpful Member
Hi,

You can make a candle simulator pretty nice with a bi color LED, green and red.
When green and red mix they make amber. A real candle has somewhat constant
intensity, but the physical position of the flame varies. By using a bi color LED
with two dies inside and a frosted lens, when the PWM remains around 100 percent
(sum of both LEDs) the intensity shifts from the red to the green, then back again
according to a random number calculation. As the modulation shifts, the position
of the light source actually truely shifts too and so gives the impression that a
flame is dancing around inside the LED.
I would imagine that this would also work with one green LED and one red LED,
inside of a small enclosure shaped maybe like one of those flame shaped
incandescent bulbs, with a frosted outside coating to diffuse the light.

I actually built one of these just as a test to see how the (then board sized)
microcontroller board was working. It's amazing how when you look at it it
gives you the distinct impression that you are looking at a small candle flame.
It even makes you feel like it is too hot to touch, and may even fool you into
thinking it is actually warm when you touch it. It's an amazing illusion if done
right. If i remember right, the PWM is gradually shifted from the red to the
green, then back again, but the total intensity is also varied a little, from
maybe 100 percent down to 50 percent, but not too low as to blank out the
light totally. Also, 100 percent green or 100 percent red is never allowed,
so the limit is maybe something like 80 percent for any one LED.
You could try different limits to see what looks the most realistic.
 
Last edited:

be80be

Well-Known Member
yes I have looked at the one on the mondo site.
all it does is turn the leds on n off .
no big deal but it dosn't flicker like a real candle
A Led don't make a good flicker A red green Like MrAI said could or a RGB but one led just dims
you have to change color for a flicker.
He using a 6.3 volt lamp
Where the led
 
Last edited:

MrDEB

Well-Known Member
that is my plan a bi-colored led

or just a red and maybe a blue.
the leds are going behind an obscure yellow glass
looking from the front= yellow obscure glass, 1/2inch space w/ LEDs in bottom of opening, a mirror.
there are two windows (2"x5") on an 8 sided octagon box.
has two doors in front.
sides made of English walnut with each corner with hard maple inlay to accentuate the corners
bottom and top to be star burst pattern (walnut and maple)
when I get it done will post pics
just want to simulate a burning flame and the "flame" controlled by a photo transistor. only on at dark.
 

MrDEB

Well-Known Member
looks easy enought but

I really don't want to buy a crystal and another chip but I need to order some parts anyway.
do you think the code can be converted for the 1320?? and run at 8mhz instead of 20??
I am still trying to figure out a timer.
I thought I had one working (2x be be exact)
been trying to tweek the longdelay code for a 20 minute off/5sec on
in the code I need to add a temp delayms as the LED flashes tooo fast I think and I miss the event.
 

be80be

Well-Known Member
Here MrDeb save the zip and unzip it and open the rgb with swordfish try it out
you can use 3 leds on portb 0to2 any color just to try it use 150ohm resistors for all led pins it's for a 18f1320
 

Attachments

Last edited:

MrDEB

Well-Known Member
making progress??

want to change ms for each color so I used ms() but keep getting an error on the ms() dim syntax
Code:
Device = 18F1320
Clock = 8

Include "IntOSC8.bas" 
Include "RandGen.bas"
Include "Utils.bas" 
Dim TMR2IE As PIE1.1,         // TMR2 interrupt enable
    TMR2IF As PIR1.1,         // TMR2 overflow flag
    TMR2ON As T2CON.2,        // Enables TMR2 to begin incrementing
    Signal_Pin As PORTA.0     // Signal output to frequency meter
 
Dim Red_Pin As PORTB.0,
    Green_Pin As PORTB.1,
    Blue_Pin As PORTB.2,
    Red_Duty As Byte,
    Green_Duty As Byte,
    Blue_Duty As Byte,
    Red_DutyVal As Byte,
    Green_DutyVal As Byte,
    Blue_DutyVal As Byte,
    RandomVal As Byte
 
Dim uS As Word,
Dim mS() As Word  
//dim mSb As Word 
//dim mSg As Word          
 
Interrupt TMR2_Interrupt()
    High(Signal_Pin)
    Save(0)                   // Back up system variables   
    If TMR2IF = 1 Then        // Check if the interrupt was from TMR2   
        TMR2IF = 0            // Clear the TMR2 interrupt flag
        uS = uS + 50
        If uS >= 1000 Then
            uS = uS - 1000
            Inc mS(r)
            IncmS(b)
            IncmS(g)
        EndIf       
        Inc(Red_DutyVal)
        Inc(Green_DutyVal)
        Inc(Blue_DutyVal)
        If Red_DutyVal > Red_Duty Or Red_Duty = 0 Then
            Red_Pin = 0
        Else
            Red_Pin = 1
        EndIf
        If Green_DutyVal > Green_Duty Or Green_Duty = 0 Then
            Green_Pin = 0
        Else
            Green_Pin = 1
        EndIf
        If Blue_DutyVal > Blue_Duty Or Blue_Duty = 0 Then
            Blue_Pin = 0
        Else
            Blue_Pin = 1
        EndIf               
    EndIf                     //
    Restore                   // Restore system variables
    Low(Signal_Pin)
End Interrupt
 
Private Sub TMR2_Initialize()
    TMR2ON = 0                // Disable TMR2
    TMR2IE = 0                // Turn off TMR2 interrupts   
 
    PR2 = 149                 // TMR2 Period register PR2
    T2CON = %00000001         // T2CON 0:1 = Prescale
                              //        00 = Prescale is 1:1
                              //        01 = Prescale is 1:4
                              //        1x = Prescale is 1:16                                 
                              //      3:6 = Postscale              
                              //     0000 = 1:1 postscale
                              //     0001 = 1:2 postscale
                              //     0010 = 1:3 postscale...
                              //     1111 = 1:16 postscale
 
    TMR2 = 0                  // Reset TMR2 Value   
    TMR2IE = 1                // Enable TMR2 interrupts
    TMR2ON = 1                // Enable TMR2 to increment
    Enable(TMR2_Interrupt)
End Sub
 
// Start Of Program...
Low(Red_Pin)
Low(Green_Pin)
Low(Blue_Pin)
Red_Duty = 0
Green_Duty = 2
Blue_Duty = 0
Red_DutyVal = 0
Green_DutyVal = 4
Blue_DutyVal = 0
 
uS = 0
mS = 0
 
RandGen.Initialize(128)       // Initialize the Random Number generator
TMR2_Initialize               // Setup and enable TMR2
 
While True                    // Create an infinite loop
    //RandomVal = RandGen.Rand  // Grab a random number from 0 to 255 
    // Select RandomVal         // Find out what colour to increase/decrease
        //Case 0 To 42
            While Red_Duty < 255
              And Green_Duty < 255
              And Blue_Duty < 255
                mS(r) = 0
                mS(b) = 0
                mS(g) = 0
                Repeat
                Until mS(r) = 19
                And mS(b) = 19
                And mS(g) = 19
                
                Inc(Red_Duty)
                Inc(Green_Duty)
                
                Inc(Blue_Duty)
            
            Wend
       // Case 43 To 84
            While Red_Duty > 0
          And  Green_Duty > 0
         And Blue_Duty > 0
                mSr = 0
                 mSb = 0
                  mSg = 0
                Repeat
                Until mS(r) = 19
                Until mS(b) = 19
                Until mS(g) = 19
                Dec(Red_Duty)
                Dec(Green_Duty)
                Dec(Blue_Duty)
            Wend
       // Case 84 To 127
            //While Green_Duty < 255
            //    mS = 0
             //   Repeat
             //   Until mS = 19
            //    Inc(Green_Duty)
            //Wend
       // Case 128 To 170
          //  While Green_Duty > 0
            //    mS = 0
            //    Repeat
            //    Until mS = 19
            //    Dec(Green_Duty)
           //Wend
       // Case 170 To 212
           // and Blue_Duty < 255
           //     mS = 0
            //    Repeat
            //    Until mS = 19
            //    Inc(Blue_Duty)
           // Wend
       // Case 212 To 255
           // While Blue_Duty > 0
           //     mS = 0
           //     Repeat
            //    Until mS = 19
           //     Dec(Blue_Duty)
         //   Wend
    // End Select           
Wend
I know it isn't pretty but then I don't know what I am doing
am sure there is a shorter way o do the IF THEN statements but at least I got all three LEDs going together (big deal)
suggestions as I want to have each color flicker different from the others
hint = a flickering candle effect other than turning the LEDs on and off
 

MrDEB

Well-Known Member
added an array? but now INC?

the syntax gets hung up on INC ms()
Code:
Dim uS As Word,
    mS(2) as byte  
//dim mSb As Word 
//dim mSg As Word
         
 
Interrupt TMR2_Interrupt()
    High(Signal_Pin)
    Save(0)                   // Back up system variables   
    If TMR2IF = 1 Then        // Check if the interrupt was from TMR2   
        TMR2IF = 0            // Clear the TMR2 interrupt flag
        uS = uS + 50
        If uS >= 1000 Then
            uS = uS - 1000
           
            Inc mS()  [COLOR="Red"]gets hung up here?[/COLOR]
           
        EndIf       
        Inc(Red_DutyVal)
probably should post entire code but the previous post has it all except these changes.
 

MrDEB

Well-Known Member
entire code

Code:
Device = 18F1320
Clock = 8

Include "IntOSC8.bas" 
Include "RandGen.bas"
Include "Utils.bas" 
Dim TMR2IE As PIE1.1,         // TMR2 interrupt enable
    TMR2IF As PIR1.1,         // TMR2 overflow flag
    TMR2ON As T2CON.2,        // Enables TMR2 to begin incrementing
    Signal_Pin As PORTA.0     // Signal output to frequency meter
 
Dim Red_Pin As PORTB.0,
    Green_Pin As PORTB.1,
    Blue_Pin As PORTB.2,
    Red_Duty As Byte,
    Green_Duty As Byte,
    Blue_Duty As Byte,
    Red_DutyVal As Byte,
    Green_DutyVal As Byte,
    Blue_DutyVal As Byte,
    RandomVal As Byte
 
Dim uS As Word,
    mS(2) as byte  
//dim mSb As Word 
//dim mSg As Word
         
 
Interrupt TMR2_Interrupt()
    High(Signal_Pin)
    Save(0)                   // Back up system variables   
    If TMR2IF = 1 Then        // Check if the interrupt was from TMR2   
        TMR2IF = 0            // Clear the TMR2 interrupt flag
        uS = uS + 50
        If uS >= 1000 Then
            uS = uS - 1000
           
            Inc mS()
           
        EndIf       
        Inc(Red_DutyVal)
        Inc(Green_DutyVal)
        Inc(Blue_DutyVal)
        If Red_DutyVal > Red_Duty Or Red_Duty = 0 Then
            Red_Pin = 0
        Else
            Red_Pin = 1
        EndIf
        If Green_DutyVal > Green_Duty Or Green_Duty = 0 Then
            Green_Pin = 0
        Else
            Green_Pin = 1
        EndIf
        If Blue_DutyVal > Blue_Duty Or Blue_Duty = 0 Then
            Blue_Pin = 0
        Else
            Blue_Pin = 1
        EndIf               
    EndIf                     //
    Restore                   // Restore system variables
    Low(Signal_Pin)
End Interrupt
 
Private Sub TMR2_Initialize()
    TMR2ON = 0                // Disable TMR2
    TMR2IE = 0                // Turn off TMR2 interrupts   
 
    PR2 = 149                 // TMR2 Period register PR2
    T2CON = %00000001         // T2CON 0:1 = Prescale
                              //        00 = Prescale is 1:1
                              //        01 = Prescale is 1:4
                              //        1x = Prescale is 1:16                                 
                              //      3:6 = Postscale              
                              //     0000 = 1:1 postscale
                              //     0001 = 1:2 postscale
                              //     0010 = 1:3 postscale...
                              //     1111 = 1:16 postscale
 
    TMR2 = 0                  // Reset TMR2 Value   
    TMR2IE = 1                // Enable TMR2 interrupts
    TMR2ON = 1                // Enable TMR2 to increment
    Enable(TMR2_Interrupt)
End Sub
 
// Start Of Program...
Low(Red_Pin)
Low(Green_Pin)
Low(Blue_Pin)
Red_Duty = 0
Green_Duty = 2
Blue_Duty = 0
Red_DutyVal = 0
Green_DutyVal = 4
Blue_DutyVal = 0
 
uS = 0
mS(0) = 0
mS(1) = 0
mS(2) = 0
 
RandGen.Initialize(128)       // Initialize the Random Number generator
TMR2_Initialize               // Setup and enable TMR2
 
While (True)                    // Create an infinite loop
    //RandomVal = RandGen.Rand  // Grab a random number from 0 to 255 
    // Select RandomVal         // Find out what colour to increase/decrease
        //Case 0 To 42
            While Red_Duty < 255
              And Green_Duty < 255
              And Blue_Duty < 255
                mS(0) = 0
                mS(1) = 0
                mS(2) = 0
                Repeat
                Until mS(0) = 19
                And mS(1) = 19
                And mS(2) = 19
                
                Inc(Red_Duty)
                Inc(Green_Duty)
                
                Inc(Blue_Duty)
            
            Wend
       // Case 43 To 84
            While Red_Duty > 0
          And  Green_Duty > 0
         And Blue_Duty > 0
         mS(0) = 0
                mS(1) = 0
                mS(2) = 0
               
                Repeat
                Until mS(0) = 19
                and mS(1) = 19
                and mS(2) = 19
                Dec(Red_Duty)
                Dec(Green_Duty)
                Dec(Blue_Duty)
            Wend
       // Case 84 To 127
            //While Green_Duty < 255
            //    mS = 0
             //   Repeat
             //   Until mS = 19
            //    Inc(Green_Duty)
            //Wend
       // Case 128 To 170
          //  While Green_Duty > 0
            //    mS = 0
            //    Repeat
            //    Until mS = 19
            //    Dec(Green_Duty)
           //Wend
       // Case 170 To 212
           // and Blue_Duty < 255
           //     mS = 0
            //    Repeat
            //    Until mS = 19
            //    Inc(Blue_Duty)
           // Wend
       // Case 212 To 255
           // While Blue_Duty > 0
           //     mS = 0
           //     Repeat
            //    Until mS = 19
           //     Dec(Blue_Duty)
         //   Wend
    // End Select           
Wend
not pretty but I know I have several bugs in this code
 
Status
Not open for further replies.

Latest threads

EE World Online Articles

Loading
Top