AVccの揺れを補償してやる必要がある。
http://hacking.majenko.co.uk/node/57
http://code.google.com/p/tinkerit/wiki/SecretVoltmeter
によると、
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 = 1126400L / result; // Back-calculate AVcc in mV
return result;
}
という関数を作って、
unsigned int ADCValue;
double Voltage;
double Vcc;
Vcc = readVcc()/1000.0;
ADCValue = analogRead(0);
Voltage = (ADCValue / 1024.0) * Vcc;
という形で、対処してやる必要があるようだ。_BV()はビットシフトするマクロでREFS0,MUX3,MUX2,MUX1,ADSCは
arduino-1.0.1\hardware\tools\avr\avr\include\avr\iom328p.hに定義されている。
ADC周りのレジスタについては
http://www9.plala.or.jp/fsson/NewHP_elc/AVR/Avr_ADC.html
を参照のこと。
これを踏まえて、readVccにコメントを付けるとするなら、
long readVcc() {
long result;
// Read 1.1V reference against AVcc
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);// ARefに1.1Vを出力し,基準電圧1.1Vをアナログ入力チャンネルに指定
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // 変換開始
while (bit_is_set(ADCSRA,ADSC));// 変換完了待ち
result = ADCL;// 変換結果取得(下位8bit)
result |= ADCH<<8;// 変換結果取得(上位2bit)
result = 1126400L / result; // 1126400 / ( 1024 * 1.1 / AVcc ) = AVcc*1000(mV)
return result;
}
という感じか。