Hi all.
I have a question about the map function.
I see there is a lot of talk on git hub about it.
opened 05:37PM - 22 Nov 14 UTC
bug
EDIT NOTE: I added a comment to the end of this from a later comment because I t… hought it should have been included in the first place.
The equation in the function stated at http://arduino.cc/en/Reference/Map
``` C++
long map(long x, long in_min, long in_max, long out_min, long out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
```
is wrong. The example given:
``` C++
val = map(val, 0, 1023, 0, 255);
```
In this example 0-1023 is mapped to 0-255. The equation gets it wrong by mapping 1023 numbers to 255 numbers, when it should be mapping 1024 numbers to 256 numbers.
0 through 1023 is 1024 numbers not 1023 : in_max - in_min : 1023-0=1023
0 through 255 is 256 numbers not 255 : out_max - out_min : 255-0=255
The corrected equation in the function should be:
``` C++
long map(long x, long in_min, long in_max, long out_min, long out_max)
{
return (x - in_min) * (out_max - out_min + 1) / (in_max - in_min + 1) + out_min;
}
```
In the following simpler example it will be easier to see:
val = map(val, 0, 3, 0, 1);
In this example 0,1,2 and 3 is mapped to 0 and 1. Mapped correctly it should be:
0 maps to 0
1 maps to 0
2 maps to 1
3 maps to 1
Using the equation in the the function as it is now, it is mapped as such:
0 maps to 0
1 maps to 0
2 maps to 0
3 maps to 1
This is a common problem programmers have dealt with before. When dealing with arrays you can not determine array size by simply subtracting first position from last position you will always be off by 1. That is why you add 1 to get proper size. I know this is for the most part a minor problem, but if your project requires accurate results this could be a serious issue.
--- Added from later comment---
To give a real world scenario as to why this needs changed consider this. You are using the arduino with a sensor to sample data and based on this data set a servo into 1 of 4 positions. The arduino uses a 10 bit adc and outputs integers from 0 to 1023. You would use map(x, 0, 1023, 1, 4). With the map function as it is currently the only time position 4 would be active is when the arduino outputs the integer 1023. With my proposed change each position would get an equal share of the possible range. When they converted this function from a float function to an integer function they didn't consider that the output is no longer a value but a position. Value mapping maps one value to another and the function works perfectly for floats. Positional mapping distributes the input as evenly as possible to the output and the function as is doesn't do that.
This function needs to be split into two functions. One for floats as it is now and one for integers as I proposed.
But here is my question, I want to map the values 0 - 4095 to 0 - 100
I use the function like this
val = map(4095,0,4095,0,100);
I am expecting 100 to return if I send in 4095 but I am getting 87.
Am I missing something ?
system
June 2, 2016, 12:12pm
#2
Am I missing something ?
The rest of your code. And proof.
void setup() {
Serial.begin(115200);
Serial.print(F("map(4095, 0, 4095, 0, 100) = "));
Serial.println(map(4095, 0, 4095, 0, 100));
}
void loop() {}
map(4095, 0, 4095, 0, 100) = 100
Thank all, I found the problem. Putty changed one of my values.
UKHeliBob:
How did it do that ?
Hi UKHeliBob.
I develop on the Rapberry Pi. I have the Arduino hooked up to the Pi. I ported the Map function to Python and used it in a very long line of code that runs up to the end of the nano editor, I used the mark and copy method between 2 putty sessions and I copied the $ by mistake, I then went in to fix it and probably hit the 9 and not the 0, As the error was at the end of the line I did not pick it up as nano will jump the line if it is to long.
As I got the map function from the Arduino source I decided to post it here after reading some posts about the map not working. I made a mistake. Thanks for the help.