map function

Any ideas why I get negative values out of this:

long a;
long b;

void loop() {
  while(true){
    delay(1000);
    for (int i = 0; i < 255; i++){
        a = pow(i,3);
        b = map(a, 0,pow(255,3), 0,300 );
...
...
...

I print b on the LCD. It starts to run up nocely but after 127 it turns to negative and starts to run closer to 0.

regards
orbitrek

It's very likely that somewhere in the implementation of de map() function, an integer overflow is occuring. If you don't need negative numbers being fed into map(), you might want to use this slightly adapted method:

unsigned long MyMap(unsigned long x, unsigned long in_min, unsigned long in_max, unsigned long out_min, unsigned long out_max) {

      return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

I think that will solve your problem.

In the map function, map is defined as

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;
}

out_max - out_min = 16581375
As i gets large, x - in_min approaches this same value.

(x - in_min) * (out_max - out_min) then overflows, resulting in crap output.

This happens even if all arguments are changed to unsigned long.

out_max - out_min = 16581375

The way I read the code, out_max - out_min = 300 - 0 = 300

(in_max - in_min) however will eval to your '16581375', but this value will not be multiplied further. I've tested the Arduino implementation of map() and was able to reproduce orbitrek's problem in GCC. Changing all the variables to UL's (as I did in the method posted) solved the problem here (again, with GCC).
Are you quite sure it will fail on the Arduino? I would guess not...

I tried a number of things to make map work. The best I could get was for i = 248, I think. I deleted the sketch, without saving, since it isn't really my problem. I changed all the arguments to unsigned, and created intermediate variables.

You are right that it is delta out that is 16,000,000+. Still, the (x - in_min) * (out_max - out_min) is what overflows.

Did some mapping development because of similar problems. See the last post in this thread for an overflow protected map function.

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1289758376