While prototyping a small LED project, I needed to map a potentiometer and found I was having bad flickering issues when I reached the higher end. Running the input/output through Serial, I saw that the distribution in map is horribly uneven. Hunting for solutions, I noticed that many folks have the same issue, so I figured I would post my temporary solution in the hopes it could be improved upon by the community.
NOTE: The flickering was not from bouncing, which I had already compensated for, but the uneven distribution in map() when using smaller numbers (e. g. 3)
unsigned int myMap(int value, int inmax, int outmax)
{
// divide input max by output max
int division = inmax / outmax;
// initialize count
int count = 1; // note: this method will not work directly if you need a 0 in the map. you will need to -1 the returned value if so.
// while the value of the sensor is greater than the desired mapping
while ( value > division * count)
{
// add 1 to the count
count++;
// if the count is greater than the maximum desired mapping, return the output max
if (count >= outmax)
{
return outmax;
}
}
// return the final count
return count;
}
usage:
ledPos = myMap(potVauel, 1023, NUMPIXELS) - 1; // map the led position
Any thoughts on improving this or effectively using map() better are very welcome.
I cannot see your code or how you used the map(...) function so I am left to guess that the problems that you had stem from the integer nature of the map(...) function.
You may have better luck implementing a floating point version of the map(...) function. The reference documentation for the map(...) function shows how it is implemented.
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;
}
You may have better results by implementing a rounded floating point version of map(...). Of course, this will increase the memory usage due to the need for floating point library routines.
Not tested:
long mapRoundedFloat(long x, long in_min, long in_max, long out_min, long out_max)
{
return long(float((x - in_min) * (out_max - out_min)) / float(in_max - in_min) + out_min + 0.5) ;
}
I believe that floating point arithmetic will be used due to the arithmetic rules of the C language.