# map() function

I have been researching the map function and its issues with truncating integers and found this code

``````void setup()
{
Serial.begin(115200);
}

void loop()
{
long y;

Serial.println("TEST 0 =============================");

y = map(10,0,1023,0,0);
Serial.println(y);
y = NewMap(10,0,1023,0,0);
Serial.println(y);

Serial.println();

y = map(10,0,0,0,0);
Serial.println(y);
y = NewMap(10,0,0,0,0);
Serial.println(y);

Serial.println();

y = map(0,0,0,0,0);
Serial.println(y);
y = NewMap(0,0,0,0,0);
Serial.println(y);

Serial.println();

y = map(-1,10,0,0,10);
Serial.println(y);
y = NewMap(-1,10,0,0,10);
Serial.println(y);

Serial.println();

// BUG should return 5
y = map(1,-2147483647L,2147483647L,0,10);
Serial.println(y);
y = NewMap(1,-2147483647L,2147483647L,0,10);
Serial.println(y);

Serial.println();
Serial.println("TEST 1 =============================");
Serial.println("y = map(i, 0, 1023, -123456789, 123456789);");
Serial.println();

for (int i=0; i<= 1024; i+=103)
{
y = map(i, 0, 1023, -123456789, 123456789);
Serial.print(i);
Serial.print(" old => ");
Serial.print(y);
y = NewMap(i, 0, 1023, -123456789, 123456789);
Serial.print("\t new => ");
Serial.println(y);
}

Serial.println();
Serial.println("TEST 2 =============================");
Serial.println("y = map(i, 0, 1000000000, -100, 100);");
Serial.println();

for (long i=0; i<=1000000000; i+=100000000)
{
y = map(i, 0, 1000000000, -100, 100);
Serial.print(i);
Serial.print(" old => ");
Serial.print(y);
y = NewMap(i, 0, 1000000000, -100, 100);
Serial.print("\t new => ");
Serial.println(y);
}

Serial.println();
Serial.println("TEST 3 =============================");
Serial.println("y = map(i, 0, 1000000, -1000000, 1000000);");
Serial.println();

for (long i=0; i<= 1000000; i+=100000)
{
y = map(i, 0, 1000000, -1000000, 1000000);
Serial.print(i);
Serial.print(" old => ");
Serial.print(y);
y = NewMap(i, 0, 1000000, -1000000, 1000000);
Serial.print("\t new => ");
Serial.println(y);
}

Serial.println();
Serial.println("TEST 4 =============================");
Serial.println("y = map(i, 0, 1000000, 1000000, -1000000);");
Serial.println();

for (long i=0; i<= 1000000; i+=100000)
{
y = map(i, 0, 1000000, 1000000, -1000000);
Serial.print(i);
Serial.print(" old => ");
Serial.print(y);
y = NewMap(i, 0, 1000000, 1000000, -1000000);
Serial.print("\t new => ");
Serial.println(y);
}

Serial.println();
Serial.println("TEST 5 =============================");
Serial.println("y = map(i, 0, 10, 0, 1);");
Serial.println();
for (int i=0; i <= 10; i++)
{
y = map(i, 0, 10, 0, 1);
Serial.print(i);
Serial.print(" old => ");
Serial.print(y);
y = NewMap(i, 0, 10, 0, 1);
Serial.print("\t new => ");
Serial.print(y);
y = BalancedMap(i, 0, 10, 0, 1);
Serial.print("\t B => ");
Serial.println(y);
}

Serial.println();
Serial.println("y = map(i, 0, 10, 0, 1);");
Serial.println();

for (int i=0; i <= 10; i++)
``````

I was just wondering if this was the best solution around or has anybody got a better solution?

Please explain the problem. It is not self evident. Why is it a problem in your particular case? Do you have code that it is breaking?

There's a float version of the map function in LC_baseTools you could try. (see the library manager)

-jim lee

Yeah, or you can scale and/or translate using plain old math. That's all that map() uses internally.

This is the section of the code which seems to be busting. The problem seems to be at the half way points of both the fade up and fade down. If the fpwm is 4096 and we are in fade down situation it will reach about half way then shoot up to strange numbers 6000! Have no idea where the number originates from and after lot of debugging think its the map function. I am using an adafruit 16channel pwm driver.

``````void SetLed(int fpin,                  //Pin number
unsigned long ftime,       //Current time in millis
unsigned long fstart,      //Start time of LED channel in millis
unsigned long fperiod,     //Total photo period in millis
unsigned long fstop,       //Stop time of LED channel in millis
int fpwm,                  //Max value of brightness 0-4096
int fVpin,                 //ProgressBar Blynk widget
int fVpin2)                //Brightness bytes Blynk widget
{
//ON PERIOD//
if (ftime > fstart + ffadeup && ftime <= fstart + fperiod - ffadedown)
{
pwm.setPin(fpin, fpwm, false);           //set pin to max pwm set
progress = round(fpwm*100/4096);  //turn the pwm into %
Blynk.virtualWrite (fVpin, progress);  // write the % to Blynk
Blynk.virtualWrite (fVpin2, fpwm);     // write pwm bytes to Blynk
Serial.println("ON");
}
else if (ftime > fstart && ftime <= fstart + ffadeup)
{
brightness = map(ftime - fstart, 0, ffadeup, 0, fpwm);  //map pwm to time
pwm.setPin(fpin, brightness, false);  //set pin to mapped pwm
progress = round(brightness*100/4096);  //convert mapped pwm to %
Blynk.virtualWrite (fVpin, progress);  //write % to Blink
Blynk.virtualWrite (fVpin2, brightness);  //write mapped pwm bytes to Blynk
}
else if (ftime > fstart + fperiod - ffadedown && ftime <= fstart + fperiod)
{
brightness = map(ftime - fstart - fperiod + ffadedown, 0, ffadedown, fpwm, 0);
pwm.setPin(fpin, brightness, false);
progress = round(brightness*100/4096);
Blynk.virtualWrite (fVpin, progress);
Blynk.virtualWrite (fVpin2, brightness);
}
//OFF PERIOD//
else if (ftime > fstop || ftime < fstart)
{
pwm.setPin(fpin, 0, false);
Blynk.virtualWrite(fVpin, 0);
Blynk.virtualWrite (fVpin2, 0);
Serial.println("OFF");
}
}
``````

@aarg I would be very interested in learning your way just using maths could you give an example please

Wait.. are you fading an RGB LED from color to color over time?

-jim lee

Proietti:
@aarg I would be very interested in learning your way just using maths could you give an example please

It helps to look at the source:

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

Suppose you call this very common case:

PWMout = map(ADCin, 0, 256, 0, 1024);

internally this looks like

return (x - 0) * (256 - 0) / (1024 - 0) + 0;

which reduces to

return x * 256 / 1024;

further reduces to

return x / 4;

thus we could have just said

@jimlee no not rgb but high power leds for my aquarium. The pwm pins of the adafruit driver connect to meanwell drivers

@aarg that math looks very interesting. I will try to work on that tomorrow. Thanks

Can you explain, in human, what your trying to do?

-jim lee

aarg:
PWMout = map(ADCin, 0, 256, 0, 1024);

thus we could have just said

I think you got one of them backwards.

Converting 10-bit to 8-bit is easier done this way

Leo..

Wawa:
I think you got one of them backwards.

Converting 10-bit to 8-bit is easier done this way

Leo…

Better to write it it the more natural way with a division, rather than a shift, and let the compiler do the legwork.

Ok I have tried the mathematical way and the fadeup works perfectly. The fadedown does not. When the fade down is triggered the 4096 byte(which is the 100% value of the fpwm) jumps to some 8000 number. I suspect it has something to do with the fact that 0-fpwm within the formula gives a negative number. Any ideas on how to resolve this?

``````    //brightness = map(ftime - fstart, 0, ffadeup, 0, fpwm); //Original map function

long x = ftime - fstart;
brightness = x * fpwm / ffadeup;
pwm.setPin(fpin, brightness, false);
``````

``````    //brightness = map(ftime - fstart - fperiod + ffadedown, 0, ffadedown, fpwm, 0); //Original map function