/* Read internal voltage reference to calculate the Vcc voltage.
* Read internal temperature sensor.
* Will use them to calibrate the clock frequency, which depends on voltage and temperature.
*/
void setup() {
Serial.begin(9600);
}
void loop() {
int intRefCode=readIntRefCode();
Serial.print("intRefCode: ");
Serial.print(intRefCode);
Serial.print("; ");
float Vcc=intRefCodeToVcc(intRefCode);
Serial.print("Vcc: ");
Serial.print(Vcc,3);
Serial.print(" V; ");
int intTempCode=readIntTempCode();
Serial.print("intTempCode: ");
Serial.print(intTempCode);
Serial.print("; ");
float intTemp=intTempCodeToTemp(intTempCode);
Serial.print("Temp: ");
Serial.print(intTemp,3);
Serial.print("°C; ");
Serial.println();
}
int readIntRefCode(void) { //convert internal 1.1 V against Vcc
//Set reference to Vcc, align to left, set input to internal 1.1 V:
ADMUX = (0<<REFS1) | (1<<REFS0) | (0<<ADLAR) | (1<<MUX3) | (1<<MUX2) | (1<<MUX1) | (0<<MUX0);
delay(50); //wait for Vref to settle
ADCSRA |= (1<<ADSC); //start conversion
while (ADCSRA & (1<<ADSC)); //bit ADSC in ADCSRA becomes 0 when conversion is complete
int i=ADC; //read result, but discard and do another conversion
ADCSRA |= (1<<ADSC);
while (ADCSRA & (1<<ADSC));
return ADC; //read ADCL and ADCH and return result
}
float intRefCodeToVcc(int code) { //convert AD code to Vcc, in V
const float intRefVoltage=1.100; //voltage of the internal reference, measured with voltmeter, in V
return (intRefVoltage*1024)/code;
}
int readIntTempCode(void) { //read internal temperature code
//Set reference to 1.1 V, align to left, set input to internal temperature sensor:
ADMUX = (1<<REFS1) | (1<<REFS0) | (0<<ADLAR) | (1<<MUX3) | (0<<MUX2) | (0<<MUX1) | (0<<MUX0);
delay(50); //wait for Vref to settle
ADCSRA |= (1<<ADSC); //start conversion
while (ADCSRA & (1<<ADSC)); //bit ADSC in ADCSRA becomes 0 when conversion is complete
int i=ADC; //read result, but discard and do another conversion
ADCSRA |= (1<<ADSC);
while (ADCSRA & (1<<ADSC));
return ADC; //read ADCL and ADCH and return result
}
float intTempCodeToTemp(int code) { //convert AD code to temperature, in °C
const int c25=352; //code at T=25°C
const float a=0.78199; //slope
return 25.0+a*(code-c25);
}