Arduinoで遊ぶページ

Arduinoで遊んだ結果を残すページです。
garretlab
Arduino(ATmega328)内蔵温度センサの実験

概要

Arduino(ATmega328)に内蔵されている温度センサの実験をします。

ATmega328のデータシートを眺めていると、温度センサが内蔵されていることに気が付きました。参照電圧を1.1Vに設定して、アナログポートの8番の値を読み取ると、温度を取得できるようです。Arduinoに何も接続することなく試せるためさっそく実験してみました。

実験その1

まずは、analogRead()で8番ポートの値を読み取ってみました。出力された値を見ると、常に1023でした。

Webで調べてみると、現状のanalogRead()では、8番ポートの値を読み取れないことがわかりました。問題はanalogRead()の以下のコードです。

ADMUX = (analog_reference << 6) | (pin & 0x07);

pinはanalogRead()で指定した、値を読み取りたいアナログポートの番号が入っている変数です。今回はこれに8を指定しています。pinに8が代入されていると、0x07と論理積をとると0となり、0番ポートの値を読み取ることになるようです。

16進表現 2進数表現 
pin = 0x8 1 0 0 0
0x07 0 1 1 1
pin & 0x07 0 0 0 0

実際、0番ポートをGNDに接続すると、それまで1023を出力していたのが、0を出力するようになりました。

実験その2

analogRead()のソースを少し変更して、8番ポートを直接読み取るようにしてみます。

どのアナログポートの値を読み取るかは、前述のADMUXというレジスタの値を設定することで選択しています。また、ADMUXには、その際の参照電圧に関する情報も入っています。具体的には、analog_referenceにINTERNAL(実際の値は3)、pinに8を代入すると、ADMUXには0xc8が代入されるはずです。

上記の変更をしたanalogRead()を、analogRead8()という名前で作成し、それだけでは不足する部分を加えて、スケッチの中に埋め込んでみました。

#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

int analogRead8()
{
  uint8_t low, high;

  ADMUX = 0xc8;
  sbi(ADCSRA, ADSC);
  while (bit_is_set(ADCSRA, ADSC));

  low = ADCL;
  high = ADCH;
  return (high << 8) | low;
}
void setup() {
  Serial.begin(9600);
}

void loop() {
  int A8val;
  float A8volt;
  float A8temp;
  
  A8val = analogRead8();
  A8volt = A8val * 1100.0 / 1024;
  A8temp = map(A8volt, 242, 380, -45, 85);
  
  Serial.print("AnalogRead: ");
  Serial.print(A8val, DEC);
  Serial.print(", ");
  Serial.print(A8volt, 1);
  Serial.print("mv, ");
  Serial.print(A8temp, 1);
  Serial.println("degree");
  delay(1000);
}

データシートによると、1mvの差は1℃に相当し、以下の対応表が掲載されています。しかし、微妙に線形ではないため、上記のプログラムの変換式は完全ではありません。

温度 -45℃ 25℃ 85℃
電圧 242mv 314mv 380mv

プログラムを動かした結果、25度くらいの部屋で約406mvが出力され、100℃以上という結果となりました…

ただ、チップを触ると少し電圧が上がり、冷たいものを近づけると電圧が下がることから、それなりに動作はしているようですが、上記のプログラムが問題なのか実際にその電圧が出力されているのかまではわかりませんでした。

外付けの温度センサとかを用いて、校正をすれば使えるようになるかもしれません。温度の精度や構成については、時間があったら試してみます。

バージョン

Arduino 0022



メニューを表示するためにJavaScriptを有効にしてください。

Arduinoで遊ぶページ
Copyright © 2011 garretlab all rights reserved.
inserted by FC2 system