LED / PWM

Have you got the greatest 48 bit multiplier ever conceived? Prove it - post your code here.

Moderator: phalanx

User avatar
ohararp
Posts: 307
Joined: Sun May 01, 2005 8:43 pm
Location: Dayton, OH
Contact:

Post by ohararp » Fri Jun 19, 2009 7:19 am

Image

This would be right on from my guesstimate in recent testing. Thanks leon.
Regards Ryan :-)
$25 SMT Kapton Stencils - http://www.ohararp.com/
US Distributor of PDS - http://www.ohararp.com/compilers.html

efox
Posts: 8
Joined: Fri Dec 28, 2007 11:46 am

Post by efox » Sat Jul 04, 2009 3:18 am

A few months ago i saw a youtube video with a fading led. Someone attached that to an apple logo to mimic apples standby led.

I thought it was cool and attempted it. FAIL.

The led did not fade at all, it would increase in brightness and was extremely choppy. After some reading, i read in a forum from some random guy that vision was logarithmic. Had no idea if he was right or wrong, so I went furthur and tried to get more information on it. Took a while, because theres not a lot of really simple explanations of it, everything is pretty advanced and really, all i wanted to do was get my led to fade. Thats it.

I came across an app-note from maxim, that involved using look up tables from gamma correction

http://www.maxim-ic.com/appnotes.cfm/an_pk/3667

This is how I got started. After reading it and figuring out how it works, I started to create my own. I used matlab to generate a csv file that would create 128 duty cycles for my led to increase linearly. You can create your own with excel even, I just wanted to use matlab.

If you(or anyone) want my code, let me know and ill clean it up a bit and put it up. I was going to release it eventually, just havent gotten a round to actually making it look nice and neat and commented, and flexible enough so that anyone can really use it (though its FAIRLY flexible right now, but I'm sure I can go furthur).

Good luck.

millwood
Posts: 115
Joined: Thu Jul 02, 2009 2:09 pm

Post by millwood » Wed Jul 08, 2009 5:15 am

the approach proposed by cheesy would work on any mcu, with or without built-in pwm.

it's downside is that the cpu is occupied during the pwm routine.

another approach that will free up the cpu is to use a counter to count the "steps" in pwm and design if you want to the pwm output to be on or off.

it adds a little bit code but allows more flexibility.

intellijel
Posts: 7
Joined: Thu Sep 21, 2006 2:50 pm

Post by intellijel » Wed Jul 22, 2009 4:21 pm

I looked at that maxim paper but did not understand it :S

Can someone explain to me how to create that same curve in C code?

I just want to make a look up table for a 10bit pwm register (i.e. 1024 values).


i.e. so based on the example, would my table be based on y = X^2.5/1023

where X is my uncorrected PWM amount and 2.5 is the gamma correction exponent?

In their example I got confused with the offsets and I guess the fact that they are assuming a fade over a certain amount of time (e.g. timer1 called every 50ms to change the pwm value?)

Mike, K8LH
Posts: 32
Joined: Fri Jun 20, 2008 8:21 pm
Location: Michigan, USA

Re: LED / PWM

Post by Mike, K8LH » Sat Apr 24, 2010 7:24 am

I realize this is an old thread but I hope someone may benefit from my reply.

I believe you want to build a gamma correction array of duty cycle values so you should modify that Maxim formula to look something like this in your spreadsheet;

duty cycle value = int(width*(((width/arraysize*(index+1))/width)^gamma))

where width would be 1024 for your 10-bit PWM, arraysize would be the size of your gamma correction array (64, 100, 256 elements, etc.), index is the array element index like 0..63 (64 element array) or 0..255 (256 element array), etc., and gamma is the gamma correction factor mentioned in the Maxim article.

I wrote a quick-n-dirty program using the (free) Just BASIC interpreter to try it out;

Code: Select all

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

REM CLOSE

And here's sample program output in the console window;

Code: Select all

Gamma array size: 64
 Total PWM steps: 256
Gamma correction: 2.5

  0,  0,  0,  0,  0,  0,  1,  1,  1,  2,
  3,  3,  4,  5,  6,  8,  9, 10, 12, 13,
 15, 17, 19, 22, 24, 26, 29, 32, 35, 38,
 41, 45, 48, 52, 56, 60, 65, 69, 74, 79,
 84, 89, 94,100,106,112,118,124,131,138,
 145,152,159,167,175,183,191,200,208,217,
 227,236,246,256
Kind regards, Mike

scottgoff
Posts: 1
Joined: Thu Aug 11, 2011 1:18 am

Re: LED / PWM

Post by scottgoff » Thu Aug 11, 2011 1:51 am

Well, not to flog a dead horse and revive a fairly old thread again, but I found the above post containing the gamma function & BASIC code very helpful. I used it to get gamma correction working with a simple array of Shiftbrites controlled from an Arduino. I used a modified version of the function inside a for loop to do the gamma correction "on the fly" without needing a gamma correction look-up table. Below is a code snippet from my Arduino sketch; hopefully someone else can benefit from it. And of course, I would love any feedback anyone has to offer, as I am pretty new to writing code :D

Code: Select all

//Fades in a number of Shiftbrite LED modules from fully off to white, indicated 
//by "NumLEDs", which is defined at the beginning of the sketch. Each iteration of
//the inner-nested for loop raises int variable "ii", intended as the raw 10 bit PWM
//value, by one count, and then performs a gamma correction function (with a gamma of
//2.5) on that number. The gamma corrected value for each iteration is put into the 
//variable declared as "dutyCycle", which is stored in the red, green, and blue slots
//in the LEDChannels array, and after the current gamma corrected PWM value is thus 
//stored, the LED array is written to by the function "WriteLEDArray", followed by a 
//delay, which slows the whole fade process slightly. This results in a perceived 
//linear change in brightness as the LEDs fade in. For more information on the other 
//parts of the code upon which the below is based, please see the macetech website, 
//which offers the full code examples
    
for (int i = 0; i < NumLEDs + 1; i++) {
      for (int ii = 0; ii < 1023; ii++) {
  
      int dutyCycle = int (float (1023.0 * pow(((ii + 1) / 1023.0), 2.5)));
      LEDChannels [i][0] = dutyCycle;
      LEDChannels [i][1] = dutyCycle;
      LEDChannels [i][2] = dutyCycle;
      WriteLEDArray();
     delayMicroseconds(onTime); 
   }
  }

Rigby
Posts: 1
Joined: Tue Jul 22, 2014 9:01 am

Re: LED / PWM

Post by Rigby » Tue Jul 22, 2014 9:28 am

I'm going to revive this ye olde threade again to include my mechanism. Square the 0-255 brightness, then bitshift right 8 places.

Code: Select all

unsigned int adjustedBrightness = (brightness * brightness) >> 8;
analogWrite(led, adjustedBrightness);
For 10-bit pwm, square the 0-1023 brightness, then bitshift right 10 places.

The 10-bit variety requires a 32-bit number, so heads up.

Post Reply