Arduino map() method - why?
Asked Answered
M

2

8

I was just looking at some example code and came across a line, I don't fully understand why it needs to be done. I understand that you are taking in an analog value. This value is between 0 and 1024 apparently? Why is this? Why does the output need to be mapped between 0 and 255? What dictates the arguments that are used here? The line in question :

   // map it to the range of the analog out:
      outputValue = map(sensorValue, 0, 1024, 0, 255); 

Highlighted in the code :

created 29 Dec. 2008
 Modified 4 Sep 2010
 by Tom Igoe

 This example code is in the public domain.

 */

// These constants won't change.  They're used to give names
// to the pins used:
const int analogInPin = A0;  // Analog input pin that the potentiometer is attached to
const int analogOutPin = 9; // Analog output pin that the LED is attached to

int sensorValue = 0;        // value read from the pot
int outputValue = 0;        // value output to the PWM (analog out)

void setup() {
  // initialize serial communications at 9600 bps:
  Serial.begin(9600); 
}

void loop() {
  // read the analog in value:
  sensorValue = analogRead(analogInPin);            
  **// map it to the range of the analog out:
  outputValue = map(sensorValue, 0, 1024, 0, 255);**  
  // change the analog out value:
  analogWrite(analogOutPin, outputValue);           

  // print the results to the serial monitor:
  Serial.print("sensor = " );                       
  Serial.print(sensorValue);      
  Serial.print("\t output = ");      
  Serial.println(outputValue);   

  // wait 10 milliseconds before the next loop
  // for the analog-to-digital converter to settle
  // after the last reading:
  delay(10);                     
}

Thanks very much for the replies.

Meatman answered 26/1, 2012 at 19:34 Comment(0)
P
12

The analog output only has an acceptable range between 0 and 255.

Therefore, the value has to be mapped within the acceptable range.

Documentation for map method is here: http://arduino.cc/en/Reference/map

Because the Arduino has an analogRead resolution of 0-1023, and an analogWrite resolution of only 0-255, this raw data from the potentiometer needs to be scaled before using it...

This explanation comes from an Arduino sensor tutorial(under the 'Code' header): http://arduino.cc/en/Tutorial/AnalogInOutSerial

Parton answered 26/1, 2012 at 19:39 Comment(5)
One could argue, that integer division by 4 would do the work too, but map() works fine as well.Mechling
Why is analogInput allowed to be 0-1024 if output must be between 0-255?Meatman
@SimonKiely I am not certain of the technical limitation or the design decisions leading to those limitations. If I were to guess, it has to do with the fact that the microcontroller has limitations for a variety of reasons such as size, memory, etc, and the designers decided that a higher input resolution would be more useful than a high output resolution.Parton
@SimonKiely This link explains the input resolution: arduino.cc/en/Tutorial/AnalogInputPins I am sure that the output has a similar limitation.Parton
Thanks very much, very interesting and informative responses ! :)Meatman
C
2

Why? Sometimes you will need to translate 0 to 1023 into a range of values OTHER THAN 0 to 1023 and the map() function is an attempt to make this easier for you, the engineer. I explain one situation in some detail on this forum post, where I am able to convert the 0 to 90 or 100 indexes of an array having values of 0 to 1023 integers into an x-y graphical plot!

idx ranges from 0 to some value near 100.
test[idx] is the ADC values, so range from 0 to 1023.

int x1= map(1, 0, idxmax, 0, 160);
int y1= yf - 2 - map(test[1], TPS_floor[_tps], TPS_max[_tps], 0, dy);
for(idx=0; idx < idxmax-1;  ){
    int x0 = map(idx, 0, idxmax, 0, 160);
    int y0 = yf - 2 - map(test[idx], TPS_floor[_tps], TPS_max[_tps], 0, dy);
    tft.drawLine(x0, y0, x1, y1, YELLOW);
    idx++;
    x1 = map(idx+1, 0, idxmax, 0, 160);
    y1 = yf - 2 - map(test[idx+1], TPS_floor[_tps], TPS_max[_tps], 0, dy);
}

So the above code translates an x of 0-~100 and y of 0-1023 into this: map() translated an array's index and its values into that plot!

My build's write up is here. (and as of 7-31-2013, is in progress)

I, personally, find that a clear illustration of "why" is the best explanation. I hope that my answer helps anyone questioning this "why" as to ... why.

Che answered 1/8, 2013 at 8:31 Comment(2)
Very interesting and informative. Still working my way through the forum post but I'm finding this very absorbing!Meatman
Thanks, Simon! Think of map() as some kind of scaling function...? You're welcome to ask questions, etc, on that forum. :)Che

© 2022 - 2024 — McMap. All rights reserved.