4

I am reading some sample code and they use this method of mapping data from IR sensors:

  sensor1 = analogRead(0); 
  adj_1 = map(sensor1, s1_min, s1_max, 0, 255);
  adj_1 = constrain(adj_1, 0, 255);

What is the point of using constrain here if adj_1 is already getting a value 0-255 from the map function?

  • 2
    Are s1_min and s1_max the guaranteed or the expected limits of the raw reading? map() does not constrain its output. – Edgar Bonet Mar 12 '15 at 10:01
  • @EdgarBonet what do you mean it doesn't constrain its output? Won't it return a value 0-255? – Michael Rader Mar 12 '15 at 10:30
  • Not necessarily, it’s just a linear mapping. – Edgar Bonet Mar 12 '15 at 10:36
  • Sorry, what does that mean? – Michael Rader Mar 12 '15 at 10:43
  • A linear function. – Edgar Bonet Mar 12 '15 at 10:55
7

From the official Arduino site:

[The map function] does not constrain values to within the range, because out-of-range values are sometimes intended and useful. The constrain() function may be used either before or after this function, if limits to the ranges are desired.

EDIT: Example.

You can try this by yourself with this code:

int val = 20;
val = map(val, 0, 10, 0, 100);

Although you set the upper bound of the value's range to 10, you passed an higher value than that and the function will linearly map it accordingly, resulting in an output of 200.

0

One caveat would be when mapping an input that ranges from 0 to 1023, since the Arduino is incapable of reading outside of this range there would be no need to constrain. You can check this by running through each iteration from 0 to 1023 and outputting the corresponding mapped value:

for (int i = 0; i < 1024; i++){
    Serial.print(i);
    Serial.print(",");
    Serial.println(map(i, 0, 1023, 0, 255));

}

Certainly, if your sensor reading offers a range smaller than 0 to 1023, then the constrain() function is definitely required, as per LoganBlade's example. Otherwise, it is not needed, but may still fall into the realm of best practice.

The only hiccup to this logic would be if you are mapping to decimal values (which doesn't make much sense since the function will return a long type anyway), in which case the Arduino's internal typecasting will round-down your lowest value mapping. Example:

map(0, 0, 1023, 8.9, 61.9));
>> 0 becomes 8

map(1023, 0, 1023, 8.9, 61.9));
>> 1023 becomes 61

Again, for the sake of best practice and the potential time wasted trying to find a mapping bug, using constrain() is better than skipping it.

  • Some sensors output high numbers when they are out of their normal range of operation or if something else is off. The STM VLS30X can suddenly output 8190 after having measured 487 (mm) for example. Therefore, constrain should be a must. See also a solution to the mapping error too many users make jetmore.org/john/blog/2011/09/… – Systembolaget Jul 20 '18 at 21:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.