View Full Version : Smooth LED fading via PWM
HankMcSpank
- 4th September 2011, 16:48
Ok, so I'm dabbling with LEDS...fading an LED smoothly until its completely off is proving to be a little irksome for me.
Up until now, I've been using 8 bit PWM, but now I'm starting to think 8 bit PWM just isn't gonna cut it - why? Becuase even with a duty value of just 1, the LED albeit very dull, is still quite visible...I'd have thought it being switched on only 1/256th of the time would have resulted in a very hard to see LED? (or have I likely got some setting wrong?)
Next...since we all see logarithmically, apparently a linear LED fade will just not do, I found some values on the net for a log fade (256 values), but such relatively lowish resolution makes for some rather large step jumps...
Smooth_fade:
Lookup count1, [ _
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1, _
1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3, _
3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,5,5, 5, _
5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,7,8,8,8,8,8,8,9, 9, _
9,9,10,10,10,10,10,11,11,11,11,12,12,12,13,13,13,1 3, _
14,14,14,15,15,15,16,16,16,17,17,18,18,18,19,19,20 , _
20,20,21,21,22,22,23,23,24,24,25,26,26,27,27,28,29 , _
29,30,31,31,32,33,33,34,35,36,36,37,38,39,40,41,42 , _
42,43,44,45,46,47,48,50,51,52,53,54,55,57,58,59,60 , _
62,63,64,66,67,69,70,72,74,75,77,79,80,82,84,86,88 , _
90,91,94,96,98,100,102,104,107,109,111,114,116,119 , _
122,124,127,130,133,136,139,142,145,148,151,155,15 8, _
161,165,169,172,176,180,184,188,192,196,201,205,21 0, _
214,219,224,229,234,239,244,250,255], duty
return
....how do I work out the log values for say 512 entries or 1024 entries (ok, so this is more a maths question tan a PICBASIC, but I suck at maths!)
sayzer
- 4th September 2011, 17:36
Oter than the math part, I can say two things about some LEDs.
I have regular & cheap 120degree ultra-LEDs and datasheet says they are 15mA. These new era ultra-LEDs are quite bright even at 0.1mA.
Diriving these LEDs with a serial resistor and with PWM may not give you a nice smooth fade effect as they are so much sensitive to current.
So, I would look at their datasheet and see what voltage they are driven.
Then, I would run the PIC at the same voltage, and drive them directly by the pin with no resistor.
Say, the LED is 3.2V, then run the PIC at 3.2V.
This way, you will see the full fade effect.
However, if you are using different LEDs with different voltage levels on the same circuit, you will have to work on the circuit to get the same method work.
Usually, Red LEDs are 2.10V and Green ones are 3.20V (depending on the brand some are up to 3.70V).
If you are using Power LEDs, then the world is completely different.
HankMcSpank
- 4th September 2011, 17:50
These are high brightness blue leds (quoted at about 25mA)
I'm running the PIC at a voltage supply of 3.0Vand driving the LEDs directly from a PIC output pin (ie slightly less than the LED's 3.2 to 3.4V fwd voltage - so as to under drive them a little & protect the PIC - no series limiting resistor...yeah, I know contentious subject!)
With a PWM value of 1 at 8 bits, that oiught to be very dull to the poiunt of not being able to see the LED, bit that's not the case...sure it's dull;, but it's clear that the LED is on...so I'm thinking if I up the number of steps to say 512 or even 1024, then that should allow much more granularity at the lower end of the PWM (where the LED remains rather perky still)
HenrikOlsson
- 4th September 2011, 18:17
So why not turn it off (0% dutycyle) when you want it to be off? Why do want to drive current thru it and NOT have it light up at all?
HankMcSpank
- 4th September 2011, 18:31
So why not turn it off (0% dutycyle) when you want it to be off? Why do want to drive current thru it and NOT have it light up at all?
Because I seek a smooth fade from max brightness through completely off.
What I'm observing is that a duty cycle of 1 seems too discernibly 'on' still (I'd have thought you'd have to get up real close to it at such a duty cycle to see if it is on or not?), the 'jump between 0 & 1 from a brightness perspective, whilst small, is still too big which is why I'm thinking more resolution may help?
(before you think why don't I just try it myself ...well, firstly I want to ask others if when using 256 steps of pwm, whether a duty value of 1 normally easily visibly shows the LED to be on.....and secondly, I've got to wrap my head around 10 bit HPWM bit mapping - the pesky registers are spread a little).
HankMcSpank
- 4th September 2011, 19:09
Just to give you a flavour, this is a duty setting of 1...
http://img705.imageshack.us/img705/4909/ledsc.jpg (http://imageshack.us/photo/my-images/705/ledsc.jpg/)
Now LED3 & LED6 happen to be faulty (I can't be bothered to swap them out right now - they're way duller than others and clearly have an issue), but I reckon with a duty cycle value of 1 the led brightness should actually be more their level!
Now LEDS are notoriously difficult to photograph...the LEDS don't actually as bright as they do in the photo 'in the flesh', and these being high brightness have a lens that accutely magnifies any LED light but nevertheless I think they're too bright for a duty value of 1!
HenrikOlsson
- 4th September 2011, 19:54
Ah, I misunderstood - again...
Yes, more resoultion might help but I honestly think the problem is the lack of current limiting resistors. Can you just give it a try, something lowish like 47ohms or so.
/Henrik.
HankMcSpank
- 4th September 2011, 21:16
Hi Henrik,
As you can see, the board I'm working on a pcb I knocked up ....so a bit of hacking involved, but I'll give your suggestion a go tomorrow....I've just tried 9 bit PWM which was better but a duty value of 1 is still too visible.
To my other question - does anyone know how to turn 512 linear values into log values (so I can put them in a LUT)
cncmachineguy
- 5th September 2011, 01:05
Hank, how fast is the "1" pulse hitting the LED? think of it this way, what is the duration of that single pulse? at what value does the LED max out to the eye? I don't think the issue is number of steps, but rather the duration of the step.
HankMcSpank
- 5th September 2011, 07:12
Hi Bert,
I'm using a HPWM frequency of 31.25KHZ (8Mhz clock & HPWM PR2 value of 63), so I'm figuring a duty value of 1 should only result in a pulse width of approx 125ns ?
Ioannis
- 5th September 2011, 07:56
1. Bright LEDs light even with nA current. I had a 5 meter LED stripe that some of the LEDs were ON while not connected to any power source!!! (Yeah, from static charge).
2. LEDs are not like lamps, so you cannot control them by a simple PWM idea. LEDs are current dependant devices so, you have to control them by current source and NOT by voltage as you do now.
My suggestion is not to bother with more resolution an try to control, by PWM, the current of the LEDs. Then you will have the exact same effect like simple filament lamps.
Ioannis
HankMcSpank
- 5th September 2011, 14:16
1. Bright LEDs light even with nA current. I had a 5 meter LED stripe that some of the LEDs were ON while not connected to any power source!!! (Yeah, from static charge).
I reckon this is the issue here....high brightness leds, with a lens that intensifies even the smallest amount of light = looks too 'on' even when almost off!
LEDs are not like lamps, so you cannot control them by a simple PWM idea. LEDs are current dependant devices so, you have to control them by current source and NOT by voltage as you do now.
Yeah, I know led's are current driven devices, but what gives...if the rated forward voltage is say 3.4V, but I run them at 3.1V regulated (because they yield sufficient brightness even at that voltage level)..then PWM principles ought to work fine (in fact, PWM does work just fine without the resistor...I'm running it here now!)....& there's always the internal series resistance of the PIC OP pin (5 ohms? not a lot, but resistance nevertheless)
Ioannis
- 5th September 2011, 21:22
For this specifically LED it might work and as long as the voltage is absolutely stable.
But I insist on using a current source. You will be able to control the brightness for a really 0 to 100%.
Even for a test it is interesting.
I have a client that for more than a year is refering to his power (chinese) LEDs as 24Volts... And I reply with the current of your LEDs is....
Ioannis
HankMcSpank
- 8th September 2011, 19:52
Just going off tack a little (still intend breadboarding this up so I can easily inster leds to suit - but for now stuck with my PCB).
I want the PIC pins to sink surrent, therefore I rejigged everything to have all the LED cathodes pointing at the pin, with all the anodes commoned and a P channel mosfet switching 3.2V to the anodes (via HPWM on the mosfet gate).
Something took me aback a little, with a duty value of 255, my leds were still *just* lit (remember we are talking reverse now, so a value of 255 is essentially 0), I changed the duty value to 256 & then the leds switched off ...therefore for all I thought I was using 8 bit/256 values (PR2=63 @8Mhhz, no pre/post ) I was actually using 257 values (and therefore a value 0f 255 sorta equalled 1)...this sucks cos obviously 257th value needs 9 bits! Now I know 255 is almost 256 so as not to worry that much....but is there any way of setting up the HPWM so that 100% duty = 255 exactly?
(BTW I've since inverted the PIC's HPWM ouput so now a value of 0 = the supply voltage & 255 = 0, which has solved my problem of the LEDs not totally extinguishing at a value of 255)
HenrikOlsson
- 8th September 2011, 20:59
Hi Hank,
I would think PR2=64 would make the resolution an even 8 bits, have you tried that?
/Henrik.
HankMcSpank
- 8th September 2011, 21:12
No I haven't tried it, but according to Mr E's multicalc, a PWM PR2 value of 64 yields @8Mhz gives 259 steps, with a value of 258 yielding a duty of 99.23%
Unless I'm missing something obvious (highly likely!), I'd have thought it'd be simpler to set a HPWM PR2 number that gives exactly 256 steps (therefore a max duty value of 255)
HenrikOlsson
- 9th September 2011, 06:29
Hi Hank,
Hmm, you might be right. It just seems that a PR2 of 64 would be more "even" since 64*4=256. On the other hand, 63 is 111111 in binary and if we stick the two lower counter bits to that we 11111111 which is 255 and then a dutycycle value of 255 "should" be 100%.
You are "splitting" the dutycycle value, putting the 6 high bits in CCPR1L and the two low bits in CCP1CON.5 and .4 right?
/Henrik.
HankMcSpank
- 9th September 2011, 08:57
Hi Hank,
You are "splitting" the dutycycle value, putting the 6 high bits in CCPR1L and the two low bits in CCP1CON.5 and .4 right?
Yes I am. Here's what I'm seeing...
PR2 = 62 ....... 253 is final value (giving 254 steps ....0-253 etc)
PR2 = 63 ....... 256 is final value (giving 257 steps)
PR2 = 64 ....... 260 is final value (giving 261 steps)
I'm rather surprised that there's no obvious HPWM setting which would give exactly 256 steps (0-255), but I guess for most, 255 is as near 256 so as not to worry so a setting of PR2=63 should suffice.
Charlie
- 9th September 2011, 11:31
1. Bright LEDs light even with nA current. I had a 5 meter LED stripe that some of the LEDs were ON while not connected to any power source!!! (Yeah, from static charge).
Static charge is by nature static and won't power LEDs. Do you have a wireless router? There is a known issue with early LED Christmas lights illuminating by acting as rectifying antennae. I have a set - turn off my wireless router and they extinguish. Of course, you might live next door to a ham operator as well... but walking across the carpet won't do it.
Charlie
- 9th September 2011, 11:54
Counting from 0 to 255, with the LED on from 0 to 1 then off from 1 to 255 should work nicely, and extending to 512 should make it dimmer yet, I agree. I'd use resistors, but what you are doing "should" work too. The only part of what you are doing that is different from what I've seen work in the past is having the fundamental of the cycle at 32 KHz. It might work, but I've had issues in the past trying to switch LEDs too fast - you might want to drop that down to a couple hundred Hz. But like most of the suggestions, this is only a guess.
HankMcSpank
- 9th September 2011, 12:16
Counting from 0 to 255, with the LED on from 0 to 1 then off from 1 to 255 should work nicely, and extending to 512 should make it dimmer yet, I agree. I'd use resistors, but what you are doing "should" work too. The only part of what you are doing that is different from what I've seen work in the past is having the fundamental of the cycle at 32 KHz. It might work, but I've had issues in the past trying to switch LEDs too fast - you might want to drop that down to a couple hundred Hz. But like most of the suggestions, this is only a guess.
The only reason I run the frequency so high, is because the hpwm carrier *always* manages to permeate its way into the guitar signal (remember this is small signal stuff, that gets amplified by the guitar amp!)...so you always end up with an audible whine in the background.....with the hpwm at 31khz, the problem is still there, but only dogs can hear it!
It does all work at the high frequency...I will revisit this value of '1' (out of 256 vlaues) 'being a bit too bright' issue....but not until my next breadboard session.
HankMcSpank
- 12th September 2011, 19:54
so I'm running out of program memory, I'm presently using the subroutine below to lookup a counter value (count1 below) to get a preset hpwm value (duty)....
Smooth_fade:
Lookup count1, [ _
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1, _
1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3, _
3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,5,5, 5, _
5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,7,8,8,8,8,8,8,9, 9, _
9,9,10,10,10,10,10,11,11,11,11,12,12,12,13,13,13,1 3, _
14,14,14,15,15,15,16,16,16,17,17,18,18,18,19,19,20 , _
20,20,21,21,22,22,23,23,24,24,25,26,26,27,27,28,29 , _
29,30,31,31,32,33,33,34,35,36,36,37,38,39,40,41,42 , _
42,43,44,45,46,47,48,50,51,52,53,54,55,57,58,59,60 , _
62,63,64,66,67,69,70,72,74,75,77,79,80,82,84,86,88 , _
90,91,94,96,98,100,102,104,107,109,111,114,116,119 , _
122,124,127,130,133,136,139,142,145,148,151,155,15 8, _
161,165,169,172,176,180,184,188,192,196,201,205,21 0, _
214,219,224,229,234,239,244,250,255], duty
return
,....now since I've not much program space left , is there any way I can win some room back by for example stuffing the above 256 bytes into EEPROM and then look up the values similar to above? (EEPROM is a bit of a new area to me...I've never had to bother with it before!)
If so....would you be so helpful to put me on the right track? (I'm figuring the 256 bytes will need writing into the PIC at the time of programming it & from thereon afterwards it can be read from EEPROM while the program is running?)
HenrikOlsson
- 12th September 2011, 20:33
Hi Hank,
You use DATA to store the constants to EEPROM at program time. Then you use READ to retreive them at runtime. Something like:
Data 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1, _
1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3, _
3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,5,5, 5, _
5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,7,8,8,8,8,8,8,9, 9, _
9,9,10,10,10,10,10,11,11,11,11,12,12,12,13,13,13,1 3, _
14,14,14,15,15,15,16,16,16,17,17,18,18,18,19,19,20 , _
20,20,21,21,22,22,23,23,24,24,25,26,26,27,27,28,29 , _
29,30,31,31,32,33,33,34,35,36,36,37,38,39,40,41,42 , _
42,43,44,45,46,47,48,50,51,52,53,54,55,57,58,59,60 , _
62,63,64,66,67,69,70,72,74,75,77,79,80,82,84,86,88 , _
90,91,94,96,98,100,102,104,107,109,111,114,116,119 , _
122,124,127,130,133,136,139,142,145,148,151,155,15 8, _
161,165,169,172,176,180,184,188,192,196,201,205,21 0, _
214,219,224,229,234,239,244,250,255
Smooth_fade:
Read Count1, duty
/Henrik.
HankMcSpank
- 12th September 2011, 22:56
Hi Henrik,
Great, many thanks ....simple enough & it works a treat!
Weirdly even though I imported all those values to Excel to check there are 256 entries (there are) - I got an error when I came to compile (stack overflow)....I took one entry out & then it compiled ok. Hey ho....but I just got rid of one of the multitude of 1s in there.
Many thanks....I've a bit more room to "breathe" in my bloaty program again :)
HankMcSpank
- 17th September 2011, 18:24
For this specifically LED it might work and as long as the voltage is absolutely stable.
But I insist on using a current source. You will be able to control the brightness for a really 0 to 100%.
Even for a test it is interesting.
I have a client that for more than a year is refering to his power (chinese) LEDs as 24Volts... And I reply with the current of your LEDs is....
Ioannis
If my calculations are right, when sinking current, my 16f1828 is working out at about 52 Ohms of series resistance per pin - now whether the resistance comes by way of a resistor, or the resistive properties of the silicon inside the PIC IO driving circuitry...resistance is resistance?
V Supply = 3.268V
V drop measured across blue LED = 2.931V
remianing V drop across PIC pin = 3.268V-2.931V = 0.337V
Current through LED (inferred by measuring current into whole circuit - 11 LEDS - then taking a little off (3mA for the PIC) & dividing by 11 = 6.4mA
Resistance of PIC pin R = V/I =....or 0.337V/0.0064A = 52.65 Ohms.
So why not simply treat the PIC's pin as a series 52 ohm resistor for the purposes of LED current calculations? (ie what am I missing?)
HankMcSpank
- 20th September 2011, 00:40
So if I want to store a (ser defined) setting that will remembered after the battery/power source has been removed from the PIC ..is EEPROM is my only option?
If so, I have a problemette...I presently have 256 bytes that already goes into EEPROM at program time..
Data 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1, _
1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3, _
3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,5,5, 5, _
5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,7,8,8,8,8,8,8,9, 9, _
9,9,10,10,10,10,10,11,11,11,11,12,12,12,13,13,13,1 3, _
14,14,14,15,15,15,16,16,16,17,17,18,18,18,19,19,20 , _
20,20,21,21,22,22,23,23,24,24,25,26,26,27,27,28,29 , _
29,30,31,31,32,33,33,34,35,36,36,37,38,39,40,41,42 , _
42,43,44,45,46,47,48,50,51,52,53,54,55,57,58,59,60 , _
62,63,64,66,67,69,70,72,74,75,77,79,80,82,84,86,88 , _
90,91,94,96,98,100,102,104,107,109,111,114,116,119 , _
122,124,127,130,133,136,139,142,145,148,151,155,15 8, _
161,165,169,172,176,180,184,188,192,196,201,205,21 0, _
214,219,224,229,234,239,244,250,255
ok, my first problem is, there's 256 bytes there...which maxes my EEPROM out. (16F1828)
Now assuming i have no other way of storing a user chosen varaiable after the power has been removed (other than EEPROM), THEN I suppose I will need to forsake one of the 256 bytes in that table above ...therefore 255 bytes + 1 byte that the user chooses (& gets stored away when he presses a switch).
But how do I control all of this. In other words if I trim the above from 256 bytes, to 255 bytes to free up one byte of EEPROM space, then the 255 bytes will go straight into EEPROM as it does now ....but how do I store the remaining (user defined) byte in the last available slot of EEPROM?
Sorry for n00by flavour here...but a prolific search didn't yield much that I can digest/apply to this conundrum.
cncmachineguy
- 20th September 2011, 00:58
Hank do you have any code space left?
HankMcSpank
- 20th September 2011, 01:00
Hi Bert,
Yes, it's getting tight, but about 400 bytes left....
cncmachineguy
- 20th September 2011, 01:05
Seems like the easy way out will be to store all or part of your table in code. Maybe that is DAT? Then you have some EEeprom left. Next up, how about compressing that data somewhat. Maybe use 2 bytes for each unique number. Ie
10,1,8,2
So the 10 means there are 10 1's 8 2's and so forth. But since I don't know how you are using the data it's hard to guess at that.
As for writing the user variable to EEPROM, there is a command for that. Can't think ou it off the top of my head.
cncmachineguy
- 20th September 2011, 01:13
Hank, just skimmed over the post and I see I have steered you back to where you were. Sorry for that. How are you usin the data? Maybe we can compress it. Are you using it in order or random access?
gadelhas
- 20th September 2011, 01:27
As for writing the user variable to EEPROM, there is a command for that. Can't think ou it off the top of my head.
Maybe the WRITE command.......
Byte_Butcher
- 20th September 2011, 02:10
I think instead of having 31 consecutive memory locations that contain a "1", I'd just store the first 1 and arrange my code so that when it looks up those locations they all point to the one slot that actually contains the "1".
SteveB
- 20th September 2011, 03:51
How about something like this:
Data 1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3, _
3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,5,5, 5, _
5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,7,8,8,8,8,8,8,9, 9, _
9,9,10,10,10,10,10,11,11,11,11,12,12,12,13,13,13,1 3, _
14,14,14,15,15,15,16,16,16,17,17,18,18,18,19,19,20 , _
20,20,21,21,22,22,23,23,24,24,25,26,26,27,27,28,29 , _
29,30,31,31,32,33,33,34,35,36,36,37,38,39,40,41,42 , _
42,43,44,45,46,47,48,50,51,52,53,54,55,57,58,59,60 , _
62,63,64,66,67,69,70,72,74,75,77,79,80,82,84,86,88 , _
90,91,94,96,98,100,102,104,107,109,111,114,116,119 , _
122,124,127,130,133,136,139,142,145,148,151,155,15 8, _
161,165,169,172,176,180,184,188,192,196,201,205,21 0, _
214,219,224,229,234,239,244,250,255
Smooth_fade:
IF Count1 = 0 THEN
duty = 0
ELSE
IF Count1 < 26 THEN
duty = 1
ELSE
Read Count1-25, duty
ENDIF
ENDIF
RETURN
WriteUserByte:
WRITE 255, UserByte
RETURN
ReadUserByte:
READ 255, UserByte
RETURN
Now you have the upper 25 EEPROM addresses to use. More space could be saved by using similar logic. But this hopefully gets the point across.
Good luck,
Steve
SteveB
- 20th September 2011, 05:01
My math was a little off, the line for the reading of the EEPROM should be
READ count1-26, duty
As a side note, you could make it really simple just by leaving the original table as-is and using this:
Smooth_fade:
IF Count1 = 0 THEN
duty = 0
ELSE
Read Count1, duty
ENDIF
RETURN
WriteUserByte:
WRITE 0, UserByte
RETURN
ReadUserByte:
READ 0, UserByte
RETURN
HankMcSpank
- 20th September 2011, 08:22
Bert.. re putting my table into program memory....it's still a work in progress and with only 400 bytes left...it only takes a couple of debug commands and I'm over the limit :-(
Byte_Butcher ...that's a good lead!
SteveB..... if I'm reading your code right, it's what Byte_butcher proposed? (& is good clawback of EEPROM)
I'll have a dabble later....many thanks for the input.
SteveB
- 20th September 2011, 21:26
SteveB..... if I'm reading your code right, it's what Byte_butcher proposed? (& is good clawback of EEPROM)
Yes, I took the suggestion from Byte_Butcher and fleshed it out a little.
Byte_Butcher
- 20th September 2011, 21:50
I've gotta go stack wood, so this is quickk and needs fixing, but this is the sort of thing I was thinking:
count = count + 1
If count < 33 then address = 1 'all "counts" less than 33 point to address 1
if count < 1 then
address = 0 'unless count is 0. Then it points to address 0
endif
else address = count - 33 'all counts above 33 get offset down so they pick up the sequence starting at address 2
endif
steve
edited to add:
Never mind, Steve B already did it.
HankMcSpank
- 21st September 2011, 17:27
IS there a rapido way of seeing the whole contents of EEPROM?
I'm storing a user determined byte, using this type of way..
DEFAULT_CONFIG DATA 1
default_config_shadow var byte
default_config_shadow = 101010 '
WRITE default_config_shadow, default_config 'write the above to EEPROM
read default_config, default_config_shadow
DEBUG "def_shadow=",BIN default_config_shadow,13,10
then immdeiately afterwards, I lob another 254 bytes into EEprom too...
data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, _
1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, _
2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4, _
4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,7,8,8, _
8,8,8,8,9,9,9,9,10,10,10,10,10,11,11,11,11,12,12,1 2, _
13,13,13,13,14,14,14,15,15,15,16,16,16,17,17,18,18 ,18, _
19,19,20,20,20,21,21,22,22,23,23,24,24,25,26,26,27 ,27,28, _
29,29,30,31,31,32,33,33,34,35,36,36,37,38,39,40,41 ,42,42, _
43,44,45,46,47,48,50,51,52,53,54,55,57,58,59,60,62 ,63,64, _
66,67,69,70,72,74,75,77,79,80,82,84,86,88,90,91,94 ,96,98, _
100,102,104,107,109,111,114,116,119,122,124,127,13 0,133,136, _
139,142,145,148,151,155,158,161,165,169,172,176,18 0,184,188, _
192,196,201,205,210,214,219,224,229,234,239,244,25 0,255
just wondering how that all gets accounted for in EEprom, because I'm sure there's going to be some impact with the way I read that table type data back (eg is my user defined bye stored in EEPROM memory slot0, with the rest filling sequentially afterwards?) I was previously using a counter variable to look up/reference the the data stored in EEprom, but now I'm wondering if I need to offset it by 1? (due to the user stored byte in Eeprom too ....or can I store the one user defined byte at the end of the EEPRM...the last slot)
can I look at EEprom via the Pickit2 (I had a dabble but it wasn't obvious to read!)
Many thanks.
HenrikOlsson
- 21st September 2011, 18:39
Hi Hank,
First off all, it seems as if your WRITE statement is "reversed", you should do WRITE Adress, Value but to me it seems you have it the other way around, ie. writing whatever is in default_config to adress 42 (101010) when I think you actually want the value 42 written to adress 0, or 1 perhaps.
Second, I think (pretty sure) you should be able to read the EEPROM with the PICKit2, I only have a PK3 but if you can't figure it out I'll have a go later. With that said you could dump the EEPROM content over a serial line (if you have one) with something like:
Count VAR BYTE
Result VAR BYTE
For Count = 0 to 255
Read Count, Result
HSEROUT ["EEPROM Location: ", DEC3 Count, ": ", DEC RESULT,13]
NEXT
Third, if the first location in EEPROM (location 0) is reserved for that "userbyte" of data then you should start your DATA table with something like DATA @1, 1, 1, 1... Which will put the first entry at location 1 instead of location 0.
Finally, remeber that DATA isn't something that executes when the program runs, it only tells the compiler/assembler to put that data in the ".hex image" so that the programmer (your PICKit2) can program the values into EEPROM together with the actual program. WRITE, on the other hand is a runtime command and does write to the EEPROM when the program executes.
Hope that helps.
/Henrik.
HankMcSpank
- 21st September 2011, 19:12
A great answer Henrik (good spot on my erroneous write too!)
That was a top heads up wrt ....DATA @1, ""
and goes some way to resolving the confusion I have wrt managing where the written Eeprom data commences being stored! Presumably I can tuck the user defined byte (called default_config) away at the very last slot of eeprom with...
DEFAULT_CONFIG DATA 255
& then place the other 255 bytes below that?
... I'll revisit this after the kids are off to bed, but that was a great reply & gives me plenty to get my teeth into - thanks. (PS I haven't forgot about the DDS stuff you did ...I really want to revisit that as soon as I'm finished this melarkey!)
HenrikOlsson
- 21st September 2011, 19:44
Hi Hank,
No, not really....
Defalt_Config DATA 255
Will store the value 255 at location 0 in EEPROM and give that location the label or name Default_Config. If you want a value to be stored at location 255 you need to use
DATA @255, 42
Or possibly (not clear to me how the label thing it works)
Default_Config DATA @255, 42
and then when the user changes that value you do[code]
userValue VAR BYTE
WRITE 255, userValue
or possibly (still not clear how that "label" works)
userValue VAR BYTE
WRITE Default_Config, userValue
Sorry if I'm confusing you...
/Henrik.
HankMcSpank
- 21st September 2011, 20:14
Ok Henrik...I've just used your 'read the EEprom serially out onto my PC screen' (rather than try to work how to look at the data with the pickit2 itself) - it worked a treat....and certainly alleviates some angst as to "I wonder what's what inside the Eeprom space)
And I was clearly wrong with respect to getting my user defined byte tucked away to slot 255, this is obviously what I needed...
WRITE 255, default_config_shadow
(definitely a case of RTFM!)
Anyway, I've learnt something from this little jaunt - I'm happy :-) (tks Henrik)
Edit: Oops - just seen your reply (was obviously typing mine while you were replying) ...anyway, the penny has dropped here!
SteveB
- 21st September 2011, 21:21
Hank,
Something to tuck away in your cranium while working with the EEPROM: It has a limited number of write cycles.
I can't remember the number of write cycles, but you will NEVER wear it out just by reprograming it. (EDIT: The 18F4620 is rated minimum 100K and typical 1M write cycles)
But you could wear it out if you repeatedly write a value during the operaitons of your code. So only make the WRITE when the user actually changes the vaule.
HankMcSpank
- 21st September 2011, 21:53
Thanks Steve ...fortunately, this is likely to be a one shot selectable option (ie set & forget) - I doubt it'll ever be updated more than a few times.
Charles Linquis
- 22nd September 2011, 00:28
I have to admit that I haven't read all the posts, but I noticed one thing awhile "up". PLEASE don't drive a LED directly from a PIC pin! LEDs are not 'lamps'. LEDs ARE DIODES! It is CURRENT, not voltage that lights them. Since they are a diode, if you put a slowly rising voltage across them, they (at first) draw no current whatsoever. Then, when they get to the diode forward voltage (which is determined by the technology of the LED), all of the sudden, they light. So, you can have no light at all at 2.2V, and burn them up at 2.3V. If a LED with a forward voltage of 2.3V was connected to a 3V source, it wouldn't last long. So why do they work when you connect them directly to PIC pins? It is because the PIC pins have very small FETs driving them, and they have an "effective" resistance. That is, they cannot supply a huge amount of current. This current-limiting allows both the PIC and the LED to survive.
You have seen the LED flashlights that have nothing but white LEDs and 3 - AAA batteries. No resistor. The forward voltage of most white LEDs is between 3.1 and 4V (Wikipedia). The 3 batteries in series produce about 4.5V. It all works because batteries are not perfect power sources, they have an Equivalent Series Resistance (ESR) that acts like a resistor in series with the battery. This ESR allows things to work - kind of. But have you ever noticed that while you expected the LED flashlights to work forever - they don't? They fail because the makers don't put in a little extra resistance in the leads of each LED to balance the LEDs and to control the current.
Back to PICs: The PIC pins outputs are not really resistors. They may act somewhat like resistors, but they are not. The "resistance" of the pin can vary quite a bit over Vcc variations and from device to device and even pin-to-pin. As a result, the results can be unpredictable. Please put a resistor (at least) in series with your LED.
HankMcSpank
- 22nd September 2011, 00:43
The PIC pins outputs are not really resistors. They may act somewhat like resistors, but they are not. The "resistance" of the pin can vary quite a bit over Vcc variations and from device to device and even pin-to-pin. As a result, the results can be unpredictable. Please put a resistor (at least) in series with your LED.
I agree they're not what we'd deem traditional resistors...but for supply of 3.268V to the (blue) LED, I'm seeing 0.337V dropped across the PIC pin - that equates to a series DC resistance in any language. I take your point about variations (though I'm not seeing it pin to pin). So with the PIC pin V drop, that only leaves about 2.95V for the blue LED (with a rated fwd voltage of about 3.2V) ...there's not much chance a blue LED will blow with just 2.95V across it (the current through it is fairly meagre at that voltage level). Fear not, I appreciate your input (& concern), but seriously...this isn't a production run - this is for my own use (& a couple of mates if my project-ette turns out to my liking) ...simply towards learning about PICs & pushing my own (small!) boundaries...I posted up my earlier findings for interest (wrt actual real world IO pin resistance) as opposed to evangelising to others about going 'resistorless'! :)
I do wonder though since 50 ohms is a surprisingly high figure, just how many factor the PIC's pin resistance in when calculating a LED resistor value? (I suspect not many) ...the resistance certainly can't be disregarded becuase certainly with relatively low value resistors normally in play for LEDs, the PIC pin's inherent resistance is gonna severely skew the desired end result.
Charles Linquis
- 22nd September 2011, 02:12
I generally use 2N7002's for driving things like that. They are great, logic-level N-channel FETs that have a pretty low ON resistance. Cheap too.
sayzer
- 22nd September 2011, 05:20
Only if using PWM on a PIC pin , you can directly drive a transistor base without a resistor.
That will save you one component (resistor) and also space on PCB.
If you use Mosfet with PWM, you can also directly drive the gate without resistor. But this time, you need to have a resistor between the gate and GND. This resistor is not needed if not using PWM.
HankMcSpank
- 22nd September 2011, 08:15
I generally use 2N7002's for driving things like that. They are great, logic-level N-channel FETs that have a pretty low ON resistance. Cheap too.
Since I'm sinking current into the pin, I'm using a common (ie shared by all pins) P Channel Mosfet (with something like .2 Ohm 'on' resistance) & inverted PWM on the ECCP module ....it works well.
Ioannis
- 22nd September 2011, 10:35
For any N-Channel small MosFet needs (up to 2A) have a look at the Si2308 too. It is working fine from 4.5 Volts with Rds of 0.192 and Id of 2.1 Amp.
And the best P-Channel Power Mosfet I have find maybe is the SUM110P04-05-E3. Usually the P-channel have high Rds and low Id specs.
Ioannis
HankMcSpank
- 22nd September 2011, 11:06
actually, I was mistaken the RDS of my Mosfet is about 0.7 Ohms.
I bought these P channel Mosfets when CPC Farnell were clearing them out for about 5p each...
http://www.farnell.com/datasheets/468737.pdf
I think I bought about 100 ....I couldn't believe it when they arrived...every Mosfet was sealed individually in a 5cm plastic bag, & then inside the plastic bag, each MOSFET was then sealed in it's SMD wrapping! It takes me more time to get to the mosfet than to make my PCB!
HankMcSpank
- 3rd October 2011, 23:31
Ok, I missing somethinh fundamental here...wondering if anyone can embarrass me!
I'm putting some data into eeprom...
data 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, _
1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, _
2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4, _
4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,7,8,8, _
8,8,8,8,9,9,9,9,10,10,10,10,10,11,11,11,11,12,12,1 2, _
13,13,13,13,14,14,14,15,15,15,16,16,16,17,17,18,18 ,18, _
19,19,20,20,20,21,21,22,22,23,23,24,24,25,26,26,27 ,27,28, _
29,29,30,31,31,32,33,33,34,35,36,36,37,38,39,40,41 ,42,42, _
43,44,45,46,47,48,50,51,52,53,54,55,57,58,59,60,62 ,63,64, _
66,67,69,70,72,74,75,77,79,80,82,84,86,88,90,91,94 ,96,98, _
100,102,104,107,109,111,114,116,119,122,124,127,13 0,133,136, _
139,142,145,148,151,155,158,161,165,169,172,176,18 0,184,188, _
192,196,201,205,210,214,219,224,229,234,239,244,25 0,252
note that last value 252....ok, when I read out the contents of eeprom...
Loc000: 000
Loc001: 001
Loc002: 001
Loc003: 001
Loc004: 001
Loc005: 001
Loc006: 001
Loc007: 001
Loc008: 001
Loc009: 001
Loc010: 001
Loc011: 001
Loc012: 001
Loc013: 001
Loc014: 001
Loc015: 001
Loc016: 001
Loc017: 001
Loc018: 001
Loc019: 001
Loc020: 001
Loc021: 001
Loc022: 001
Loc023: 001
Loc024: 001
Loc025: 001
Loc026: 001
Loc027: 001
Loc028: 001
Loc029: 001
Loc030: 001
Loc031: 002
Loc032: 002
Loc033: 002
Loc034: 002
Loc035: 002
Loc036: 002
Loc037: 002
Loc038: 002
Loc039: 002
Loc040: 002
Loc041: 002
Loc042: 002
Loc043: 002
Loc044: 002
Loc045: 002
Loc046: 002
Loc047: 002
Loc048: 002
Loc049: 002
Loc050: 003
Loc051: 003
Loc052: 003
Loc053: 003
Loc054: 003
Loc055: 003
Loc056: 003
Loc057: 003
Loc058: 003
Loc059: 003
Loc060: 003
Loc061: 003
Loc062: 003
Loc063: 004
Loc064: 004
Loc065: 004
Loc066: 004
Loc067: 004
Loc068: 004
Loc069: 004
Loc070: 004
Loc071: 004
Loc072: 004
Loc073: 004
Loc074: 005
Loc075: 005
Loc076: 005
Loc077: 005
Loc078: 005
Loc079: 005
Loc080: 005
Loc081: 005
Loc082: 006
Loc083: 006
Loc084: 006
Loc085: 006
Loc086: 006
Loc087: 006
Loc088: 006
Loc089: 007
Loc090: 007
Loc091: 007
Loc092: 007
Loc093: 007
Loc094: 007
Loc095: 008
Loc096: 008
Loc097: 008
Loc098: 008
Loc099: 008
Loc100: 008
Loc101: 009
Loc102: 009
Loc103: 009
Loc104: 009
Loc105: 010
Loc106: 010
Loc107: 010
Loc108: 010
Loc109: 010
Loc110: 011
Loc111: 011
Loc112: 011
Loc113: 011
Loc114: 012
Loc115: 012
Loc116: 012
Loc117: 013
Loc118: 013
Loc119: 013
Loc120: 013
Loc121: 014
Loc122: 014
Loc123: 014
Loc124: 015
Loc125: 015
Loc126: 015
Loc127: 016
Loc128: 016
Loc129: 016
Loc130: 017
Loc131: 017
Loc132: 018
Loc133: 018
Loc134: 018
Loc135: 019
Loc136: 019
Loc137: 020
Loc138: 020
Loc139: 020
Loc140: 021
Loc141: 021
Loc142: 022
Loc143: 022
Loc144: 023
Loc145: 023
Loc146: 024
Loc147: 024
Loc148: 025
Loc149: 026
Loc150: 026
Loc151: 027
Loc152: 027
Loc153: 028
Loc154: 029
Lo1155: 029
Loc156: 030
Loc157: 031
Loc158: 031
Loc159: 032
Loc160: 033
Loc161: 033
Loc162: 034
Loc163: 035
Loc164: 036
Loc165: 036
Loc166: 037
Loc167: 038
Loc168: 039
Loc169: 040
Loc170: 041
Loc171: 042
Loc172: 042
Loc173: 043
Loc174: 044
Loc175: 045
Loc176: 046
Loc177: 047
Loc178: 048
Loc179: 050
Loc180: 051
Loc181: 052
Loc182: 053
Loc183: 054
Loc184: 055
Loc185: 057
Loc186: 058
Loc187: 059
Loc188: 060
Loc189: 062
Loc190: 063
Loc191: 064
Loc192: 066
Loc193: 067
Loc194: 069
Loc195: 070
Loc196: 072
Loc197: 074
Loc198: 075
Loc199: 077
Loc200: 079
Loc201: 080
Loc202: 082
Loc203: 084
Loc204: 086
Loc205: 088
Loc206: 090
Loc207: 091
Loc208: 094
Loc209: 096
Loc210: 098
Loc211: 100
Loc212: 102
Loc213: 104
Loc214: 107
Loc215: 109
Loc216: 111
Loc217: 114
Loc218: 116
Loc219: 119
Loc220: 122
Loc221: 124
Loc222: 127
Loc223: 130
Loc224: 133
Loc225: 136
Loc226: 139
Loc227: 142
Loc228: 145
Loc229: 148
Loc230: 151
Loc231: 155
Loc232: 158
Loc233: 161
Loc234: 165
Loc235: 169
Loc236: 172
Loc237: 176
Loc238: 180
Loc239: 184
Loc240: 188
Loc241: 192
Loc242: 196
Loc243: 201
Loc244: 205
Loc245: 210
Loc246: 214
Loc247: 219
Loc248: 224
Loc249: 229
Loc250: 234
Loc251: 239
Loc252: 244
Loc253: 250
Loc254: 252
Loc255: 255
I get 252 as the 2nd to last number....with 255 being the final number (I'm guessing all 1s is a default value of unused eeprom slots?)
therefore there must be just 255 values in that table, but if I add another value on the end (the 256th slot) ...saya number of 253...
data 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, _
1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, _
2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4, _
4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,7,8,8, _
8,8,8,8,9,9,9,9,10,10,10,10,10,11,11,11,11,12,12,1 2, _
13,13,13,13,14,14,14,15,15,15,16,16,16,17,17,18,18 ,18, _
19,19,20,20,20,21,21,22,22,23,23,24,24,25,26,26,27 ,27,28, _
29,29,30,31,31,32,33,33,34,35,36,36,37,38,39,40,41 ,42,42, _
43,44,45,46,47,48,50,51,52,53,54,55,57,58,59,60,62 ,63,64, _
66,67,69,70,72,74,75,77,79,80,82,84,86,88,90,91,94 ,96,98, _
100,102,104,107,109,111,114,116,119,122,124,127,13 0,133,136, _
139,142,145,148,151,155,158,161,165,169,172,176,18 0,184,188, _
192,196,201,205,210,214,219,224,229,234,239,244,25 0,252,253
it won't compile (compiler says stack over flow)
So if there are only 255 values being stored in my eeprom, then why won't it let me squeeze in a byte to the final (256th byte) eeprom slot ...rather than defaulting the final value to 255?
Any ideas?
RossWaddell
- 9th February 2013, 19:42
Only if using PWM on a PIC pin , you can directly drive a transistor base without a resistor.
That will save you one component (resistor) and also space on PCB.
If you use Mosfet with PWM, you can also directly drive the gate without resistor. But this time, you need to have a resistor between the gate and GND. This resistor is not needed if not using PWM.
Hi sayzer - I've been working on driving up to 10 LEDs with a BS170 MOSFET and have connected the PIC pin directly to the gate of the 'FET. I had seen a circuit diagram with a resistor connecting the PIC -> gate to end, but then heard that this wasn't needed. What size resistor should I use?
Ioannis
- 9th February 2013, 20:31
Not necessary to add resistor to Fet gates.
Only if you had bipolar transistors.
Ioannis
RossWaddell
- 10th February 2013, 00:12
Thanks heaps, Ioannis.
Powered by vBulletin® Version 4.1.7 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.