Continue to Site

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.

  • 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.

Using PWM on a 18F13K22

Status
Not open for further replies.
I don't feel picked on as this whole candle project has been very educational BUT I have yet to try out Tumbleweeds suggestion and thats what really bothers me. I commend LittleGhostman on his writing skills and thirst for knowledge. After reading ALL the posts very carefully, YES I failed to put a . on the 4.7volts. Nobodies perfect.
 
And swoosh.....any number of points flew right by without even being noticed....
 
Last edited:
They ere noticed and notes were written down but why rehash as everyone or most everyone expects me to make a comment on everythig discussed and yet I ask a simple question on my schematics posting. I looked over the suggestions from last year but never received a response. So either my schematic posts are good and readable (they look fine on this end) or nobody wants to make a worth while comment. In the past I used a different schematic software then used MS Paint and never had readability issues. Now using Diptrace and INFAVIEW but having issues. Tried most all of the different suggestions made last year and now I get readability issues.
I explained my plan for this candle but keep getting remarks to do it with a higher priced chip. Add to that I pointed out that my maximum sink current is less than 20ma per pin but it keeps coming up about how much current with 3 leds per pin which is not what I described. 3 RGB leds driven off one 20 pin pic with a max of 20ma per pin.
I'm beginning to wonder if people are actually reading what I post. Maybe I need to go deeper with descriptions? with more detailed schematics etc.
 
MrDEB, you might read my post #139 to understand why people are responding more and more negatively to you. When you fail to acknowledge the effort people are making on your behalf they become annoyed. Yes, people expect YOU to take a few moments to read, understand and remark on a post that may have taken 30 minutes or more to compose and proofread.

But, since you are focused on your schematics, may I ask if you actually look at them after you post them? If so, don't you notice the fact that there is not enough resolution to read the text? Below is one of your schematics. Notice the text is a blur.

Below that is a zoomed section of the labels. They can't be made out because you didn't save the image with enough resolution. This has been discussed to death before and I'm not going to discuss it further here.

image.jpg


image.jpg
 
Last edited:
On the schematic posting I am going to change the type font Go from Vector to true type. I think this is what I did in the past but find no reference to it.
After searching high and low on the data sheet I found the PSTRCON register that Tumbleweed referred to in post #129. This has to do with the steering of the PWM output.
If I built any project similar to this then yes I will look at using a different pic.
On the RGB color numeration, YES I am collecting information on this and contemplating just for informational purposes a programmable RGB.
using perhaps a resistor ladder and setting port pins to high impedance. That's another day or year.
 
There is confusion everywhere here!
Mr Deb if I may address one point for you and hopefully clear it up.The chip you have will do a good job of making a candle.
So a new chip isnt needed, However the problem is the way you had in mind of doing the pwm. There are chips that will do exactly what you want to do, and these chips more importantly will do it the WAY YOU want to do the pwm. This is why more expensive chips have been suggested.
In order to achieve your goal with the chips you have, what is needed is a different approach to how the pwm signal is generated.
you could in theory run more Leds from your chip, the 20mA per pin is a sticking point in your mind, To clear it up when you need to drive more than one Led from a software generated pwm signal, you can use a transistor, OR what i would recommend for your project is more simple. All that is needed is to put in the pwm code a line that in pseudo code goes something like this

pin x = pin Y

so when the pwm signal drives a pin high, another pin of your choice is also driven high! that way you do not exceed the pin current, All that is needed is to make sure you stay under the device total current (normally 200mA??).
So infact from one signal you could do

pseudo code

port X = pin Y
in that case you drive 8 pins at the same duty cycle as the main pwm signal pin! no transistor needed, no going over 20mA
I hope this helps you understand better why software pwm with a timer, is most likely the best way for you to now go
 
For your schematics, the issue is that you need to save them with more pixels – it's not a problem with the fonts. I know this was covered before because I installed DipsTrace just to test it out for you. Compare the jaggies on the curved lines in your schematic to one of my schematics here.

Regarding using a transistor vs separate port pins. I'm not trying to rain on your parade, but you have another issue to consider. Yes, a PIC18F-series port pin can source or sink 25 mA. But there's a limitation on how much the chip can source or sink. In addition to the 25 mA limit of a port pin, you have to consider the total current into or out of the PIC. This is listed in the Absolute Maximums section of the data sheet; "absolute maximum" means exactly that – exceed the values listed and the operation of the chip is no longer guaranteed.

I've lost track of your circuit configuration. I think you're sinking current (i.e., supplying V+ to the LED and providing a ground via the port pins), so you may be ok but you need to keep these limits in mind:

Maximum current sunk by all ports: 200 mA

Maximum current sourced by all ports: 70 mA

If you sink 25 mA on 9 port pins, you'll be exceeding the absolute maximum rating of the chip. On the other hand, if you're sourcing current (i.e., supplying V+ from the port pins) you'll be over the limit with just 3 port pins at 25 mA.

image.jpg
 
Last edited:
At least if it starts smoking, It will start to look like a candle :D
 
I tried the pin x = pin y but it didn't output the PWM as I thought it would. Was hoping that it would but it didn't. As I pointed out I really only needed one PWM output per LED but four separate PWM outputs woulds have been nice. I did find the changing the PSTRCON register that Tumbleweed suggested did the trick for outputting the PWM on more than one pin. In this case it was portC.5. I had a hard time locating that registers settings. The PWM section on page 111 and the PSTRCON register settings way over on page 128.
On this project I got adventurous and made some changes to the PWM module, the changes that Tumbleweed suggested and started tinkering with the module on PWM2 and the INTOSC8 module. After experimenting and using suggested changes the dang project runs as desired.
On posting the schematics I am pretty sure I increased the number of pixels but will post another later to see.
On the maximum current output per chip, I am aware of the maximum but using a 25% error factor so I stayed under 150ma sink current level. IF i used all 9 RGB colors at 20ma then we are looking at 180ma BUT the red and Blue colors have less than 20ma each so I am safe from letting the magic smoke get out. Am still adjusting resistors so final values have not been put in stone yet.
 
X=Y is unlikely to be able to output the same as the pwm peripheral. I was talking about in software pwm. Now i am not 100% on this but, the pwm peripheral does it's thing regardless hat the rest of the chip is doing, so you cant really keep up with it, because all kind of stuff get's in the way. But when you use a timer and interrupt then things are different, The timer roll's over and the interrupt fires, Inside the ISR you can then set as many pins high as you want, hence you get pwm all the same on each pin.
Sometimes the pwm peripheral is more trouble than it's worth, Other method's would serve you better at this point. Mr Deb it has got to be worth giving it a try??? Throw the code you have in your doc's folder and start from scratch, I honestly think it would be the quicker route now, and the best effect
 
here is the code I haven't given up on. It uses a timer interrupt routine and not PWM. I was using this on a different pic (18F2420) not the 18F13K22. I also have a code that I used a CONST array and just turned on ports using the bits. It was too strobe like effect. Your correct about the PWM being a pain to use. Am trying to get the right yellow/orange glow, close but no cigar yet. Adjusting the LED resistors to achieve. Getting close but the DUTY in the PWM routine gets in the way. I have a yellow/orange slow flicker but an orange / yellow would be better. The following code is not what I am using at this point.
Code:
Device = 18F2420
Clock = 8

Include "InternalOscillator.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 PORTB.0    // Signal output to frequency meter
Dim Red_Pin As PORTA.2,        //was b.0
    Green_Pin As PORTA.0,      //was b1
    Blue_Pin As PORTA.1,        //was b2
    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 As Word,         
    ranval(1)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 = 255
Green_Duty = 0
Blue_Duty = 0
Red_DutyVal = 0
Green_DutyVal = 0
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
          If  Red_Duty =RandomVal-5
            Then  mS = 0
                Repeat
                Until mS = 19
                And Red_Duty>0
            End If
             
      ' Case 43 To 83
            If Red_Duty > 0
              Then  mS = 0
                Repeat
                Until mS = 20
                Dec(Red_Duty)
            EndIf
           
      'Case 84 To 127
            If Green_Duty =RandomVal-20
              Then  mS = 0
                Repeat
                Until mS = 19
                Inc(Green_Duty)
            End If 
        'Case 128 To 170
            If Green_Duty > 0
              Then  mS = 0
                Repeat
                Until mS = 40
                Inc(Green_Duty)
                DelayMS(5000)
            EndIf
        'Case 171 To 212
          If  Blue_Duty = RandomVal-30
              Then  mS = 0
                Repeat
                Until mS = 19
                Inc(Blue_Duty)
            End If
           
        'Case 213 To 255
            If Blue_Duty > 0
              Then  mS = 0
                Repeat
                Until mS = 20
                  DelayMS(5000)
                Inc(Blue_Duty)
            EndIf
            End Select
      Wend
         
        End
 
Here is the short code I am getting close to good results. Easier to follow what is going on. Code needs several edits IMO as it is a work in progress.
Code:
{
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Candle Code test using PWM
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
}








Device = 18F13K22
Clock = 8

Include "osc1322.bas"
Include "RandGen.bas"
Include "Util1322.bas"

// import PWM module...
Include "PWM2.bas"
Const color(10) As Byte = (100, 70,65, 90,75,95,85, 60, 80, 85)
// local duty variable...
Dim Duty As Byte
Dim x As Word
Dim blue As PORTB.6
Dim red As PORTB.5
Dim chA As PORTC.5
Dim chB As PORTC.4
Dim chC As PORTC.3
Dim chD As PORTC.2
// main program...
pwm.SetFreq(5000)
pwm.Start1
PSTRCON = $07
Output (blue)
Output (red)
Output (chA)
Output (chB)
Output (chC)
Output (chD)
While true

red = 1
blue = 1
For x = 0 To 10
red = 0
Duty = 0
Repeat
pwm.SetDuty1Percent(Duty)
Inc(Duty)
'red = PORTC.5
'blue = PORTC.5
DelayMS(5)
red = 0
Until Duty = color(x)
Repeat
pwm.SetDuty1Percent(Duty)
Dec(Duty)
red = 0
If Duty = 60  Then
blue = 0
DelayMS(500)
blue = 1
Else blue = 1
End If
DelayMS(30)

Until Duty=0
Next
Wend
 
"...but the DUTY in the PWM routine gets in the way...."

That which makes PWM PWM gets in the way? Huh? Never mind – this is simply beyond my ability to comprehend.

image.jpg
 
BUT without the PWM I can't get the nice slow transition of orange to yellow and back again. After trying different set ups, IMO, the PWM code is the way to go. As I stated I haven't given up on any version of coding for a candle flicker.
The timer interrupt tends to look like a strobe light
Using a CONST array and just turning port pins off and on using the CONST array tends to be too strobe like as well
Using the PWM tends to slow down the color transitions and mixes the colors very well.
I was responding to LittleGhosts comment about using PWM
see post #150
 
Maybe what you need to no is like what little G was stating. Software pmw
You don't really need but one timer and let it count and three variables and I would use 30 cents on three fets or npn to drive the LEDs
 
I have re read this thread. And i am now sure of two things, 1) you need or want a RGB candle. 2) You need this fairly quickly now.
The rest I have no idea about, one minuet i think i have it, then the next post I dont!
So lets work with the facts we know.
1) You need a LED RGB candle.
Go here https://www.wire2wire.org/LED_candle/LED_candle.html
1). Download the zip file. actually dont there are several files so to save confusion here is the one you want

It's in ASM, I know nothing about ASM, Also note that it is for another chip. The source file, seems well commented, I dont think it would be difficult, for one the ASM guy's to alter the config for your chip.
Inside the file it also comments on what you can change to alter the effect's, so you can play with it.
There is a video on the site, this will show you how it looks.
There is a 5 channel option, so it will do what you want.
Also there is a pcb board layout! This will give you an idea on the layout, i think though you will have to alter a couple of things, mainly because it is for another chip.
Use this, get your candle going and be happy. You can then play with SF and the candle untill doom's day, but at least if you fail, you will have RGB led candles for your dinner night
Regards
GM11

edit
Just in case the page is down the following is taken from it

"Download the full package (micro code and PCB data) here [LED_candle.zip].

The core of this project is a PIC12F508 which was strictly picked based on cost and availability. This firmware should be easy to port to just about any PIC micro. Code only uses 1 timer, no interrupts, 22 bytes ram, and 369 words of flash.

The core of the firmware is 5 independent 16 bit linear feedback shift registers generating pseudo random bit streams. These bits streams are used to generate both the brightness level and dwell of a given output to approximate the flicker of the candle. Also included in the firmware is a "wind" function that will randomly activate for a random amount of time that switches from the normal bright slow flicker to a dimmer fast flicker just as if there was a wind gust / draft in a room with a candle.

In the firmware source code there is a set of constants near the top that can be used to customize the operation to taste. These include min / max brightness and dwell for both the normal and wind states as well as the wind gust timings.

As stated in the logics and videos there are 2 different populations of this circuit value and premium. Value mode has the minimum parts count and is good for small candles and / or proto boarding. Premium has more parts and allows the brightest and smoothest flickering. (see videos) If using the value build make sure to limit your LED current to 20mA or less per LED and no more than 60mA for all LEDs attached to the micro. For the premium version the only limitation is 200mA per led with no practical group limitations. Even this limitation can be extended with the use of higher power NPN transistors and or LED drivers. Note if building the value version make sure to pull pin 4 of the PIC low instead of high. This sets the outputs to active low instead of high to drive the LEDs directly (else your flicker will be inverted).

Power supply can either be a 5V adapter or a 6V battery pack. 6V is a little over recommended ratings but well under max. Also soon as the batteries start to run down a little it will be well under the 5.5V recommended max. On the topic of batteries the estimated life on a set of 4AA with 5 50mA LEDs is about 5 hours. Will update once I have some testings done. By picking lower power / less LEDs this time can easily be extended. To calculate the LED resistor value use this formula Rled = (Vsupply - Vled)/Iled if this does not result in a exact resistor value (more than likely) round the value up to the next larger resistor. Also water clear LEDs with a narrow (~25deg) seem to work best."
 

Attachments

  • LED_candle.zip
    247.5 KB · Views: 231
There you go MrDEB. The design Ghostman posted uses a total of five LEDs per candle (3 yellow and 2 red) and the results are impressive.

If you duplicate this design exactly, which offers you a fair chance at success, you'll have to build one for each candle. No chaining off one micro.

I can hear you sputtering already... "He doesn't understand I want to keep this CHEAP."

Here's the BOM cost based on 25 individual candles:

1x pre-programmed PIC12F508 $15 for 25 from Digikey (cheaper than I can find on ebay)
1x 100uF capacitor $ 0.03 each at Tayda Electronics (all following parts)
1x 0.1uF capacitor $ 0.10 each (should be cheaper options at Tayda)
5x 2N3904 transistors $ 0.02 each
5x 1k ohm resistors $ 0.01 each
3x Yellow LEDs 5mm $ 0.03 each
2x Red LEDs 5mm $ 0.03 each
5x 82 ohm resistor 5% 1/4W $ 0.01each
1x 4xAA Battery holder $ 0.36 each (splurging on the high cost option)
1x 8 pin dip socket Not needed, but program FIRST

BOM cost bast on 25: $1.44 plus PCB

PCB from Elecrow

Estimating 10 boards per 100mm x 100 mm panel:
10 panels: $24
V-scoring, 10 boards per panel: +$12

Total = $36 for 100 boards, = $0.36 per board


This makes the total cost per candle $1.80

Note: this is the cost for the high power premium version.


You'll pay more than that for Rg-45 jacks and cables to connect your 3 candle design together.
 
$1.80!!!!! i will go find a cheaper option :D thank you for looking at it jonsea. I confess i didn't see the multi led thing, just 5 channel. So it's going to be a bust :( i will search again! God this google is good,it took just over 4 min's to find that page.
 
Jon it can't cost much when you get samples for free lol. Your right it's not that costly I'm not being smart but when a 6 cent part is to much. How can it be to much what he wants is easy to do if you did it the right way. But I guess we don't know what where talking about.
Makes me wonder what I been doing for 30 years lol
 
Would it be worthwhile asking all this, on say the Swordfish Forum? You never know someone might have some code.
Or is there forum like Microchip's?
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top