Linearizing an LED for 800 pwm steps'?


Closed Thread
Results 1 to 37 of 37

Hybrid View

  1. #1
    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.

  2. #2
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    4,132


    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

  3. #3
    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: 5153
Size:  20.1 KB

  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'?

    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.

  5. #5
    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

  6. #6
    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.

  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'?

    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.

Members who have read this thread : 0

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