/* * measure adc voltage accurately by taking multiple readings - see notes on this page * http://www.skillbank.co.uk/arduino/adc1.htm * * www.skillbank.co.uk Sept 2020 */ //Analog input and pin assignments const byte V1Pin = 1; // use will use analog pin 1 for voltage 1 int reading; //the value we read from the ADC // sampling parameters int nSamp = 16; // Number of Samples to take for each reading - best if it's a power of two. int interval = 7; // milliseconds interval between successive readings unsigned long sum1 = 0; // the total of nSamp readings from the ADC //calculating voltages int result; // calculated value of measured voltage in millivolts //float vScale=5; //choose the right scale to suit the reference you have chosen. //float vScale=3.3; //float vScale=2.56; //float vScale=1.1; //*** If you calibrate the system you can adjust the value of vScale to give more accurate readings. void setup() { Serial.begin(9600); analogReference(DEFAULT); // program is being tested on a 5V Arduino Micro Pro - 32U4 chip so this will be 5.0V //*** The chip on your Arduino - depending on type - is provided with SOME of the following reference voltages //DEFAULT: the default analog reference of 5 volts (on 5V Arduino boards) or 3.3 volts (on 3.3V Arduino boards) //INTERNAL: a built-in reference, equal to 1.1 volts on the ATmega168 or ATmega328 and 2.56 volts on the ATmega8 and 32U4 chip boards. //EXTERNAL: the voltage applied to the AREF pin. The Arduino Micro Pro does not have a pin to let you do this vScale = vScale * 1000/1024; //scale the reading to read in millivolts reading = analogRead(V1Pin); // dummy read to settle ADC Mux delay(5); } void loop() { sum1 = 0; //ready to start adding values //add up nSamp successive readings; for (byte count = 0; count < nSamp; count++ ) { reading = analogRead(V1Pin); // actual read sum1 = sum1 + reading; delay(interval); } // we print reading values to help with calibration Serial.print("Total of "); Serial.print(nSamp); Serial.print(" readings is: "); Serial.println(sum1); result = convReadings(sum1, nSamp, vScale); Serial.print("Voltage is "); Serial.print(result); Serial.println(" millivolts."); delay(2000); } // // Calculate average sensor reading, convert to voltage // int convReadings(int sum, int number, float scale) { sum = sum + (number >>1); // add a correction of 0.5 of the reading - see notes float mV = sum * scale; // mV = sum * (Vref * 1000 / 1024 ) mV = mV / number; //divide by number of readings last to keep precision high return ((int) mV); //return the result as an integer as decimal point values arent valid // (int) is a "cast" to change a float variable to an integer. Values after the decimal point are "cut off" so float 1.93 becomes int 1 }