まごころせいじつ堂

浜町庄金 研究開発  マイコンで遊んでばっかりで

LM35DZ

LM35DZを複数繋いだ温度ロガーと誤差

温度センサLM35DZを複数個繋いだロガーやっとできた。

これまでの記事:
LM35DZを複数つないだ時の問題 お詫びとハードでの解決
温度センサLM35DZを複数Arduinoに繋いだ時のトラブル
LM35DZによる温度測定とanalogReference()

マイコン風雲録さんのanalogReadEx()関数で解決しました。ありがとうございました。
Arduino:温度センサー Processing + Firmata LM61BIZとLM35DZとDS18B20のメモ[マイコン風雲録]

Arduino UNOのA0〜A5ポートにLM35DZを接続。信号線は10KΩでGNDに。

 ログ時刻はRTCをつないで頑張るつもりだったが、Arduino UNOではI2Cの端子がアナログポートとかぶるのであきらめた。Arduino Microだとアナログポートはたくさんあるし次はこれ使おう。
で、肝心のタイムスタンプはTeraTermに任せた。ログを取るときに□タイムスタンプのチェックボックス入れるか、teraterm.ini内のLogTimestamp=onにする。
参考:
TeraTermログの行毎に自動的にタイムスタンプを付与する

※追記:@maris_HYさんにSPI接続のRTC教えてもらいました。
DS3234搭載のリアルタイムクロック・モジュール

以下を追加・修正した。
・Setup()内で5秒の待ち。シリアルモニタ(TeraTerm等)を立ち上げる時間を待つため
・別のセンサを付けることを考慮して、A0〜A5ポートの入れ替えを最初のほうで定義した。
・温度測定の結果は先頭に連番を付けるようにした
・Arduinoが生きているかどうか分かるようLEDを点滅させる処理を追加
・LM35DZセンサの誤差を補正できるようにした(Adj[]で定義)

さて、これで安定して測定できるようになったが、温度センサを一箇所にまとめても数℃の誤差が出る。これはセンサについてまわるので素子のばらつきと思われる(安いグレードだし)が、ADCの基準電圧が内部リファレンス1.1Vと外部リファレンス3.3Vではどう違うだろうか。

ADCの基準電圧1.1Vと3.3Vについて200回測定し、平均を求めた。
$ gawk -f 20121130.awk lm35dz1v1.txt
AVG1= 188.02
AVG2= 190.65
AVG3= 193.33
AVG4= 191.77
AVG5= 192.27
AVG6= 194.555

1.1V÷1024で分解能は1.07mV
6.54ステップのゆらぎ 約7.00mV

$ gawk -f 20121130.awk lm35dz3v3.txt
AVG1= 60.2977
AVG2= 61.1395
AVG3= 61.4512
AVG4= 61.214
AVG5= 60.9488
AVG6= 61.8791

3.3V÷1024で分解能は3.22mV
1.58ステップのゆらぎ 約5.10mV

 ということで、ATmega328の内部1.1Vよりも外部の定電圧レギュレータによる3.3Vの方がより正確。外部5Vも使えるが、USBから給電して使う場合はそちらに影響されるので3.3V参照のほうがよさそう。
 または、基準1.1Vの方がセンサの誤差に対してより敏感なのかも。ちょっとこの辺はLM35DZの良いグレードの品で比較しないといけないんだろうけど資本切れです。


プログラムはこちら。
※analogReference()の箇所がINTERNALになってますが3.3V参照ではEXTERNALでした。ただしINTERNAL設定でもAREFにかかっている電圧が優先になるようです。

https://gist.github.com/4176111


20121201terrmal

一晩測ってExcelに持っていった。おおよそ期待通り。上がったりしている箇所はストーブを使った時間。

LM35DZを複数つないだ時の問題 お詫びとハードでの解決

前回の続き。
温度センサLM35DZを複数Arduinoに繋いだ時のトラブル

こちらの方がADCの動作を考慮した読み捨ての回数を記事にされていた。
Arduino:温度センサー Processing + Firmata LM61BIZとLM35DZとDS18B20のメモ[マイコン風雲録]

ログを分析しようとしててあっと気付いた。
 for(int i=0;i<=NUM_LM35;i++) {
 だめだ……チャネルは6個しかないのに7個目読んでる……

 というわけでADC読み取りの最後が順番によらず跳ね上がるのは私のプログラムが原因でした。未定義のチャネル読んでる。申し訳ありません。

 ところで、チャネル読み込みの初回が順序に関わらず少し上がる現象は間違いなく起こっている。これを改善できるかどうか、以前も参考にした
■AVR(Arduino)にLM35温度センサをつなげた場合に正しくA/D変換出来ないトラブル(2012年2月15日)[SIESTA HOMEPAGE]
を参考に、LM35DZの出力に10KΩをぶら下げた。テスタでちゃんと信号-GND間が10KΩ程度か確認。
2012_10Kohm

 これで一晩ランニング。
比較のため前回とまったく同じヘボいコード(ADC0〜6まで読んでしまうもの)で実施。
この結果、最初に読んだチャネルが跳ね上がるという現象はなくなった。

□前回の生ログ(Arduino Leonardo、3V3リファレンス版) ※間違ったADCの7番目は除去
60702 72 73 74 74 73 74
121405 72 73 74 73 73 74
182107 72 73 73 73 73 73
242809 72 73 74 73 73 73
303512 72 73 73 73 73 73
364215 72 73 73 73 73 73
424918 72 73 73 72 73 73
485620 105 73 73 73 72 73
546323 71 73 73 73 72 73
607026 128 73 73 73 73 73
667727 72 73 73 73 73 74
728430 72 73 73 73 72 73
789133 72 73 73 73 72 73
849836 71 72 73 72 73 73

□今回の生ログ(Arduino Uno R3、1V1リファレンス版)
1759184 135 127 136 122 124 125 
1760387 135 128 136 122 124 124 
1761589 134 128 136 121 125 124 
1762791 135 127 136 122 125 124 
1763994 135 127 136 121 124 124 
1765196 134 127 135 122 125 123 
1766398 134 128 136 121 124 124 
1767602 135 127 136 122 125 124 
1768804 135 128 136 122 124 124 
1770006 134 127 135 122 124 124 
1771209 135 128 136 122 124 124 
1772411 135 128 136 122 125 124 
1773614 134 127 136 122 125 124 
1774816 135 128 136 122 125 124 

 LM35DZ直結の時は最初のADC読み取りで跳ね上がる現象が見られたが、10KΩをぶら下げることによりなくなった。しかし、各センサの値にむらがあるように見える。ADC0とADC2が値が大きい。

・今後の調査方針
(1)温度センサを束ねて同じ条件に
(2)ログをしっかり取ってawkで分析
(3) マイコン風雲録さんのanalogReadEx()で確認
 
 うう、デジタル温度センサに逃げたくなった……

LM35DZによる温度測定とanalogReference()

LM35DZという三端子の温度センサを使ってみた。
高精度IC温度センサ LM35DZ 0~100℃ [秋月電子]
【LM35DZ-N】高精度・摂氏直読温度センサーIC [マルツ]
 1℃あたり10mVの出力で、外付け部品なしの測定範囲は+2℃〜。Arduinoだとアナログ入力が使える。
作例はたくさんあるのでLCDに表示してみた。つかったのはLCDシールド
2012LM35DZ

ソースはこちら。https://gist.github.com/3724141 
→ https://gist.github.com/3725477

※A/D入力を℃に変換する箇所:ain*330/1024を修正。(ドライヤーで温めたらマイナス表示になってしまった)
float temp3v3(int ain) { // analog 0-1023 10mV/Celsius,3.3V*100/1024
  return ain*3.3*100/1024;
}



 今回使用したのはArduino UNO R3とArduino IDE1.0.1。A/Dコンバータの基準電圧に外部3.3Vを使用している。AREFピンと3V3ピンを接続し、スケッチ内でanalogReference(EXTERNAL); と指定した。

 ここでちょっと引っかかったのがanalogReference(INTERNAL)の指定。
http://arduino.cc/en/Reference/AnalogReference
これによるとATmega328でINTERNAL指定すると基準電圧は2.56V1.1Vになるらしいのだが、指定してみたらどうも3.3Vみたい。AREFピンに3V3を接続していたが、これを外すと値がおかしくなる。INTERNAL指定のままでAREFを5Vに接続したらそれが基準電圧みたいな動作をする。
Arduino UNO R3/Arduino IDE1.0.1ではINTERNAL指定もEXTERNAL指定も同じみたいだ。 

追記:MacOSXのArduino IDE1.0 と 0023でも同じだった。
解決:INTERNAL指定の時はAREFをつないじゃいけない。

ATmega328Pのデータシート、p.251 Figure 23-1. Analog to Digital Converter Block Schematic OperationをみるとA/Dコンバータの基準電圧はAREF端子に直に出ているので、INTERNALで1.1V指定していてもここに3.3Vをつなぐとそっちが勝つ。
 
記事検索
プロフィール

hardyboy

カテゴリ別アーカイブ
月別アーカイブ
QRコード
QRコード
  • ライブドアブログ