Arduino Programming – Map and smooth values

I’ve created two code examples. One that shows how to use the Arduino map() function to change a variable number from one range to another. We also apply the constrain() function. The other example shows how to smooth Analog Input values by taking multiple samples and average those.

Level: beginner with Arduino. (Basic knowledge of programming principles like if/else and variables).

Map.ino

/* 
  Mapping example

  Re-map a number from one range to another. 

  created 01-12-2009 by kasperkamperman.com
*/

const int sensorPin = 0;    // the pin that the potmeter is attached to
int sensorValue     = 0;    // store the value coming from the sensor
int mappedValue;            // store the new value

void setup() {
  // opens serial port, sets data rate to 57600 bits per second
  Serial.begin(57600);
}

void loop() {
  // read the value from the sensor
  // the range from an analog input is 0 - 1023
  sensorValue = analogRead(sensorPin);  

  // print the value
  Serial.print("sensorValue                                 : ");
  Serial.println(sensorValue);   

  // map(value, fromLow, fromHigh, toLow, toHigh)
  mappedValue = map(sensorValue, 0, 1023, 0, 255);

  Serial.print("map to 0 - 255                              : ");
  Serial.println(mappedValue);  

  // invert a value is possible too 
  mappedValue = map(sensorValue, 0, 1023, 255, 0);

  Serial.print("map to 255 - 0                              : ");
  Serial.println(mappedValue);  

  // or negative values
  mappedValue = map(sensorValue, 0, 1023, -127, 128);

  Serial.print("map to -127 - 128                           : ");
  Serial.println(mappedValue);  

  // only watch a certain part of the sensor values
  // for example when using a sensor that doesn't cover the whole
  // range
  mappedValue = map(sensorValue, 512, 712, 0, 100);
  Serial.print("map 512 - 712 to 0 - 100                    : ");
  Serial.println(mappedValue);

  // constraining the sensorValue can be usefull to prevent negative values
  sensorValue = constrain(sensorValue, 512, 712);  
  Serial.print("constrained sensorValue                     : ");
  Serial.println(sensorValue);

  mappedValue = map(sensorValue, 512, 712, 0, 100);
  Serial.print("map 512 - 712 to 0 - 100 ( with constrain ) : ");
  Serial.println(mappedValue); 

  // division between next read
  Serial.println("------------------------------------------------");

  // wait for 1000 milliseconds ( 1 second ) to read every second
  delay(1000);
}

Analog_smooth.ino

/* 
  Smoothing example

  Read the analog input and smooth out the result by averaging
  the result with past values of the input.

  The more samples to longer it takes to reach the final value. 
  4/5 samples give a smooth and reactive enough result. 

  Simpler algorithm than the smoothing included with the Arduino 
  examples.

  based on : Analog Smoothing Algorithm by Tom Igoe 
  <http://www.tigoe.net/pcomp/code/category/arduinowiring/41>

  created 05-01-2010 by kasperkamperman.com
*/

const int sensorPin = 0;    // the pin that the potmeter is attached to

int sensorVal       = 0;    // store the value coming from the sensor
int smoothedVal     = 0;    // smoothed result
int samples         = 4;    // amount of samples

void setup() {
  Serial.begin(57600);
}

void loop() {

  // read the value from the sensor
  // the range from an analog input is 0 - 1023
  sensorVal = analogRead(sensorPin); 

  smoothedVal = smoothedVal + ((sensorVal - smoothedVal)/samples);

  // print the original value and the smoothedValue
  Serial.print(sensorVal); 
  Serial.print(", ");
  Serial.println(smoothedVal); 

  // slow down amount of readings and prints
  delay(100); 

}

3 thoughts on “Arduino Programming – Map and smooth values”

  1. Hi there,

    I have a situation where I’d like to invert the values either side of a centre point,
    it’s an analog value ranging from 0-1000 with a centre point of 500.
    I’d like to make the analog read of 0-499 to become 499 -0 and 501-1000 to become 1000-501. This so that a lo/high threshold level will work in the opposite direction.
    I’m using a Phidget 1111 and need to control proximity, the closer you are the range is closer to the centre point and further away results in values in the extreme range. Inverting either side should make a rule better for this particular application.
    Any help would be much appreciated.
    cheers
    Kenneth

  2. Actually if you insert a value for the sensor read, say sensorVal = 50, then run the program rather than 50 being the average value the program returns 47. Not good enough for me.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.