google-site-verification: google3bd66dd162ef54c7.html

外付け部品無しでArduinoの電源電圧を測定する

 ArduinoのCPUのADコンバーターの入力セレクタで面白い機能を作る話の続きです。前回はCPU温度計を作りましたが、今回は電源電圧を測定してみます。

▼測定原理
ADCのVrefとINPUTの関係図
 Arduinoで電源電圧を測定する場合、左の図のようにVccの電圧を抵抗で分圧してADCに入力。ADCのVrefには内部基準電圧である1.1Vを使うのが普通の方法です。

 ところで、ADコンバーターの入力は1.1Vの基準電圧に接続出来るようになっています。ということは、右の図のようにVrefにVccを接続することで、1.1Vに対するVccの比率を知ることが出来ます。1.1Vに対する比率が判るということはVccの絶対値が判る、つまり電源電圧の測定が出来るということになります。

 右の図の回路にすると、分圧抵抗が不要です。さらに、この状態はCPU内のレジスタ操作だけで作ることが可能なので、配線は不要です、またI/Oピンすら使わないで済ませることが出来ます。

 まあいろいろな事情で、こういうことが出来るようになっているのだと思いますが、入っているなら使わないと損です。

 ということで、いきなりプログラムというかスケッチです。

▼電源電圧読み出しデモプログラム
/*
 CPU温度センサーと電源電圧の読み出し、表示デモ
 2014/7/19 ラジオペンチ
 http://radiopench.blog96.fc2.com/
 */

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  pinMode(13, OUTPUT);
  lcd.begin(16, 2);
  lcd.print("Starting...");
  delay(1000);
  Serial.begin(9600); 
}

void loop() {
  float temp, Vcc;
  digitalWrite(13, HIGH);
  temp = cpuTemp();                  // CPU温度測定
  Vcc  = cpuVcc();                   // 電源電圧測定
  digitalWrite(13, LOW);

  Serial.print("Temp= ");           // シリアルに温度を出力
  Serial.print(temp,1);
  Serial.print(", Vcc= ");          // シリアルにVccを出力
  Serial.println(Vcc,2);

  lcd.setCursor(0, 0);               // 液晶に表示
  lcd.print("Temp= ");
  lcd.print(temp,1);                 // 温度、小数点以下1桁表示
  lcd.print("c ");                   // ゴミ消し
  lcd.setCursor(0, 1);
  lcd.print("Vcc = ");               // Vcc
  lcd.print(Vcc,2);
  lcd.print("V ");                   // ゴミ消し

  delay(500);
}

// 流用する場合は以下を全てコピーする

float cpuTemp(){                     // CPU温度測定関数
  long sum=0;
  adcSetup(0xC8);                    // Vref=1.1V, input=ch8
  for(int n=0; n < 100; n++){
    sum = sum + adc();               // adcの値を読んで積分
  }
  return (sum * 1.1/102.4)- 342.5;   // 温度を計算して戻り値にする。-342.5は要調整
}

float cpuVcc(){                      // 電源電圧(AVCC)測定関数
  long sum=0;
  adcSetup(0x4E);                    // Vref=AVcc, input=internal1.1V
  for(int n=0; n < 10; n++){
    sum = sum + adc();               // adcの値を読んで積分
  }
  return (1.1 * 10240.0)/ sum;       // 電圧を計算して戻り値にする
}

void adcSetup(byte data){            // ADコンバーターの設定
  ADMUX = data;                      // ADC Multiplexer Select Reg.
  ADCSRA |= ( 1 << ADEN);            // ADC イネーブル
  ADCSRA |= 0x07;                    // AD変換クロック CK/128
  delay(10);                         // 安定するまで待つ
}

unsigned int adc(){                  // ADCの値を読む
  unsigned int dL, dH;
  ADCSRA |= ( 1 << ADSC);            // AD変換開始
  while(ADCSRA & ( 1 << ADSC) ){     // 変換完了待ち
  }
  dL = ADCL;                         // LSB側読み出し 
  dH = ADCH;                         // MSB側
  return dL | (dH << 8);             // 10ビットに合成した値を返す
}
 せっかくなので、前の記事のCPU温度センサー読み出しプログラムと合体させ、サブルーチンを共用するようにしました。

▼実行するとシリアルモニタに温度と電圧を表示
シリアルモニタ

▼液晶シールドがあれば
Arduinoで温度と電圧測定
 こんなふうに表示します。I/Oコネクタに何も接続しなくても動くので、初心者にもお勧めしたいプログラムです。なお、動作確認はArduino1.0.5で行っています。

 温度計はCPUのチップの温度を測っているので、電源ON直後と比べると5℃くらい徐々に温度が上昇します。ポートにたくさん電流を流したりすると更に温度上昇するはずです。ということで、気温を正確に測定することは出来ません。

 温度測定プログラムはcpuTemp()、電源電圧測定プログラムはcpuVcc()という名前の関数で、それぞれの測定結果を浮動小数点形式で返してきます。プログラムリストの44行目以降を全部コピペしてこの関数を呼べば温度や電圧を手軽に測定できるようになります。何か他の目的のプログラムに混ぜて使うと、面白いことが出来ると思います。

 以上、2回に分けてArduino UNOのCPU(ATmega328P)のADコンバーターのちょっと面白い使い方について紹介しました。

 このあたりの話は日本語のWebではあまり見かけないのですが、記事を書きながら検索してみると、同じようなことをやっている英語の資料がいろいろ出てきました。代表的と思われる資料のリンクを以下に置いておきます。

Internal Temperature Sensor, Arduino Playground
AVR122: Calibration of the AVR's internal temperature reference
Can Arduino measure its own Vin?, Arduino Forum
関連記事

コメントの投稿

管理者にだけ表示を許可する

No title

こんにちは、edyと申します。
LCDシールドを作ったので、スケッチをコピーさせていただきました。無事動きました。
Arduinoは初心者ですので、これからもいろいろと参考にさせていただきます。
ありがとうございました。

edyさん今晩は

うまく動いたみたいで良かったです。

adyさんって、PSoCやられてる、迷走の果ての方ですよね。以前からブログ拝見してます。

今後ともよろしくお願い致します。
カレンダー
03 | 2017/04 | 05
- - - - - - 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 27 28 29
30 - - - - - -
プロフィール

ラジオペンチ

Author:ラジオペンチ
電子工作を中心としたブログです。たまに近所(東京都稲城市)の話題など。60過ぎて視力や器用さの衰えを感じつつ日々挑戦!
コメントを入れる時にメールアドレスの記入は不要です。なお、非公開コメントは受け付けていません。

記事が気に入ったらクリックを!
最新記事
カテゴリ
最新コメント
リンク
FC2カウンター
検索フォーム
月別アーカイブ
RSSリンクの表示
QRコード
QRコード