# Using the pow() function??

s Hi there!

I am trying to use the pow() function to create an exponential map. I have looked in various places online and have been able to locate very little info on the function and even less on using it for exponential mapping. Any suggestions and/or links that might be able to help me achieve my goal would be greatly appreciated!

Thanks!!

Walter

create an exponential map

Do you mean draw a graph of an exponential function? If so, what sort of display are you going to use?

Pete

is multimap() - http://arduino.cc/playground/Main/MultiMap - a solution for your problem?

Thanks for all the replys guys!

I’ve been through that webpage quite a few times but never could pull much from it.

el_supremo:

create an exponential map

Do you mean draw a graph of an exponential function? If so, what sort of display are you going to use?

Pete

By map I just mean take input say 0-255 and scale it to say 0-2000. However, I would like to do it exponentially.

robtillaart:
is multimap() - http://arduino.cc/playground/Main/MultiMap - a solution for your problem?

Possibly? I am not very familiar with using multimap(). What I am trying to do is take the input from a ps2 controller analog stick (0-255 and scale it exponentially to 0-2000. I am using the the ps2 controller to control a differential drive robot, but currently just pushing the stick forward a tiny bit sends the not shooting across the room. This is why I need to create the exponential map(or similar) : to make the controls less sensitive.

Thanks!!

Walter

How to use this forum

I don’t think you need an exponential mapping function. A simple quadratic might work well. The function y = 3xx/100 will map the input range of 0-255 to an output range of 0-1950 (close enough to 2000?). The multiplies are done using long integers to avoid overflow problems. This code tests the function:

``````uint16_t my_map(uint16_t pot_value)
{
return(3L*pot_value*pot_value/100L);
}

void setup(void)
{
Serial.begin(9600);

Serial.println(my_map(0));
Serial.println(my_map(1));
Serial.println(my_map(10));
Serial.println(my_map(100));
Serial.println(my_map(200));
Serial.println(my_map(255));
}

void loop(void)
{
}
``````

and prints:

``````0
0
3
300
1200
1950
``````

Pete

+1 for pete

doing it integer is way faster, reverse engineering gives an almost exact solution

y = x * x * a / b;

x* x = 0 .. 65025 which should map to 0 .. 2000
==> a/b == 2000/65025 == 80 / 2601

y = 80L * x * x /2601L

if you want to add rounding to the formula

y = (1300L + 80L * x * x) /2601L;

as the square can be calculated in 16 bit, it can be optimized a few clock cycles y = (1300L + 80L * (x * x)) /2601L;

I was going to go with y=x^2/32.5 for simplicity

It meets the linear version at the ends, and in the middle where the linear one would give 1000, it gives 500 (ie 2000/4). Gets steep after that.

if you want to do it exponentially, you might have to use floats

y = ax y = 0…2000 x = 0…255

because zero is difficult for exponential functions we use

y = ax-1 y = 1…2001 x = 0…255 !! a0 == 1 ==> -1

a = xthroot(2001) = 20011/255 = 1.03025817

so the formula becomes

y = pow(1.03025817, x) -1;

... but currently just pushing the stick forward a tiny bit sends the not shooting across the room.

Doesn't the OP want a logarithm and not an exponent?

Walter103:
s Hi there!

I am trying to use the pow() function to create an exponential map...

Walter

...

"pushing the stick forward a tiny bit sends the not shooting across the room" is X.

The exponential map is Y.

Thanks for all the suggestions! using a quadratic equation would certainly be worth a try. I’ll work through all the suggestions and see what works best. However, It will probably take me a while as I’m currently swamped with school work.

For all who are interested, here is the code as it stands without any modifications:

``````#include <SoftPWM.h>
#include <SoftPWM_timer.h>
#include <Servo.h>
#include <PS2X_lib.h>  //for v1.6

PS2X ps2x; // create PS2 Controller Class

int error = 0;
byte type = 0;
byte vibrate = 0;

Servo Signal1; //creates servo object
Servo Signal2;

int Input1 = 1500;
int Input2 = 1500;

int Speed1 = 1500;
int Speed2 = 1500;

int setMotorSensitivity()
{
float gamma = 1.5;
for (x=0; x<256; x++)
{
float normx = x / 255.0;
float normy = pow (normx, gamma);
int y = (int) (0.5 + normy * 255);

serial.print("x: ");
serial.print(x, DEC);
serial.print("   y: ");
serial.println(y, DEC);
}

}

void setup()
{
Serial.begin(57600);

Speed1.attach(4);  //the pin for the servo control
Speed2.attach(5);

error = ps2x.config_gamepad(13,11,10,12, true, true);   //setup pins and settings:  GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error

if(error == 0)
Serial.println("Controller found! You may now send commands");

else if(error == 1)
Serial.println("No controller found, check wiring, see readme.txt to enable debug. visit www.billporter.info for troubleshooting tips");

else if(error == 2)
Serial.println("Controller found but not accepting commands. see readme.txt to enable debug. Visit www.billporter.info for troubleshooting tips");

else if(error == 3)
Serial.println("Controller refusing to enter Pressures mode, may not support it. ");

switch(type)
{
case 0:
Serial.println("Unknown Controller type");
break;
case 1:
Serial.println("DualShock Controller Found");
break;
}
}
//My sabortooth motordriver can use the two signals 1000us-2000us to control the two motors
void loop()
{
if(error == 1)
{
return;
}
else
{

Input1 = map(ps2x.Analog(PSS_LY), 0, 255, 2000, 1000);
Speed1 = setMotorSensitivity(Input1);
Signal1.writeMicroseconds(Speed1);
//Serial.print ("Input1: ");
//  Serial.println (Input1);

Input2 = map(ps2x.Analog(PSS_LX), 0, 255, 2000, 1000);
Speed2 = setMotorSensitivity(Input2);
Signal2.writeMicroseconds(Speed2);
//Serial.print ("Input2: ");
// Serial.println (Input2);
delay(8);
}
}
``````

Thanks!

Walter

Pete

el_supremo:

But have you got the libraries, el_s?

Doesn’t matter. Errors in this function are independent of the libraries.

``````int setMotorSensitivity()
{
float gamma = 1.5;
for (x=0; x<256; x++)
{
float normx = x / 255.0;
float normy = pow (normx, gamma);
int y = (int) (0.5 + normy * 255);

serial.print("x: ");
serial.print(x, DEC);
serial.print("   y: ");
serial.println(y, DEC);
}

}
``````

Pete

I believe I may have uploaded the wrong version of my code. I will check it when I get back home today

Sorry guys,

Walter