Question about the MAP function

Good morning,
I would like to know a little more about some feature in the 'map' function. It maps a value from a low_level to high_level, toward another Lowlevel to Hilevel.
OK.
Now, what happens if:

  1. I define the Low_level as being for instance a value not equal to Zero ?
    My tests on working on a sketch about displaying on a LCD bargraph an analog value moving from 1v to 4 v show the values <1v as negative and thus the bargraph display I use becoms crazy.
  2. how to get the values <low_level to be ignored ?

Thanks a lot !

The map function is an integer rounding function and a shortcut for a linear interpolation so if your input value is outside input min/max then the resulting value is outside the min/max output bounds. (See that as solving y=ax+b and finding a and b so that the line goes through (Xmin, Ymin) and (Xmax,Ymax). If you feed an x that is not within the min max values then you are outside the mapping range. The integer rounding can also play tricks and only Xmax will lead to Ymax)

The constrain() function can help you ensure a value stays between min and max

Timezones vary round the world!

Since Arduino is open source you can go look at the definition - its in WMath.cpp in my installation:


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

As pointed out this is using integer math, which won't always be what you want (if using floating point ranges for example). Easy enough to write a float version if you want.

You can peruse the Arduino runtime on your install, or on Github for instance: https://github.com/arduino/ArduinoCore-avr/tree/master/cores/arduino

The map() functions doesn't constrain the input range or the output range. If the input value is outside the input range, the output value will be outside the output range.

There is a constrain() function to constrain to a range.

You could use the constrain() function on the input to map() or on the result of map(). It doesn't matter which.

If you would like a mapper function (actually a mapper object) that DOES constrain the input bounds. And works in floats as well..

Grab LC_baseTools from the IDE library manager.

#include <mapper.h>   // To include it.

mapper percentMapper(0,1023,0,100);   // A mapper that takes an analog input and maps to percent.
mapper servoMapper(0,1023,0,180);     // A mapper that takes an analog input and maps to servo input.

// Typical example..
val = analogRead(A0);         // Grab an analog value
deg = servoMapper.map(val);   // map it to the range you want.
myServo.write(round(deg));    // Servos like ints.

Or something along those lines..

Good luck!

-jim lee

Thanks JimLee, I'll have a look.
I managed with Constrain, to keep only the span I want, and Max to get rid of values under the minimum value I am interested.
I had to do this because the custom lib I used from a guy named Robojax, is pretty rigid and is a blackbox.
Now it all works.
Last, I still need a float mapping, to have a divider go from 3.75 to 4 according to Bat measurement. It could go without it of course, but it is a good way to learn in details.
Thanks a lot
Have a good day !
Billy

Replace long by float in this function and you got it


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

(And give the function another name like mapf())

MUCH simpler.
I found a very simple way to avoid looking for a float map function.
I just went mapped the values using their values from 0 to 1023 after applying a proper division.
This way no fractions needed. map is easy.
Then I Just transform back the values I got this way in true 0 to 5V values, by a reverse multiplication.
It is simple, and of course works well in my case.
Thanks for the various helps.

Good !

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.