Even one failure of a sensor can result in a disaster for your robot. In this post, I explored the method to make accurate ADC readings with Arduino to eliminate the failures of analog sensors used in robotics applications.
This method is applied to analog sensors such as temperature, light, etc. For accurate readings, you need to take into account the actual value of the power supply voltage.
Of course, I need a development board to test this method. Roboticists, electronicists, hobbyists, hackers, artists seem to have at least one point in common. It is called Arduino. So, to test the method, I used an Arduino UNO board. The same board that I used to build this self-driving robot.
Table of Contents
ToggleAccurate ADC readings
Arduino UNO can be powered from a USB port, one or more batteries and from an AC-to-DC adapter. So far everything is simple. Very simple.
But, when you got the Arduino plugged into one of its compatible power supply sources, you supposedly have a constant voltage to feed the Arduino board. Wrong!
The voltage from the USB ports and batteries fluctuates. The voltage output from an AC-to-DC adapter is more stable. For example, the USB port sometimes outputs a voltage of 5.12V and sometimes 5.14V.
When Arduino is connected to batteries, the things are even worse. The voltage of the batteries is likely to decrease over time. In this situation, you should check often the Vcc voltage that feeds Arduino.
The fluctuations of voltage in the electric power supply influence the results of the conversion from the ADC to a voltage value.
The analog sensors
An analog sensor output a voltage as a function of the supply voltage as their sensed value. These sensors can be temperature sensors, light sensors, accelerometer sensors, gas sensors, etc.
With Arduino measure the voltage output of the sensor and convert it into values for whatever is being used the sensor to measure. Almost all the examples on the Internet that converts an ADC value into a voltage use this code:
C++
1
2
3
4
5
6
|
unsigned int ADCValue;
double Vcc;
double Voltage;
ADCValue = analogRead(0); //ADCValue is the voltage value on the analog pin, the voltage at the ends of the sensor
Voltage = (ADCValue / 1024.0) * Vcc; //Vcc is the supposed value of the power supply voltage (PSV). If the Arduino is powered by USB, Vcc is considered 5V
|
This code works great if the Arduino’s power supply source returns a constant voltage. The Vcc value in the above formula. Otherwise, you have to know exactly what your supply voltage is.
Any Arduinos based on 328 or 168 chips have integrated a function to measure the power supply voltage.
I found this very useful code on tinkerit. So, your code should look like the below code and would return more accurate readings for analog sensors.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
unsigned int ADCValue;
double Voltage;
double Vcc;
void setup() {
  Serial.begin(9600);
}
void loop() {
Vcc = readVcc()/1000.0;
ADCValue = analogRead(0);
Voltage = (ADCValue / 1024.0) * Vcc; //For accurate measurements, divide the ADC value by the ADC maximum value and multiply by the resultant ADV value.
}
long readVcc() {
  long result;
  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA,ADSC));
  result = ADCL;
  result |= ADCH<<8;
  result = 1125300L / result; // Back-calculate AVcc in mV
  return result;
}
|