Skip to content
Jim Lee edited this page Mar 20, 2020 · 18 revisions

Abstract:

A very common issue one runs across when programming is unit translation and value limiting. You are given some value that covers an arbitrary range and you need to "map" this value to a unit that you are looking for. And, at the same time, limit the range of the inputted data to "sane" values.

That was really wordy, lets try an example. You would like to make a digital volt meter. You have an analog input that gives values from 0 to say.. 1024. Next you need to find what the limits are of your circuit. At your lowest voltage, what number do you read from the analog input? What's your highest voltage reading? This gives us 4 values.

Low voltage - corresponding analog value, analogA.
High voltage - corresponding analog value, analogB.

From this we plug all four into a mapper object.

mapper myMapper(analogA, analogB,lowVoltage,highVoltage);

Now that we have our mapper, we can read analog values and use our mapper object to calculate our voltage values.

float voltageValue = myMapper.Map(analogValue);

So, if this is such a handy thing, why doesn't the Arduino library have one already? It does! But the Arduino one is all done in integers and doesn't save any of its calculation data between mappings. This version is written to use doubles and does as much of its calculation in the constructor as possible. This is to save time during use. And yes, I know the Arduino can't do doubles. But no one said this is restricted to Arduinos did they? As chips get more powerful more systems will use double precision and this version will automatically use this if its available.

mapper:

Constructor:

mapper(void);
No parameters, creates a mapper that maps 0..1 -> 0..1. This is default used when one does not know the domain or range of a mapper at creation time.

mapper(double x1,double x2,double y1,double y2);
The standard constructor. The inputted values will range from x1..x2 and these will be mapped to the output range of y1..y2. There are no restrictions on the entered values. An inputted range from high to low can just as easily map to a low to high as a high to low.

Other methods:

double Map(double inNum);
Maps a inputted value to its resultant mapped value. If the inputed value is below the programmed range, then the lower programmed range is used instead. Also, if the inputted value is greater than the programmed range, the greater programmed range is used.

void setValues(double x1,double x2,double y1,double y2);
Used internally to set the values of the ranges. Can also be used to change the ranges of a mapper.

double getSlope(void);
double getMinX(void);
double getMaxX(void);
double getIntercept(void);
These four are seldom used. Seeing that this is a liner mapper, it calculates the formula of a line : y=mx+b, or y = slope * x + y intercept. If you are interested, you can see what these different values are by calling these methods.

void printMap(void);
Used for printing the information of a mapper to the serial port of an Arduino. Typically only used for debugging and the last time I checkedm it was commented out in the source code.

And that pretty much sums it up for liner mappers..

Clone this wiki locally