Monday, March 9, 2015

Arduino Map: Floats or Ints?

The Arduino Map function is a very useful function. It allows you to map a input range from a analog sensor to another set of values. For instance, lets say we have a fuel gauge, with a varying resistance. We do a analogRead on the variable resistor, but then we want to map that to inches of fuel (we will convert inches to volume, and volume to gallons). The problem with the map command is it only works for integers, so:

h = map(sensorValue, 0, 1023, 0, 12);

results in a number like 5 inches, which would throw off our calculations. We need to be able to handle float values, and get a fractional result. If we had a function called mapfloat, we could do the following:

h = mapfloat(sensorValue, 0, 1023, 0, 12);

and get a result of 5.87 inches, which will make our fuel gauge more accurate. But the Arduino doesn't do floats with the map command, does it? No, it does not, so we will make our own function by adding the following chunk of code after the last } in your sketch:

float mapfloat(float x, float in_min, float in_max, float out_min, float out_max)
{
 return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

now our mapfloat call will return a float that more accurately describes the amount of fuel in our tank. Remember to specify the number of decimal places in your Serial.print command:

Serial.print(h, 2);

so now the complete sketch would look something like this:

int sensorPin = 0; // select the analog input pin for the potentiometer
int sensorValue = 0; // variable to store the value coming from the sensor

float h; // variable for height of liquid
float v; // variable for volume in cu. in.
float g; // variable for gallons
float r = 3; //radius

void setup() {
Serial.begin(9600);

}

void loop() {

sensorValue = analogRead(sensorPin);
Serial.print(sensorValue); //actual adc value
Serial.println(" ADC");
h = mapfloat(sensorValue, 171, 512, 12, 0);
Serial.print(h, 2); // fluid height (inches)
Serial.println(" inches");
v = h*PI*sq(r); // volume (cu. in.)
g= v * 0.004329; // gallons conversion
Serial.print(g, 2); // gallons
Serial.println(" gallons");
delay(5000);
}

float mapfloat(float x, float in_min, float in_max, float out_min, float out_max)
{
 return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

No comments:

Post a Comment