News:

Let's find out together what makes a PIC Tick!

Main Menu

Need: 16 Bit gamma correction formula

Started by diebobo, Aug 22, 2022, 07:25 AM

Previous topic - Next topic

diebobo

Hi Folks,

I am in need of a 16 bit gamma correction formula for LED's.. Everyone uses a Lookup table which is oke for 8 bit but with 16bit it gets a bit crazy :). Anyone done this before in Proton ? Or has a piece of code i can alter to make it work to 16 bit ?


John Lawton

You can still use a lookup table with 16 bit values, if you don't supply every single one. Then you can use interpolation to recreate the 'missing' values from in between the ones you have.

keytapper

There is a description on the manual,  just search Cread16 and related topics. But for speed it rather preferable to use variables in RAM.
Ignorance comes with a cost

top204

Reading from flash memory is extremely fast with the compiler on 18F and enhanced 14-bit core and dsPIC33 and PIC24 devices. In fact it is the same speed as reading from RAM. Also, a RAM array or flash table for 16-bits would take 131072 bytes to hold the 16-bit values! So a table is not the solution on a microcontroller, either in RAM or flash memory.

Keytapper....
Please..... If an answer is not known, do not give the wrong advice. Do not post with incorrect speculations or guesses! Throughout my life, I have always followed the rule: "No information is better than incorrect information"!

What is required in a device that has a limited amount of RAM or flash memory, is the calculation that actually creates the values for a table. I created one many years ago for gamma correction using 8-bits for LEDs based upon Leo Bodnar's antilogarithm calculations, and it worked quite well. I used it to create values for a flash memory table displayed on a serial terminal, then copied into the program's data table. So I have just adapted it for 16-bits and to be used directly, but it is not fully tested!

Because the algorithm uses antilog, it does need floating point to be implemented, which will slow down the process. But if speed is a priority, move to a PIC24 or dsPIC33 device because the floating point I implemented on them is extremely fast! With the 18F device operating at 64 MHz, the Gamma16 procedure will take approx 1.1 ms to perform its calculations. Interpolation of a smaller flash memory table would be difficult because it is not linear, so the values between two points would also, probably, need calculations with logs.

The program listing is below, and is not fully tested, but the graph it produces looks correct. Are you sure you actually need 16-bits for an LED? Even televisions only use 13-bits for the LED and LCD DACs inside them.

'
'   /\\\\\\\\\
'  /\\\///////\\\
'  \/\\\     \/\\\                                                 /\\\          /\\\
'   \/\\\\\\\\\\\/        /\\\\\     /\\\\\\\\\\     /\\\\\\\\   /\\\\\\\\\\\  /\\\\\\\\\\\  /\\\\\\\\\
'    \/\\\//////\\\      /\\\///\\\  \/\\\//////    /\\\/////\\\ \////\\\////  \////\\\////  \////////\\\
'     \/\\\    \//\\\    /\\\  \//\\\ \/\\\\\\\\\\  /\\\\\\\\\\\     \/\\\         \/\\\        /\\\\\\\\\\
'      \/\\\     \//\\\  \//\\\  /\\\  \////////\\\ \//\\///////      \/\\\ /\\     \/\\\ /\\   /\\\/////\\\
'       \/\\\      \//\\\  \///\\\\\/    /\\\\\\\\\\  \//\\\\\\\\\\    \//\\\\\      \//\\\\\   \//\\\\\\\\/\\
'        \///        \///     \/////     \//////////    \//////////      \/////        \/////     \////////\//
'                                  Let's find out together what makes a PIC Tick!
'
' Calculate a value to linearise an LED's brightness using a 16-bit Gamma correction algorithm.
' Based upon Leo Bodnar's antilogarithmic gamma correction algorithm.
'
' Written for the Positron8 BASIC compiler by Les Johnson.
'
    Device = 18F25K20                                 ' Tell the compiler what device to compile for
    Declare Xtal = 16                                 ' Tell the compiler what speed the device is operating at (in MHz)
'
' Setup USART1
'
    Declare HSerial_Baud = 9600
    Declare HRsout1_Pin = PORTC.6
'
' Create some global variables for the demo
'
    Dim wElementIndex As Word                                       ' Holds the element within the gamma algorith to return the value for
    Dim wGammaValue   As Word                                       ' Holds the return from the Gamma16 procedure

'--------------------------------------------------------------------
' The main program starts here
' Calculate a 16-bit gamma value for an LED's brightness.
' And send the values to a serial terminal, with a graph to show the curve's trace
'
Main:
    For wElementIndex = 0 To 65535 Step 128                         ' Create a loop for the elements to calculate
        wGammaValue = Gamma16(wElementIndex)                        ' Calculate the gamma for a particular element value
        '
        ' Draw a curve of the results on a serial terminal for visualisation
        '
        Hrsout Dec5 wGammaValue, "| "
        If wGammaValue <= 1 Then
            HRSOutLn "*"
        Else
            HRSOutLn Rep " "\(wGammaValue / 1000), "*"
        EndIf
    Next

'--------------------------------------------------------------------
' Return a 16-bit logarithmic value to linearise an LED's brightness
' Input     : pElement holds the element within the linearisation calculation to receive the value of
' Output    : Returns the 16-bit gamma value
' Notes     : Uses Leo Bodnar's antilogarithmic gamma correction algorithm
'
Proc Gamma16(pElement As Word), Word
    Dim fTemp As Float
    Symbol cGammaSize = 65535                                       ' The amount of iterations in the gamma calculation
    Symbol cGammaValue = 0.5                                        ' The Gamma correction value. Normally between 0.5 to 1.0

    fTemp = Pow((pElement / cGammaSize), cGammaValue)
    Result = Pow(pElement, fTemp)
EndProc

The loop in the main program has been stepped by 128, so that the curve shown on the serial terminal is not huge. i.e. 65536 lines long. :-)

Below is the curve chart the above program creates on the serial terminal. It is still big, but shows the curve moving up in a non-linear fashion, to give the LED a more linear glow pattern. Change the floating point constant held in "cGammaValue" and run tests on an LED or on the curve traced to see which value is better suited for the LED type being used.

00000| *
00001| *
00001| *
00001| *
00001| *
00001| *
00002| *
00002| *
00002| *
00002| *
00002| *
00002| *
00003| *
00003| *
00003| *
00003| *
00003| *
00004| *
00004| *
00004| *
00004| *
00004| *
00005| *
00005| *
00005| *
00005| *
00006| *
00006| *
00006| *
00007| *
00007| *
00007| *
00008| *
00008| *
00008| *
00009| *
00009| *
00009| *
00010| *
00010| *
00010| *
00011| *
00011| *
00012| *
00012| *
00013| *
00013| *
00013| *
00014| *
00014| *
00015| *
00015| *
00016| *
00017| *
00017| *
00018| *
00018| *
00019| *
00020| *
00020| *
00021| *
00022| *
00022| *
00023| *
00024| *
00024| *
00025| *
00026| *
00027| *
00028| *
00028| *
00029| *
00030| *
00031| *
00032| *
00033| *
00034| *
00035| *
00036| *
00037| *
00038| *
00039| *
00040| *
00041| *
00042| *
00044| *
00045| *
00046| *
00047| *
00049| *
00050| *
00051| *
00053| *
00054| *
00056| *
00057| *
00058| *
00060| *
00062| *
00063| *
00065| *
00067| *
00068| *
00070| *
00072| *
00074| *
00075| *
00077| *
00079| *
00081| *
00083| *
00085| *
00087| *
00090| *
00092| *
00094| *
00096| *
00099| *
00101| *
00103| *
00106| *
00108| *
00111| *
00114| *
00116| *
00119| *
00122| *
00125| *
00128| *
00130| *
00133| *
00137| *
00140| *
00143| *
00146| *
00149| *
00153| *
00156| *
00160| *
00163| *
00167| *
00171| *
00175| *
00178| *
00182| *
00186| *
00190| *
00195| *
00199| *
00203| *
00208| *
00212| *
00217| *
00221| *
00226| *
00231| *
00236| *
00241| *
00246| *
00251| *
00257| *
00262| *
00268| *
00273| *
00279| *
00285| *
00291| *
00297| *
00303| *
00309| *
00315| *
00322| *
00328| *
00335| *
00342| *
00349| *
00356| *
00363| *
00371| *
00378| *
00386| *
00393| *
00401| *
00409| *
00417| *
00426| *
00434| *
00443| *
00451| *
00460| *
00469| *
00478| *
00488| *
00497| *
00507| *
00517| *
00527| *
00537| *
00547| *
00558| *
00569| *
00579| *
00591| *
00602| *
00613| *
00625| *
00637| *
00649| *
00661| *
00674| *
00686| *
00699| *
00712| *
00726| *
00739| *
00753| *
00767| *
00781| *
00795| *
00810| *
00825| *
00840| *
00856| *
00871| *
00887| *
00904| *
00920| *
00937| *
00954| *
00971| *
00989| *
01007|  *
01025|  *
01043|  *
01062|  *
01081|  *
01100|  *
01120|  *
01140|  *
01160|  *
01181|  *
01202|  *
01223|  *
01245|  *
01267|  *
01289|  *
01312|  *
01335|  *
01358|  *
01382|  *
01406|  *
01430|  *
01455|  *
01481|  *
01506|  *
01532|  *
01559|  *
01586|  *
01613|  *
01641|  *
01669|  *
01698|  *
01727|  *
01756|  *
01786|  *
01817|  *
01847|  *
01879|  *
01911|  *
01943|  *
01976|  *
02009|   *
02043|   *
02077|   *
02112|   *
02148|   *
02184|   *
02220|   *
02257|   *
02295|   *
02333|   *
02372|   *
02411|   *
02451|   *
02492|   *
02533|   *
02575|   *
02617|   *
02660|   *
02704|   *
02748|   *
02793|   *
02839|   *
02885|   *
02932|   *
02980|   *
03028|    *
03077|    *
03127|    *
03178|    *
03229|    *
03281|    *
03334|    *
03388|    *
03442|    *
03498|    *
03554|    *
03611|    *
03668|    *
03727|    *
03786|    *
03846|    *
03908|    *
03970|    *
04033|     *
04096|     *
04161|     *
04227|     *
04293|     *
04361|     *
04430|     *
04499|     *
04570|     *
04641|     *
04714|     *
04788|     *
04862|     *
04938|     *
05015|      *
05093|      *
05172|      *
05252|      *
05333|      *
05416|      *
05499|      *
05584|      *
05670|      *
05757|      *
05846|      *
05936|      *
06026|       *
06119|       *
06212|       *
06307|       *
06403|       *
06501|       *
06600|       *
06700|       *
06802|       *
06905|       *
07009|        *
07115|        *
07222|        *
07331|        *
07442|        *
07554|        *
07667|        *
07782|        *
07899|        *
08017|         *
08137|         *
08259|         *
08382|         *
08507|         *
08634|         *
08762|         *
08892|         *
09024|          *
09158|          *
09293|          *
09431|          *
09570|          *
09711|          *
09854|          *
09999|          *
10146|           *
10295|           *
10446|           *
10599|           *
10754|           *
10911|           *
11070|            *
11232|            *
11395|            *
11561|            *
11729|            *
11900|            *
12072|             *
12247|             *
12424|             *
12604|             *
12786|             *
12970|             *
13157|              *
13347|              *
13538|              *
13733|              *
13930|              *
14129|               *
14332|               *
14537|               *
14744|               *
14955|               *
15168|                *
15384|                *
15603|                *
15824|                *
16049|                 *
16276|                 *
16507|                 *
16741|                 *
16977|                 *
17217|                  *
17460|                  *
17706|                  *
17955|                  *
18208|                   *
18463|                   *
18723|                   *
18985|                   *
19251|                    *
19520|                    *
19793|                    *
20069|                     *
20349|                     *
20633|                     *
20920|                     *
21211|                      *
21506|                      *
21804|                      *
22107|                       *
22413|                       *
22723|                       *
23037|                        *
23355|                        *
23678|                        *
24004|                         *
24335|                         *
24669|                         *
25008|                          *
25352|                          *
25700|                          *
26052|                           *
26408|                           *
26770|                           *
27135|                            *
27506|                            *
27881|                            *
28261|                             *
28646|                             *
29035|                              *
29430|                              *
29829|                              *
30234|                               *
30643|                               *
31058|                                *
31478|                                *
31903|                                *
32334|                                 *
32770|                                 *
33211|                                  *
33658|                                  *
34111|                                   *
34569|                                   *
35033|                                    *
35503|                                    *
35979|                                    *
36461|                                     *
36948|                                     *
37442|                                      *
37942|                                      *
38448|                                       *
38960|                                       *
39479|                                        *
40004|                                         *
40536|                                         *
41074|                                          *
41619|                                          *
42170|                                           *
42729|                                           *
43294|                                            *
43866|                                            *
44446|                                             *
45032|                                              *
45626|                                              *
46227|                                               *
46835|                                               *
47451|                                                *
48075|                                                 *
48706|                                                 *
49344|                                                  *
49991|                                                  *
50645|                                                   *
51308|                                                    *
51978|                                                    *
52657|                                                     *
53344|                                                      *
54039|                                                       *
54743|                                                       *
55456|                                                        *
56177|                                                         *
56906|                                                         *
57645|                                                          *
58393|                                                           *
59149|                                                            *
59915|                                                            *
60690|                                                             *
61475|                                                              *
62269|                                                               *
63072|                                                                *
63885|                                                                *
64708|                                                                 *

diebobo

Thanks Les for the Code.. I really Need, uhhhhh want 16 bit yes :).. I am already using it for years perfectly fine, just wanted some more eye - smootness out of it.. The commercial available RGB controllers are ( most of them ) just 8 bit PWM'ers, and i can't stand the coarse dimming of them. At full brightness to off mode in 1 second is fine. But sometimes my lights are dimmed to 20% and i got a fade speed of 3 secs, then i don't want to see any stepping. With the 8 bitters it's just horrible. 16 Bit is a lot better...

Also i am using some kind of "wake up light/strip" which is 0 to 100% in 15 minutes ? I really need fine stepping for that, i am a light sleeper and will be awake at step 1 of thoose 8 bitters ;)

Am using a PIC24 at 32 mHz, so got some power availble. Still need to receive some large UART strings at 38K4 while at 200hz update interrupt for the RGB calculations / push to PWM registers..  Got it working now, 4 byte UART buffers give's some slack ;)

Thanks !