Wednesday, January 27, 2016

Utilizing the Arduino ADC Internal Reference

In this video we look at the ADC internal reference in an Arduino, why / when would you use it, how to ensure you get good measurement accuracy when using it, and how to use it to check your battery voltage.



**********************Arduino Code from the video****************************
float iREF = 1.08; //internal reference cal factor

void setup() {
  // put your setup code here, to run once:
  analogReference(EXTERNAL);
  //burn some ADC readings after reference change
  for(int i=0; i<8; i++) analogRead(A0);
  Serial.begin(57600);
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(3000);
  Serial.print("Measured battery voltage is: ");
  Serial.println(fReadVcc());
  Serial.println();
}

//This function uses the known internal reference value of the 328p (~1.1V) to calculate the VCC value which comes from a battery
//This was leveraged from a great tutorial found at https://code.google.com/p/tinkerit/wiki/SecretVoltmeter?pageId=110412607001051797704
float fReadVcc() {
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(3); //delay for 3 milliseconds
  ADCSRA |= _BV(ADSC); // Start ADC conversion
  while (bit_is_set(ADCSRA,ADSC)); //wait until conversion is complete
  int result = ADCL; //get first half of result
  result |= ADCH<<8; //get rest of the result
  float batVolt = (iREF / result)*1024; //Use the known iRef to calculate battery voltage
  return batVolt;
}

2 comments:

  1. the code below does exactly what i need. But is not precise enough. Therefore I would like to use the internal ref. My range on AO is 95 mvolt to 650 mvolt so that's good. Can you change this code to use the 1.086 ref?

    I can't figure it out, I watched them all your movies many times. Can you please help me !?


    // 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 = 10; // Analog output pin that the LED is attached to
    const int set = 3;

    int led = 2;
    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);
    pinMode(set, INPUT);
    // read the analog in value:
    sensorValue = analogRead(analogInPin);
    // map it to the range of the analog out:
    outputValue = map(sensorValue, 0, 1023, 0, 255);
    // change the analog out value:
    analogWrite(analogOutPin, outputValue);
    }

    void loop() {
    if(digitalRead(set)== HIGH){
    // read the analog in value:
    sensorValue = analogRead(analogInPin);
    // map it to the range of the analog out:
    outputValue = map(sensorValue, 0, 1023, 0, 255);
    // change the analog out value:
    analogWrite(analogOutPin, outputValue);
    }
    else{
    // 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 2 milliseconds before the next loop for the analog-to-digital
    // converter to settle after the last reading:
    delay(4);
    }
    }

    ReplyDelete