Linearizing an LED for 800 pwm steps'?


Closed Thread
Results 1 to 37 of 37
  1. #1
    Join Date
    Mar 2009
    Posts
    653

    Default Linearizing an LED for 800 pwm steps'?

    Hi there...long time no post, dusted my pic stuff down & have dived straight back in....almost out the blocks I'm stumbling - not with the picbasic aspect but maths, logs etc! (knew I should have paid more attention in maths classes!)

    Anyway, I want to fade an LED up & down so it appears linear to the eye ...if I just step the LED linearly, my eye (& I guess everybody elses eyes!), sees the main brightness changes at the lower end of the stepping scale (so for example with 256 bits....the main visual brightness steps happen at the lower end of the range 0-50 ....with less perceivable change in steps as you head on up to 255 bits)....the end result is a lumpy fade up/down.

    Now then, I need to use a PWM frequency of about 20khz (in case you're wondering the LED still seems to react ok at this frequency!) ...this is beacause the LED will be going into an audio circuit & past attempts have proved that the PWM signal bleeds into the signal very easy so low PWM frequencies are out ...the kludge is to put it above the hearing range of most......at 16Mhz, a 20khz signal gives 800 bits of resolution, so what I'm wanting is for some maths savvy person to give me a hint at how I would use a LUT for 800 values in a way that would make the LEDappear to be fading up/down linearly?

    Any ideas?

  2. #2
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    Ok...I think I might be stuffed here! (it won't be the first time!)

    I'm using a lowly 12f1840 (as I need to use a PIC with just 8 pins -due to physical space constraints!) .....am I right in thinking that below the the PIC18F series ...I can't use a lookup table with more than 256 entries? (because as it turns out, I think I need a lookup table with 1024 entries!)
    Last edited by HankMcSpank; - 26th February 2012 at 17:10.

  3. #3
    Join Date
    Nov 2005
    Location
    Bombay, India
    Posts
    947


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    Hi Hank

    Why 800 or even 1024 steps? Why not 256? You may need even lesser!!!
    Yes the lookup table approach is appropriate. However, since the majority brighness changes happen in the bottom segment, you need a very tiny step size/value changes at those levels. The easiest way to create this table of PWM values is to take your favourite desktop programming language and write a small program that will print out the PWM values. I have been used to using QuickBasic from MS for such stuff.

    Code:
    j = 1
    for i = 0 to 256 step j                ' keep widening the step size as we don't need high resolution at larger PWM values
        print log(i)*256;",";               ' print a value like this "val,"  and stay on the line
        j = j+1
    next
    This, of course, is not the best code, but, just a guideline to get you moving.

    Regards

  4. #4
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    thanks ...i know how to do 256 steps....the problem is it's not enough resolution

    I likely need 1024 steps (even a pwm value of 1 has the led quite visible).....at 256 steps a PWM value of 1 is too bright.

    I can obviously just use 1024 steps and drive the LED that way ...but without some form of linearizing lookup/data table the LED doesn't fade up/down smoothly (all the brightness action is slanted towards the lower end of the PWM scale)

    i've since worked out how to generate the curves I need....but what I still can't figure out is how to put this resulting lookup data into code space.

    I read Melanie's "use code space as your playground"....but her syntax relates to PBP assembler....and I'm too clueless to map it to MPASM!

    I tried pokecode....but it baulked when the data lookup values got above 255.

    Since I can't use Lookup2 .....all I want to do is (for a starter!) get the following 512 lookup values into my program/codespace (my PIC has 7KB of program space ...my program is only about 1800 words...so should be sufficient space to cram list of 512 words in)....

    Code:
    0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,
    50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
    96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,
    131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,
    165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,
    199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,
    233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,
    267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,
    301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,
    335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,
    370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,
    405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,
    441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,
    477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511
    Just to give a little more detail wrt the end goal - I'm wanting to take an AD reading & convert it to LED brightness ....I'm using 10 bit ADC...so my intention is to divide the AD result by two then use that AD value to reference the corresponding bit of 512 words in that list ....therefore if incoming AD reading is 760 (10 bit reading)....divide it by 2 to get a 9 bit reading of 380 .....now reference the for 380th entry in that sequence of values ...that'll be the PWM value I need to use.


    I've been searching/reading all night & I'm as confused now as whe I started - is this even do-able?
    Last edited by HankMcSpank; - 27th February 2012 at 01:50.

  5. #5
    Join Date
    Apr 2007
    Location
    Pennsylvania, USA
    Posts
    158


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    Could you do something like this?

    Code:
    ADCvalue var word
    x        var byte
    duty     var byte
    
    main:
    adcin 0, ADCvalue
    x=adcvalue/2
    
    if x<256 then lookup x, [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,_
    50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,_
    96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,_
    131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,_
    165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,_
    199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,_
    233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255],duty
    
    if x>255 then lookup x, [256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,_
    301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,_
    335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,_
    370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,_
    405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,_
    441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,_
    477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511],duty
    
    hpwm 1, duty, 1000
    
    goto main
    Shawn

  6. #6
    Join Date
    Nov 2005
    Location
    Bombay, India
    Posts
    947


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    of course it is do-able. However, I don't think you'll be too happy with the linearity. I am currently working with a similar led lighting problem and know what you're talking about. You need very fine grain at the bottom of the curve to get the intensity variations you need. Shawn has shown an excellent way to split the table lookup into 2 parts.

  7. #7
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    Thanks guys, I'm pursung Shawn's method now, a couple of things I've spotted that might need adjustment...

    Code:
    if x>255 then lookup2 x-255, [256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,_
    301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,_
    335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,_
    370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,_
    405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,_
    441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,_
    477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511],duty
    In other words, for the second table I think I need to use lookup2 ( as the data in the send group of lookups are words), also I need to take 256 off the index value ....else it's trying to lookup the 256th->512th values in the data list .....but the data list runs 0 thru 255.

    Anyway, many thanks....I'll let you know how I get on!
    Last edited by HankMcSpank; - 27th February 2012 at 09:17.

  8. #8
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    Boo hiss - No workeee, man cries.

    lookup2 only allows up to 85 values in the list. ...I then tried to group all the lookup data I need into blocks of 85 values....but I spontaneously combusted (which gave my wife a bit of a fright)

    Any other ideas how to get creative ...I just need to reference at least 512 values in a list (actually, I'd ideally like 1024 values) for a modest 12f1840? (it's got 7kb of program space)
    Last edited by HankMcSpank; - 27th February 2012 at 10:20.

  9. #9
    Join Date
    Apr 2007
    Location
    Pennsylvania, USA
    Posts
    158


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    What if you keep all the values below 256 and do multiple lookup tables with some simple maths.

    ex.

    if X<256 then lookup X, [0,...255],duty
    if X>255 and X<512 then lookup X-256, [0,...255],duty
    if X>511 and X<768 then lookup X-512, [0,...255],duty
    if X>767 then lookup X-768, [0,...255],duty

    You will loose some resolution in the upper bits, but that is where it doesn't matter for this application.
    Last edited by spcw1234; - 27th February 2012 at 12:22.
    Shawn

  10. #10
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    but the numbers are non linear ...for example here are the first 256 numbers....

    Code:
    0,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,7,7,7,7,7,7,
    8,8,8,8,8,8,9,9,9,9,9,10,10,10,10,10,10,11,11,11,11,11,12,12,12,12,12,12,13,13,13,13,13,
    14,14,14,14,14,15,15,15,15,15,15,16,16,16,16,16,17,17,17,17,17,18,18,18,18,18,19,19,19,
    19,19,20,20,20,20,20,21,21,21,21,22,22,22,22,22,23,23,23,23,23,24,24,24,24,24,25,25,25,
    25,26,26,26,26,26,27,27,27,27,28,28,28,28,28,29,29,29,29,30,30,30,30,31,31,31,31,31,32,
    32,32,32,33,33,33,33,34,34,34,34,35,35,35,35,36,36,36,36,37,37,37,37,38,38,38,38,39,39,39,
    39,40,40,40,40,41,41,41,41,42,42,42,43,43,43,43,44,44,44,44,45,45,45,46,46,46,46,47,47,47,
    48,48,48,48,49,49,49,50,50,50,50,51,51,51,52,52,52,53,53,53,53,54,54,54,55,55,55,56,56,56,57
    & here are the final 256 values I need to look up against...

    Code:
    57,57,58,58,58,59,59,59,59,60,60,60,61,61,62,62,62,63,63,63,64,64,64,65,65,65,66,66,66,67,
    67,67,68,68,69,69,69,70,70,70,71,71,72,72,72,73,73,74,74,74,75,75,76,76,76,77,77,78,78,78,
    79,79,80,80,80,81,81,82,82,83,83,84,84,84,85,85,86,86,87,87,88,88,89,89,90,90,90,91,91,92,
    92,93,93,94,94,95,95,96,96,97,98,98,99,99,100,100,101,101,102,102,103,104,104,105,105,106,
    106,107,108,108,109,109,110,111,111,112,113,113,114,114,115,116,116,117,118,118,119,120,
    120,121,122,123,123,124,125,125,126,127,128,128,129,130,131,132,132,133,134,135,136,137,
    137,138,139,140,141,142,143,144,145,145,146,147,148,149,150,151,152,153,154,155,157,158,
    159,160,161,162,163,164,166,167,168,169,171,172,173,175,176,177,179,180,182,183,185,186,188,
    189,191,193,194,196,198,200,201,203,205,207,209,211,213,216,218,220,223,225,228,230,233,236,
    239,241,245,248,251,255,258,262,266,270,275,279,284,290,295,301,308,315,323,332,341,352,365,
    380,398,422,455,512
    (so the second tranche are mainly bytes, but a fair few words too)


    I don't see how maths can be applied to the numbers like you're suggesting?

    here's the vibe I'm try to get (ie the data above plotted on a graph)...
    Last edited by HankMcSpank; - 27th February 2012 at 12:34.

  11. #11
    Join Date
    Apr 2007
    Location
    Pennsylvania, USA
    Posts
    158


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    Not sure how to explain it at the moment, but the values above 255 would have to have 256 subtracted out from them (add this back in when you do the PWM statement) to keep it all below bytes. Let me try to explain this.

    The other math is just for your lookup steps. first table of 256 values (your numbers) works the way you have it. To lookup the next 256 your adc value will be 256-511, so subtract 256 from this value to give you the approporiate position in the lookup table. Use your data for the second lookup table. The only catch is when the values in the lookup table jump above 255. I would simply subtract 256 from the values you calculated and use those new numbers in the lookup table. Then in your PWM statement if the ADC valaue is above 490 (the point in your table that goes above 255) add 256 to the final duty value. Hope this makes some sense, maybe I am overlooking something.
    Shawn

  12. #12
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    Hi Shawn,

    Actually I followed all of that...I'll have a pop at this later - many thanks!

    (I'm quite surprised how convolute it is just to get 512 word values looked up in a small pic with heaps of program space!)

  13. #13
    Join Date
    Feb 2006
    Location
    Gilroy, CA
    Posts
    1,530


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    Hi Hank,

    What kind of math did you use for your excel graph? Wondering if we can get close to that without a lookup.
    http://www.scalerobotics.com

  14. #14
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    Quote Originally Posted by ScaleRobotics View Post
    Hi Hank,

    What kind of math did you use for your excel graph? Wondering if we can get close to that without a lookup.
    It wasn't that slick...nor scientific - basically I was after an anti log type of slope...now when it comes to maths & trig, I'm an epic fail - the only excel function I could get to work was Excel's 'log' (I'm not particularly familiar with excel either!), so I simply dragged down the rows to 512 - applied the log formula (log (A1,512) ...which gave me all the log values ....I then inverted the result in Excel (there's got to be a better way, but I work with the tool & knowledge constraints I have - I don't have time each time I hit a problem to park up & learn how to do it the right way!)

    So basically it's an anti log.....but I'd imagine doing the calculation in in PBP, would be like having your kneecaps drilled, then filled with salt & vinegar.

  15. #15
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    Quote Originally Posted by HankMcSpank View Post
    lookup2 only allows up to 85 values in the list. ...

    That was increased to 1024 in PBP3.
    Bug fixes and tweaks:
    • Limit on LOOKUP2 item list increased to 1024 for Mid-Range and Enhanced Mid-Range architectures.
    • ...
    But each value in a LOOKUP2 requires 3 WORDs.
    1024 values will use 3K from the 4K available on the 12F1840..


    Any other ideas how to get creative ...I just need to reference at least 512 values in a list (actually, I'd ideally like 1024 values) for a modest 12f1840? (it's got 7kb of program space)

    This method can store 1024 14-bit values in 1024 words of program space.
    http://www.picbasic.co.uk/forum/show...php?t=3891#LAB
    DT

  16. #16
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    Hi Darrel,

    thanks for he info...re the ext modifier, your example in the thread you linked to shows how to store one value in one location, but how would I store many follow on values....do I have to have a huge amount of similar associated lines


    Code:
    GOTO OverData             ; Make sure data doesn't try to execute
    ASM
    DataTable
        DW  1234h, 2178h     ; etc.
    endasm
    OverData:
    So for example, let's say I want to store eight words, starting at location 2049 of codespace (of my pic12f1840), for example the following values....

    256,257,258,259,260,261,262,263,264


    what would that look like?

    Once I get the overall vibe, then I'm rocking...... :-)

  17. #17
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    There's no need to put it at a specific location (2049).
    It's just in-line data that can be anywhere in code space.
    The DataTable label let's the compiler know where it is.

    The example shows putting two values in two locations.
    Just continue putting more data in as needed. You can use multiple lines,
    Code:
        DW 256,257,258,259,260,261,262,263,264
        DW 268,270 ... etc.
    And rember that the READCODE has to be AFTER the DataTable.
    Another reason not to put it at a specific address.
    Last edited by Darrel Taylor; - 28th February 2012 at 02:19.
    DT

  18. #18
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,807


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    Do you have any freedom to make hardware changes?

    PWM controlling the current of the LED will give the best results.

    So you could use a PWM output to drive a programmable constant current which in turn will drive the LED.

    It sounds complicated but is not that much. Look at the schematic.

    Name:  LED_CONTROL.png
Views: 3913
Size:  2.5 KB
    PWM output is filtered and drives the transistor that operates as a constant current driver. Current is controlled by R2 and should be selected to satisfy max LED current.

    R1 and C1 be 5-10 times the PWM frequency.

    Ioannis

  19. #19
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    Darrel,

    That works a treat...many thanks :-)

    A monster 1024 value table .....& as compact as Mr Compact's very compact car ....which in turn has been compacted & stored in a very compact gap between two houses.

    Code:
    DataWord  VAR  WORD
    counter1    VAR  WORD
    DataTable CON  EXT
    '-----[The DATA table]--------------------------------------------------------
    GOTO OverData             ; Make sure data doesn't try to execute
    ASM
    DataTable
        DW 0,0,0,0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,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,8,9,9,9,9,9,9,10,10,10,10,10,10,10,11,11
        DW 11,11,11,11,12,12,12,12,12,12,13,13,13,13,13,13,13,14,14,14,14,14,14,15,15,15,15,15,15,16,16,16,16,16,16,16,17,17,17,17,17,17,18,18,18,18,18,18,19,19,19,19,19
        DW 19,20,20,20,20,20,20,21,21,21,21,21,21,22,22,22,22,22,22,23,23,23,23,23,23,24,24,24,24,24,24,25,25,25,25,25,25,26,26,26,26,26,27,27,27,27,27,27,28,28,28,28,28
        DW 28,29,29,29,29,29,29,30,30,30,30,30,31,31,31,31,31,31,32,32,32,32,32,33,33,33,33,33,33,34,34,34,34,34,34,35,35,35,35,35,36,36,36,36,36,37,37,37,37,37,37,38,38
        DW 38,38,38,39,39,39,39,39,40,40,40,40,40,40,41,41,41,41,41,42,42,42,42
        DW 42,43,43,43,43,43,44,44,44,44,44,44,45,45,45,45,45,46,46,46,46,46,47,47,47,47,47,48,48,48,48,48,49,49,49,49,49,50,50,50,50,50,51,51,51,51
        DW 51,52,52,52,52,53,53,53,53,53,54,54,54,54,54,55,55,55,55,55,56,56,56,56,56,57,57,57,57,58,58,58,58,58,59,59,59,59,59,60,60,60,60,61,61,61,61
        DW 61,62,62,62,62,63,63,63,63,63,64,64,64,64,65,65,65,65,65,66,66,66,66,67,67,67,67,67,68,68,68,68,69,69,69,69,70,70,70,70,70,71,71,71,71,72,72
        DW 72,72,73,73,73,73,74,74,74,74,74,75,75,75,75,76,76,76,76,77,77,77,77,78,78,78,78,79,79,79,79,80,80,80,80,81,81,81,81,82,82,82,82,83,83,83,83
        DW 84,84,84,84,85,85,85,85,86,86,86,86,87,87,87,87,88,88,88,89,89,89,89,90,90,90,90,91,91,91,91,92,92,92,93,93,93,93,94,94,94,94,95,95,95,96,96
        DW 96,96,97,97,97,97,98,98,98,99,99,99,99,100,100,100,101,101,101,101,102
        DW 102,102,103,103,103,103,104,104,104,105,105,105,105,106,106,106,107,107,107,108,108,108,108,109,109,109,110,110,110,111,111,111,111,112,112
        DW 112,113,113,113,114,114,114,115,115,115,116,116,116,116,117,117,117,118,118,118,119,119,119,120,120,120,121,121,121,122,122,122,123,123,123,124
        DW 124,124,125,125,125,126,126,126,127,127,127,128,128,128,129,129,129,130,130,130,131,131,132,132,132,133,133,133,134,134,134,135,135,135,136,136
        DW 137,137,137,138,138,138,139,139,139,140,140,141,141,141,142,142,142,143,143,144,144,144,145,145,146,146,146,147,147,147,148,148,149,149,149,150
        DW 150,151,151,151,152,152,153,153,153,154,154,155,155,156,156,156,157,157,158,158,158,159,159,160,160,161,161,161,162,162,163,163,164,164,165,165
        DW 165,166,166,167,167,168,168,169,169,169,170,170,171,171,172,172,173,173,174,174,175,175,175,176,176,177,177,178,178,179,179,180,180,181,181,182
        DW 182,183,183,184,184,185,185,186,186,187,187,188,188,189,189,190,190,191,191,192,193,193,194,194,195,195,196,196,197,197,198,198,199,200,200,201, 201,202,202,203
        DW 204,204,205,205,206,206,207,208,208,209,209,210,211,211,212,212,213,214,214,215,215,216,217,217,218,219,219,220,221,221,222,222,223,224,224,225,226,226,227,228
        DW 228,229,230,230,231,232,233,233,234,235,235,236,237,238,238,239,240,240,241,242,243,243,244,245,246,246,247,248,249,250,250,251,252,253,253,254,255,256,257,258
        DW 258,259,260,261,262,263,263,264,265,266,267,268,269,270,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295
        DW 296,297,298,299,300,301,303,304,305,306,307,308,309,311,312,313,314,315,317,318,319,320,322,323,324,326,327,328,329,331,332,334,335,336,338,339,341,342,344,345
        DW 347,348,350,351,353,354,356,358,359,361,362,364,366,368,369,371,373,375,377,378,380,382,384,386,388,390,392,394,396,398,401,403,405,407,410,412,414,417,419,422
        DW 424,427,429,432,435,437,440,443,446,449,452,455,458,462,465,468,472,475,479,483,487,490,495,499,503,507,512,517,521,526,532,537,543,548,554,561,567,574,581,589
        DW 597,605,614,624,634,645,657,670,684,699,717,736,759,786,819
        DW 862,922,1023
    endasm
    Overdata:   ' this is a jump point to make sure the above data table isn't executed
    increment_loop:
    if counter1 < 1023 then
    COUNTER1 =COUNTER1+1
    ReadCODE  (DataTable + COUNTER1), DataWord
    duty = dataword
    gosub change_pwm
    pause 1
    GOTO increment_loop
    endif
    decrement_loop:
    if counter1 > 0 then
    COUNTER1 =COUNTER1-1
    ReadCODE  (DataTable + COUNTER1), DataWord
    duty = dataword
    gosub change_pwm
    pause 1
    GOTO decrement_loop
    endif
    GOTO increment_loop
    change_pwm:
    CCP1CON.4 = Duty.0       'Bit 0
    CCP1CON.5 = Duty.1       'Bit 1
    CCPR1L = Duty >> 2       'Bit 2-7
    return
    I've now get a smoothtastic fading up/down LED. (there did appear to be one gotcha...being of the lazy ilk, I wanted each DW line to be 256 values long - nope, max allowed seems to be about 65-70 bytes - I can't be exact but it is in or around that value ....so lots of DW lines needed)

    Ioannis ...that sort of what I'm doing - but rather than a tranny I'm using a mosfet (no filtering either...since the end result is visual, and the eye is only good for about 25Hz ....my pwm is about 16khz...so I didn't see the need?)
    Last edited by HankMcSpank; - 28th February 2012 at 09:46.

  20. #20
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,807


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    There is no difference (significant at least) whether you use bipolar or mosfet since the transistor will work in linear region. So, since it works linearly, cap will make calculation easier, because you will have to deal with dc voltages in base of the transistor in regard with the ground.


    So, after PWM fltering the resulting dc voltage is the sum of Vbe (~0,6) and V(R1). V(R1) will define the current through the LED.

    Have not tested in comparisson with the table but seems easier to control.

    Ioannis

  21. #21
    Join Date
    Aug 2005
    Location
    Michigan, USA
    Posts
    224


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    Hi Hank,

    Have you tried using fewer discrete brightness level steps spread across the much larger pwm width? For example, I get very smooth fades using between 64 and 100 gamma corrected brightness level steps spread across a much larger 512 pwm steps.

    You can also "bend" the duty cycle curve to help match the characteristics of the LEDs.

    Regards, Mike

    Name:  gamma correction.png
Views: 4929
Size:  20.1 KB

  22. #22
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    Hi Mike,

    Thnaks for the input...no I've not tried fewer brightness steps - I figured my problem was an insufficient number of brightness steps ......especially at the low end of the brightness scale, where for example the first 20 steps at 256 pwm levels sees quite a swing in the perceived LED brightness.....this is why I whacked it right up to 1024 brightness levels....which is much better from a less 'steppy' LED response perspective , but I'm still not happy with the overall fade curve, so your formula is of high interest! (there's aplethora of curves out there...and it's difficult to decide which one is best for this application!)

    I've copied your formula into an excel spreadsheet for LUT of 1024 (well, I have the code space so may as well use it!) & 10 bit PWM.....the curve looks more like what I'm aiming for (if you look at my earlier curve further up the thread, the last part of the curve was almost vertical - this is too extreme)....I see yours is a little more gradual/linear towards the upper/final part of the plot ....and I shall give this a try tomorrow...many thanks.


    What's with the 0.3 at the end of the formula ...where did that come from?
    Last edited by HankMcSpank; - 8th March 2012 at 00:33.

  23. #23
    Join Date
    Aug 2005
    Location
    Michigan, USA
    Posts
    224


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    Hank,

    The PWM "step" size makes a significant difference at the low end too. It's amazing how much more light you get from a LED running at 1/1024th duty cycle with 1-usec PWM steps compared to, say, 125-nsec steps. Getting more brightness resolution at the lower duty cycle range seems to pay off with better smooth fade capability.

    What's with the 0.3 at the end of the formula ...where did that come from?

    Oh, the 0.3 was for rounding. Sorry if it caused any confusion.

    BTW, here's a little program I use for building my gamma array tables. It uses the free JustBASIC program. After running it I copy the array from the console into my PIC source file. Hope it may be of some use.

    Regards, Mike

    Code:
     '  Leo Bodnar's 'antilogarithmic' 
     '  gamma correction algorithm (Mike, K8LH)
     '
     '  JustBASIC (free) interpreter
     '
     Input "Gamma array size: "; arraysize
     Input " Total PWM steps: "; width
     Input "Gamma correction: "; gamma       ' try 0.5 to 1.0
    
    
     FOR index = 0 to arraysize-1
        dcyval = INT(width^(((index+1)/arraysize)^gamma)+.3)
        if(index = 0) then
          dcyval = 0
          PRINT
        else
          if(index MOD 10 = 0) then
            PRINT ","
          else
            PRINT ",";
          end if
        end if
        if(dcyval < 100) then print " ";
        if(dcyval < 10) then print " ";
        PRINT dcyval;
     NEXT index
     PRINT
     PRINT
     REM CLOSE
    And here's what the output looks like when you run the program;

    Code:
    Gamma array size: 64
     Total PWM steps: 256
    Gamma correction: .84
    
    
      0,  1,  1,  2,  2,  2,  2,  2,  3,  3,
      3,  4,  4,  4,  5,  5,  6,  7,  7,  8,
      9,  9, 10, 11, 12, 13, 14, 16, 17, 19,
     20, 22, 24, 26, 28, 30, 33, 36, 39, 42,
     45, 49, 53, 57, 62, 67, 72, 78, 84, 90,
     98,105,113,122,132,142,153,165,177,191,
    205,221,238,256

  24. #24
    Join Date
    Aug 2005
    Location
    Michigan, USA
    Posts
    224


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    Hank,

    You got a 12F683? If so, and if you want to experiment, connect an LED to GP0 (anode) and GP5 (cathode) and try the program below. The circuit doesn't use a current limiting resistor, relying instead on the RDS(on) resistance of the I/O pin output FETs.

    The program fades the LED through sixty four gamma corrected brightness levels spanning 256 1-usec BAM duty cycle steps with a 1280-usec frame rate (781-Hz refresh rate).

    Code:
    :020000040000FA:0600000083018501F128D7
    :08000800F000030EF10083017A
    :100010000A08F2008A010408F3008C1074088500B5
    :1000200083167608850077088500162878088500ED
    :100030000030FF3E031819281D287908850002307A
    :10004000FF3E0318202824287A08850074087407C6
    :1000500074191030F41A0130F4000430FF3E031814
    :100060002E28322800007B0885002030F418243028
    :1000700074192830741A2C30F41A303084000C3083
    :10008000FF3E031840287C0885007D08F5007409B0
    :10009000F600F700F800F900FA00FB00FC00FD0094
    :1000A0000130741820300018F6068018F706001981
    :1000B000F8068019F906001AFA06801AFB06001BDA
    :1000C000FC06801BFD06840A0230F418203000185C
    :1000D000F6068018F7060019F8068019F906001AC6
    :1000E000FA06801AFB06001BFC06801BFD06840A2C
    :1000F0000430741920300018F6068018F70600192D
    :10010000F8068019F906001AFA06801AFB06001B89
    :10011000FC06801BFD06840A1030741A203000187B
    :10012000F6068018F7060019F8068019F906001A75
    :10013000FA06801AFB06001BFC06801BFD06083031
    :10014000FF3E0318A0287508850073088400720814
    :100150008A00030E8300F00E700E09008A013F39F9
    :10016000820700340134023402340234023403348E
    :1001700003340334043404340534053406340634BB
    :1001800007340834083409340A340B340C340D3481
    :100190000E340F3411341234143415341734193426
    :1001A0001B341D341F342234243427342A342D3494
    :1001B0003134353439343D34413446344B345134A0
    :1001C00057345D3464346B3472347B3483348C3410
    :1001D0009634A134AC34B734C434D134E034EF3481
    :1001E000FF340730990083169F0170308F000F1D78
    :1001F000F72883123F30840080018403841AFC288E
    :100200002030F4000130AA000230AB000330AC0013
    :100210000430AD000530AE000630AF000730B0004E
    :100220000830B1000930B2000A30B3008C019101EE
    :100230000530920083167F3092008C148312C030F8
    :100240008B0010303321B60A361B2C293608AE201D
    :10025000A000212910303321B603B61B212936080E
    :10026000AE20A0002A29B500740820393406B4064F
    :0C027000340503193429350B332908002C
    :02400E00D43F9D
    :00000001FF
    I'll also write something using the PWM module so that we can try 125-nsec PWM steps (with an 8-MHz clock).

    Cheerful regards, Mike
    Last edited by Mike, K8LH; - 10th March 2012 at 13:54.

  25. #25
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    Hi Mike,
    exactly
    I haven't got a 12f683 to hand .... I'm still a rather weak/n00by programmer, so wondering what exatly that program is you've posted?!!!

    I tried 1024 PWM levels with a gamma (0.8 & 1.6), but actualy neither of them seemed to fade any better than what I had in place already (which was some anti log kludge).

    The hassle for me here is converting any lookup table to a DW table (to be able to use lots of available code space to store the lookup values), presently, I'm doing the test curves in excel, then saving to a csv...but my version of excel only allows 256 columns wide, so I have to put 1024 values the curve on 4 rows, then save it as a csv.

    Worse still the 'DW' command seems to have a restriction of somewhere in the order of 70 bytes per line entry, so I can't just use a hulking 256 byte long lines, but having to break the 4 long CSV lines, into smaller snippets....

    Code:
        DW 0,0,0,0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,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,8,9,9,9,9,9,9,10,10,10,10,10,10,10,11,11
    & so on...what I really need is to knock up a program that takes an excel 'column' 1024 deep coverts it into blocks of lines 70 bytes long (like the above) all rpefaced with a DW on the front...because presently it's about 30 minutes work just to trial a different curve - it get tiring very quickly!

    While I'm here, can anyone field an elegant way of rescaling....let's say I have 10 bit ADC that I want to scale to a maximum of 800 PWM steps (if you are wondering what I'm trying to achive....a max LED brightnesss setting ...I hoping to have a maximum PWM value (which will differ depending upon the maximum brightness setting required) & need to rescale the incoming ADC to it ...therefore a MAX ADC value of 1023 -> max PWM value of 800 (or 600, 400...whatever I've chosen to be the maximum PWM value)....it's easy to outside of picbasic...

    (max PWM value/1023) * incoming ADC value ...but the first part of the caclulation results in a floating point number. (for example 800/1023 = 0.78201368523949169110459433040078 !!!) ....now I realise you have to gear everything up, but just wanted a little bit of guidance how this is done in Picbasic to set me on my way!
    Last edited by HankMcSpank; - 10th March 2012 at 20:32.

  26. #26
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    re the scaling...I found the floating point thread....

    http://melabs.com/resources/fp.htm

    but adding that particular bas file wiped my program out (I'm at the edge of my PIC's variable limit), so here's what I'm doing...

    I scale up the max PWM value (which will be the maximum LED brightness) by 64 (the maximum multiplier that still keeps me within 'word' constraints), then divide this value by the maximum possible incoming ADC reading (10 bit = 1023) ... I then mulitply that result by the actual incoming ADC reading ......and then divide by 64.

    I lose about 0.5% of resolution but that's pretty close for my needs.

  27. #27
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    Keep coming back to this. (I I like a breather in between!)

    Is there any electronic sensor that mimics the eye's 'response' curve out there that I can buy & put a scope on its output? What I'm thinking is that if I put such a sensor directly over the LED being driven with PWM then 'shoot' for a linear slope, then that's gonna be the way forward here - else I'm sort of stabbing in the dark!

  28. #28
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,807


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    Something like this maybe?

    http://www.intersil.com/content/dam/...n66/fn6691.pdf

    http://www.vishay.com/docs/49670/pl0366.pdf

    Have used before the BPW21 and is very nice.

    Ioannis
    Last edited by Ioannis; - 7th March 2013 at 17:16.

  29. #29
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,521


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    I don't know exactly HOW close to "human eye response" it is but the APDS-9300 from Avago (I2C interface, $1.60 at Digikey) claims to Approximate the human-eye response. Or perhaps one of the sensors from Vishay. I don't know enough about them to tell if they are good or bad, just Googles for a couple of minutes.

    EDIT: Weird how similar two responses can be sometimes....

  30. #30
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    Hiya,

    Long time no code!

    I'm wanting to use Mike, K8LH 'Just Basic' code to generate values towards linerarizing an LED for PWM ...what Mike has done is great & & more or less ideal for my needs, but to save a bit of post editing for use with my PIC of choice, I ideally seek a way of having the code place a DW on the front of every line.

    Mike wrote it in standard basic, but I'm not familiar with syntax (besides I'm very rusty with coding now!) & hoped that someone could quickly edit the code to place a DW at the front of all the outputted lines.

    Here's Mike's code that I've modified a little already...

    Code:
    '  Maxim Gamma Correction Algorithm
    '
    '  JustBASIC (free) interpreter
    '
    Input "Gamma array size: "; arraysize
    Input " Total PWM steps: "; width
    Input "Gamma correction: "; gamma       ' maxim uses 2.5
    
    FOR index = 0 to arraysize-1
      dcyval = INT(width*(((width/arraysize*(index+1))/width)^gamma))
      if(index = 0) then
        PRINT
      else
        if(index MOD 34 = 0) then 'this dictates how many values per line
          PRINT " " 'this puts no comma at the end of the line
        else
          PRINT ","; 'this puts commas in between the values
        end if
      end if
      if(dcyval < 100) then print " ";
      if(dcyval < 10) then print " ";
      PRINT dcyval;
    NEXT index
    PRINT
    
    REM CLOSE
    The above gernerates output like this

    Code:
    Gamma array size: 255
     Total PWM steps: 1023
    Gamma correction: 2
    
      0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  2,  2,  3,  3,  4,  4,  5,  5,  6,  6,  7,  8,  9,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18
     19, 20, 21, 22, 23, 25, 26, 27, 29, 30, 31, 33, 34, 36, 37, 39, 40, 42, 44, 45, 47, 49, 51, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72
     74, 77, 79, 81, 83, 86, 88, 90, 93, 95, 98,100,103,105,108,111,113,116,119,121,124,127,130,133,136,139,141,144,148,151,154,157,160,163
    166,170,173,176,180,183,186,190,193,197,200,204,208,211,215,219,222,226,230,234,238,241,245,249,253,257,261,265,269,274,278,282,286,290
    295,299,303,308,312,317,321,326,330,335,339,344,349,353,358,363,368,373,377,382,387,392,397,402,407,412,417,423,428,433,438,444,449,454
    460,465,470,476,481,487,492,498,504,509,515,521,526,532,538,544,550,556,561,567,573,579,586,592,598,604,610,616,623,629,635,641,648,654
    661,667,674,680,687,693,700,707,713,720,727,734,740,747,754,761,768,775,782,789,796,803,810,817,825,832,839,846,854,861,868,876,883,891
    898,906,913,921,928,936,944,952,959,967,975,983,991,999,1007,1014,1023
    whereas what I seek is a DW at the front of each line like thus...

    Code:
    Gamma array size: 255
     Total PWM steps: 1023
    Gamma correction: 2
    
    DW  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  2,  2,  3,  3,  4,  4,  5,  5,  6,  6,  7,  8,  9,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18
    DW 19, 20, 21, 22, 23, 25, 26, 27, 29, 30, 31, 33, 34, 36, 37, 39, 40, 42, 44, 45, 47, 49, 51, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72
    DW 74, 77, 79, 81, 83, 86, 88, 90, 93, 95, 98,100,103,105,108,111,113,116,119,121,124,127,130,133,136,139,141,144,148,151,154,157,160,163
    DW 166,170,173,176,180,183,186,190,193,197,200,204,208,211,215,219,222,226,230,234,238,241,245,249,253,257,261,265,269,274,278,282,286,290
    DW 295,299,303,308,312,317,321,326,330,335,339,344,349,353,358,363,368,373,377,382,387,392,397,402,407,412,417,423,428,433,438,444,449,454
    DW 460,465,470,476,481,487,492,498,504,509,515,521,526,532,538,544,550,556,561,567,573,579,586,592,598,604,610,616,623,629,635,641,648,654
    DW 661,667,674,680,687,693,700,707,713,720,727,734,740,747,754,761,768,775,782,789,796,803,810,817,825,832,839,846,854,861,868,876,883,891
    DW 898,906,913,921,928,936,944,952,959,967,975,983,991,999,1007,1014,1023
    Can anyone help me out here?

    (the code runs with this http://www.justbasic.com/download.html )
    Last edited by HankMcSpank; - 10th May 2013 at 21:58.

  31. #31
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,597


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    Try this modification (untested):

    Code:
    ...
      if(index = 0) then
        PRINT
        PRINT "DW ";
      else
        if(index MOD 34 = 0) then 'this dictates how many values per line
          PRINT " " 'this puts no comma at the end of the line
          PRINT "DW ";
        else
    ...
    Robert

  32. #32
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    Hi, that worked a treat, here's the output after modifying with your snippets...

    Code:
    Gamma array size: 255
     Total PWM steps: 1023
    Gamma correction: 2
    
    DW   0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  2,  2,  3,  3,  4,  4,  5,  5,  6,  6,  7,  8,  9,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18
    DW  19, 20, 21, 22, 23, 25, 26, 27, 29, 30, 31, 33, 34, 36, 37, 39, 40, 42, 44, 45, 47, 49, 51, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72
    DW  74, 77, 79, 81, 83, 86, 88, 90, 93, 95, 98,100,103,105,108,111,113,116,119,121,124,127,130,133,136,139,141,144,148,151,154,157,160,163
    DW 166,170,173,176,180,183,186,190,193,197,200,204,208,211,215,219,222,226,230,234,238,241,245,249,253,257,261,265,269,274,278,282,286,290
    DW 295,299,303,308,312,317,321,326,330,335,339,344,349,353,358,363,368,373,377,382,387,392,397,402,407,412,417,423,428,433,438,444,449,454
    DW 460,465,470,476,481,487,492,498,504,509,515,521,526,532,538,544,550,556,561,567,573,579,586,592,598,604,610,616,623,629,635,641,648,654
    DW 661,667,674,680,687,693,700,707,713,720,727,734,740,747,754,761,768,775,782,789,796,803,810,817,825,832,839,846,854,861,868,876,883,891
    DW 898,906,913,921,928,936,944,952,959,967,975,983,991,999,1007,1014,1023
    Many thanks....this will save me a lot of time experimenting with different gamma values with the LUT going into the PIC

  33. #33
    Join Date
    Aug 2005
    Location
    Michigan, USA
    Posts
    224


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    Hi Hank,

    Sorry for the late reply. Glad you figured it out. Another slightly more recent version of that Gamma Table program is listed below.

    Gamma values of 1.7 to 1.9 worked good for me but it's very much dependent on your LEDs, voltage, hardware, etc..

    Cheerful regards, Mike

    Code:
     '  Leo Bodnar's 'antilogarithmic'
     '  gamma correction algorithm (Mike, K8LH)
     '
     '  JustBASIC (free) interpreter
     '
     Input "Gamma array size: "; arraysize
     Input " Total PWM steps: "; width
     Input "Gamma correction: "; gamma       ' try 0.5 to 1.0
     Input "Entries per line: "; entries     '
    
     FOR index = 0 to arraysize-1
        dcyval = INT(width^(((index+1)/arraysize)^gamma)+.3)
        if(index MOD entries = 0) then
          PRINT
          PRINT "  DW ";
        else
          PRINT ",";
        end if
    
        if(dcyval < 100) then print " ";
        if(dcyval < 10) then print " ";
        PRINT dcyval;
     NEXT index
     PRINT
     PRINT
     REM CLOSE
    Last edited by Mike, K8LH; - 11th May 2013 at 01:14.

  34. #34


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    Quote Originally Posted by Mike, K8LH View Post
    Hi Hank,

    Sorry for the late reply. Glad you figured it out. Another slightly more recent version of that Gamma Table program is listed below.

    Gamma values of 1.7 to 1.9 worked good for me but it's very much dependent on your LEDs, voltage, hardware, etc..

    Cheerful regards, Mike

    Code:
     '  Leo Bodnar's 'antilogarithmic'
     '  gamma correction algorithm (Mike, K8LH)
     '
     '  JustBASIC (free) interpreter
     '
     Input "Gamma array size: "; arraysize
     Input " Total PWM steps: "; width
     Input "Gamma correction: "; gamma       ' try 0.5 to 1.0
     Input "Entries per line: "; entries     '
    
     FOR index = 0 to arraysize-1
        dcyval = INT(width^(((index+1)/arraysize)^gamma)+.3)
        if(index MOD entries = 0) then
          PRINT
          PRINT "  DW ";
        else
          PRINT ",";
        end if
    
        if(dcyval < 100) then print " ";
        if(dcyval < 10) then print " ";
        PRINT dcyval;
     NEXT index
     PRINT
     PRINT
     REM CLOSE
    Hi Mike,

    I'm implementing a LED dimmer using Darrel Taylor's MIBAM library (see http://www.picbasic.co.uk/forum/cont...-Modulation%29) which accepts values from 0 - 255 for the duty cycle. I also want to smoothly fade the LEDs so I believe I need to include something similar to your Gamma correction algorithm, but I'm having trouble understanding what you mean by 'Gamma array size'. On another thread I see you posted a chart where you used 100 for that value (and 512 for pwm steps) - is that analogous to saying, 'My brightness can go from 0 (fully off) -100% (fully on, max LED brightness) with 512 steps'? Would I use Gamma array size = 100 and pwm steps = 256?

  35. #35
    Join Date
    Aug 2005
    Location
    Michigan, USA
    Posts
    224


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    Quote Originally Posted by RossWaddell View Post
    Would I use Gamma array size = 100 and pwm steps = 256?
    Yes... Good luck with your project...

    Cheerful regards, Mike

  36. #36


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    Thanks Mike!

  37. #37


    Did you find this post helpful? Yes | No

    Default Re: Linearizing an LED for 800 pwm steps'?

    Next question - if this produces data than I **think** gets added to a .pbp file with the ASM/ENDASM block, how do I search/look up values from it in code?

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts