Go Down

Topic: simple gamma function e.g. to correct analogRead (Read 45 times) previous topic - next topic

robtillaart

Apr 07, 2015, 05:09 pm Last Edit: Apr 07, 2015, 09:27 pm by robtillaart
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.

Code: [Select]
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
Code: [Select]

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).
Code: ("test sketch") [Select]

//
//    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.
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy