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();
  x = analogRead(A0);
  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;
}

double gammaDecode(double in, double gamma)
{
  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...

As always comments are welcome.

gamma.JPG