# simple gamma function e.g. to correct analogRead

For a experiment I needed to correct the input of the analogRead() function. Normally analogRead() maps approx. linear the values 0…5 Volt to 0…1023. The gamma function proved very useful.

``````double gammaEncode(double in, double gamma)
{
return pow(in / 1023.0, 1.0 / gamma) * 1023.0;  // note two hard coded magic numbers
}
``````

as my code did a mapping to 0…5V again I changed it to

``````double gammaEncodeMap(double in, double gamma, double maxIn, double maxOut)
{
return pow(in / maxIn, 1.0 / gamma) * maxOut;
}
``````

to support direct mapping to the wanted value.

A little test sketch shows it is not really fast code, but that was no issue (yet).

``````//
//    FILE: gammaEncodeMap.ino
//  AUTHOR: Rob Tillaart
// VERSION: 0.1.00
// PURPOSE: demo
//    DATE: 7-apr-2015
//     URL:
//
// Released to the public domain
//

uint32_t start;
uint32_t stop;
double x, y, z;

void setup()
{
Serial.begin(115200);
Serial.println("Start ");

start = micros();
stop = micros();
Serial.println(stop - start);

start = micros();
y = gammaEncode(x, 1.5);  // NOTE 10% SLOWER
stop = micros();
Serial.println(stop - start);

start = micros();
y = gammaEncodeMap(x, 1.5, 1023, 1023);
stop = micros();
Serial.println(stop - start);

Serial.print(x);
Serial.print(" -> ");
Serial.println(y);

Serial.println("\ntest2");
for (int i = 0; i < 1023; i ++)
{
x = gammaEncodeMap(i, 1.3, 1023, 5);
y = gammaDecodeMap(x, 1.3, 5, 1023);
Serial.print(i);
Serial.print(" -> ");
Serial.print(x);
Serial.print(" -> ");
Serial.println(y);
}

Serial.println("done...");
}

void loop()
{
}

double gammaEncode(double in, double gamma)
{
return pow(in / 1023.0, 1.0 / gamma) * 1023.0;
}

{
return pow(in / 1023.0, gamma) * 1023.0;
}

double gammaEncodeMap(double in, double gamma, double maxIn, double maxOut)
{
return pow(in / maxIn, 1.0 / gamma) * maxOut;
}

double gammaDecodeMap(double in, double gamma, double maxIn, double maxOut)
{
return pow(in / maxIn, gamma) * maxOut;
}
``````

output:

``````00
1021 -> 4.99 -> 1021.00
1022 -> 5.00 -> 1022.00
done...
Start
216
392
352
374.00 -> 523.05

test2
0 -> 0.00 -> 0.00
1 -> 0.02 -> 1.00
2 -> 0.04 -> 2.00
3 -> 0.06 -> 3.00
4 -> 0.07 -> 4.00
5 -> 0.08 -> 5.00
6 -> 0.10 -> 6.00
7 -> 0.11 -> 7.00
8 -> 0.12 -> 8.00
9 -> 0.13 -> 9.00
10 -> 0.14 -> 10.00
..
1013 -> 4.96 -> 1013.00
1014 -> 4.97 -> 1014.00
1015 -> 4.97 -> 1015.00
1016 -> 4.97 -> 1016.00
1017 -> 4.98 -> 1017.00
1018 -> 4.98 -> 1018.00
1019 -> 4.98 -> 1019.00
1020 -> 4.99 -> 1020.00
1021 -> 4.99 -> 1021.00
1022 -> 5.00 -> 1022.00
done...
``````