Still looks like a perfect job for multimap() - http://arduino.cc/playground/Main/MultiMap - does not use float so it has a smaller footprint and faster (not tested extensively)
an example S-curve - fill in your own values -
int s[] = {
0, 0, 10, 30, 70, 130, 180, 320, 350, 370, 380}; // 11
int in[] = {
0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
unsigned long d = 0;
void setup()
{
Serial.begin(9600);
d = millis();
for (int i=0; i< 10000; i++)
{
int val = analogRead(A0)/10;
volatile int x = multiMap(val, in, s, 11);
}
d = millis() - d;
Serial.print("a: ");
Serial.println(d);
d = millis();
for (int i=0; i< 10000; i++)
{
int val = analogRead(A0)/10;
}
d = millis() - d;
Serial.print("b: ");
Serial.println(d);
d = millis();
for (int i=0; i< 10000; i++)
{
int val = analogRead(A0)/10;
volatile int x = pow(val/255.0, 2.5)*255;
}
d = millis() - d;
Serial.print("c: ");
Serial.println(d);
}
void loop()
{
}
int multiMap(int val, int* _in, int* _out, uint8_t size)
{
// take care the value is within range
// val = constrain(val, _in[0], _in[size-1]);
if (val <= _in[0]) return _out[0];
if (val >= _in[size-1]) return _out[size-1];
// search right interval
uint8_t pos = 1; // _in[0] allready tested
while(val > _in[pos]) pos++;
// this will handle all exact "points" in the _in array
if (val == _in[pos]) return _out[pos];
// interpolate in the right segment for the rest
return map(val, _in[pos-1], _in[pos], _out[pos-1], _out[pos]);
}
a: 1643
b: 1120
c: 4344
So 10000 calls took :
multimap: 1643 - 1120 = 525 millis or 53 micros() per call .
powefunc: 4344 - 1120 = 3224 millis or 322.5 micros() per call.
difference: 322/53 ~~ factor 6
Sketch with 1 call to the power func: size 3528 bytes (IDE 0.22, duemillanove)
Sketch with 1 call tothe multimap: size 2180 bytes
The diff in size here is mainly because no floats are used.
That said you need the power formula to generate the lookup table...