Go Down

Topic: Map() function for curve (Read 1 time) previous topic - next topic

SouthernAtHeart

I'm needing to map a value, but I'd like to figure out a formula or function to give me a slight curve in the mapped graph.  Here's the current map:
Code: [Select]
int val = map(reading, neutralVal, maxVal, 0, 799);

This is to map an analog reading to a motor speed. 0-799 being the motor's speed, off and 100%.
What I'd like is a curve so that 50% of the analog reading give about 25% motor speed.  I remember from Algebra there's a way to figure out the formula, but ...that was tooling ago.
Here's a graph depicting what I have I mind.

johnwasser

Your analog reading would be 0-1023 with a mid-point at 512.

If you square the reading (reading * reading) you will get a range of 0 to 1,046,529 (be sure to use LONG integers).  The 512 would then be 262,144 or about 1/4 of the range.  Divide by 1,309 to get a range of 0 to 799.

Code: [Select]

unsigned long reading = analogRead(inputPin); // 0-1023
reading = reading * reading;  // 0-1046529
reading = reading / 1309;  // 0-799
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

SouthernAtHeart

Thanks. I think I will need to do it with variables though, as my high and low limits can change, depending on other factors (READING is from neutralVal to MaxVal rather than 0 to 1024) . I think it shouldn't be a problem though. Would this do it?

Code: [Select]

unsigned long reading = analogRead(inputPin);
unsigned long SQneutral = NeutralVal * NeutralVal;
unsigned long SQmax = MaxVal * MaxVal;
reading = reading * reading;

reading = map(reading, SQNeutral, SQmax, 0, 799);


michinyon

The map() function is linear  and is not going to give you a parabola type curve.

You need to do what johnwasser said.   if some of the parameters change,  use those
the parameters in the equation instead of the constant numeric literals.

SouthernAtHeart

Ok, so if I've got variables to work with instead of numbers, it'd be like this?

Code: [Select]

unsigned long reading = analogRead(inputPin);
unsigned long SQneutral = NeutralVal * NeutralVal;
unsigned long SQmax = MaxVal * MaxVal;
reading = reading * reading;
reading = reading / (reading / 799);

Go Up