Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

64 Level Gamma Table Scale to 8 Bit

Status
Not open for further replies.

Suraj143

Active Member
I'm doing an RGB colour changing light.It has 255 PWM steps. I'm doing interrupt driven software PWM for 3 channels.

Xtal OSC = 4Mhz
Interrupt rate is 32uS.
PWM Period :32uS X 256 = 8192uS
PWM frequency is 122Hz.

I can fade an LED from 0 to 255 steps without a problem.Now I want to add an 64 level gamma table to the 8bit PWM steps.

My problem is there is only 64 gamma values but I have 255 PWM steps,How to scale this down?
The below code hangs when "Brightness" register comes to 65 :(
Code:
    incf    Brightness,F    ;increments from 0 to 255
    movf    Brightness,W
    call    Gamma_Table    ;call gamma value (contains 64 values)
    movwf    W_Brightness    ;load gamma value

Thanks
 
I'm no programmer, but if you have to map 255 values to 64 don't you need to divide the Brightness value by 4 before calling Gamma-table?
 
The below code hangs when "Brightness" register comes to 65 :(
There are several different ways of doing that. Here is one way.
Lookup table:
0=0, 5,7 (numbers for Red, Blue, Green)
1=4,9,11
2=8,14,15
.......
62=200, 251, 198
63=204,255,202
end of table
So the table is 0 through 63 (64 values) so there can't be a brightness of 65. You only have 64 brightness levels.
(each level has R, G, B values)

In monitors (some) (CRT or LCD) there is a gamma table that has 256 locations and 10 bit or 12 bit numbers.
 
If the table is 0 to 63 (64 levels), multiply by 4 (left shift 2). This will map to 0 to 253 by 4's. There are still only 64 discrete values (can't make data out of nothing) but they are in the range of your PWM input.
 
Thanks guys you all have come closer.

There are several different ways of doing that. Here is one way.
Lookup table:
0=0, 5,7 (numbers for Red, Blue, Green)
1=4,9,11
2=8,14,15
.......
62=200, 251, 198
63=204,255,202
end of table
So the table is 0 through 63 (64 values) so there can't be a brightness of 65. You only have 64 brightness levels.
(each level has R, G, B values)

In monitors (some) (CRT or LCD) there is a gamma table that has 256 locations and 10 bit or 12 bit numbers.

Now I understood a bit.Gamma represents "smooth brightness level" sort of thing.So I have a 64 level gamma correction table over a 255 PWM steps.That means I can fade LEDs with 64 level of brightness levels.

The attached table is my 64 levels over a 8bit PWM steps.

Now the question is if I want to load a single colour let say value "Red 200" (that is not in the table anywhere) and need to fade up to full brightness.How to achieve this?How do I know which index out of 0-63 the value 200 is present?
 

Attachments

  • gamma.png
    gamma.png
    14.7 KB · Views: 234
Index = int(value/4).
 
Hi Suraj,

I wrote a program in JustBASIC many years ago that produces the anti-log type gamma correction tables. I don't have the program handy at the moment (it's on another hard drive not hooked up to my laptop), but I think it's available in the links in this post.

Good luck on your project. Cheerful regards, Mike
 
Because I don't know what you are doing it is a little hard.
Your eye is not linear. The current through a LED is linear, or close.
If you divide up the LED current into 255 steps (linear) your eye will not see this as linear. To your eye there is a large step from level 2 to 3 and a very small step from 200 to 201. Gamma correction can be used to make all steps appear to your eye as the same size.

Now the question is if I want to load a single colour let say value "Red 200" (that is not in the table anywhere) and need to fade up to full brightness.How to achieve this?How do I know which index out of 0-63 the value 200 is present?
The user only has 0 to 63. There is no 200.
You can make a 0 to 255 table and it might not have a 200.
 
Here's what an early version of the program looked like (below). I would end up using "gamma" values around 0.7 to get a relatively nice fade effect in my projects. This is just a crude method for producing brightness correction table values. Color LEDs is a whole different thing. Hopefully it will give you some ideas though.
Code:
'  Leo Bodnar's 'antilogarithmic'
'  gamma correction algorithm
'
'  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
The output from the program looks something like this;

Code:
Gamma array size:64
  Total PWM steps:256
Gamma correction:1

    0,  1,  1,  1,  1,  1,  2,  2,  2,  2,
    2,  3,  3,  3,  3,  4,  4,  5,  5,  5,
    6,  7,  7,  8,  9,  9, 10, 11, 12, 13,
   14, 16, 17, 19, 21, 22, 24, 27, 29, 32,
   35, 38, 41, 45, 49, 54, 58, 64, 70, 76,
   83, 90, 99,107,117,128,139,152,166,181,
  197,215,235,256
I would just copy the table values from the console and paste them into a table in my PIC programs.

Cheerful regards, Mike
 
Last edited:
Ok thank you very much guys for the help of understanding.

Mike thanks for your codes that generates gamma values.

Now when fading LEDs I'm using 64 level brightness register that represents 0 to 255 duty cycle values.

The thing is as I mentioned earlier I am doing a RGB mood light thing.I'm not always fading LEDs. In the mean time while fading I need to show fixed & mixed colours as well.

Ex: the colour "yellow green" 8bit values are (154,205,50).So I need to find the index values for the above duty cycles.

Index = int(value/4) is not correct as the table is not having linear values.

Whats the point in a mood light that cannot show a colour as expected :(
 
Hi mike your justBASIC code is really helpful in this matter.Thanks for the nice software.

I have shifted my design to a 255 gamma correction method.I'll let you all the progress :)

With a gamma correction design you get really nice colours in the spectrum change.Without a gamma corrector intermediate colours like Orange,light yellow,light purple etc very hard to produce & its not noticeable to human eyes while fading.
 
Last edited:
There are many different ways to gamma correct.
The 256 table is best. If you have that much memory.

If memory is short, you can use a smaller table and interpret values. Less memory but much more math and time.

There are many trade offs that can be made.

Another option that works if the R, G, and B tables have the same curve.
Make one curve, then at 0, 64, 128, 192, 255 test for "color temperature". So at "255" test to see how much color correction you need. example R=+3%, B=-10% to get RG & B right. But at "128" there will be a different color correction number and at "0" they will be different again.
When I first started doing this; we used analog "computers".
We would test "black levels". R, G, B values for very dim.
Test "white levels". R, G, B values for very bright.
Test "mid point levels". RGB values at half bright.
That is all the numbers needed.

The last time I used a FPGA computer. We looked up 256 (12 bit) values. R, G and B every 10nS.
 
There are many different ways to gamma correct.
The 256 table is best. If you have that much memory.

If memory is short, you can use a smaller table and interpret values. Less memory but much more math and time.

There are many trade offs that can be made.

Another option that works if the R, G, and B tables have the same curve.
Make one curve, then at 0, 64, 128, 192, 255 test for "color temperature". So at "255" test to see how much color correction you need. example R=+3%, B=-10% to get RG & B right. But at "128" there will be a different color correction number and at "0" they will be different again.
When I first started doing this; we used analog "computers".
We would test "black levels". R, G, B values for very dim.
Test "white levels". R, G, B values for very bright.
Test "mid point levels". RGB values at half bright.
That is all the numbers needed.

The last time I used a FPGA computer. We looked up 256 (12 bit) values. R, G and B every 10nS.

Nice info.I'll keep mind on this.I'd prefer the lookup table method.I'm doing my PWM part on every 32uS timer tick.So I have very limited time period to do other parts.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top