はじめてのMKR ZERO (9) アナログ温度センサLM35DZを利用
■温度を測るには温度センサが必要
Arduinoでは、内部温度センサを読み出す機能をデフォルトでは用意していません。マイコンが動くたびに内部温度も変化するので、室内温度を測るなどの用途には適していません。
Arduino MKRZEROで使われているマイコンSAM D21の内部には、温度センサが入っています。内蔵A-Dコンバータのマルチプレクサ(切り替え器)の0x18を指定すれば読み出せます(コラム参照)。
温度を測りたいときは、市販されている温度センサを購入します。センサには「アナログ出力」と「ディジタル出力」があり、Arduino MKRZEROはいずれをつないでも温度を測れます。
●Arduinoの外部との接点がヘッダピン
マイコン・ボードArduinoにはプリント基板の両端にピンヘッダが並んでいます。UNOとMKRシリーズでは並びが異なりますが、多くのボードでこのピンの順番は決まっています。Arduinoでは、アナログ入力はA0につないで、というと、みんな間違わずにマイコンの「A-Dコンバータのチャネル0」に何かセンサをつなぐことができます。
Arduino MKRZEROで使われているマイコンSAM D21自体には、アナログ入力がAIN0~AIN19あります。そのうち7本が外部ピンヘッダにつながっています。UNOとMKRではCPUも違えばピンヘッダの数も異なりますが、analogRead(A0);と記述すると、どちらもピンヘッダのA0の電圧を読みます。
マイコンはディジタルICなので、そのままではアナログ事象を扱えません。アナログをディジタルの値に変換できる機能を利用します。Arduino MKRZEROにはその機能が複数内蔵されています。
それぞれの役割を次の図に示します。I2Cバスは信号線2本で、SPIバスは信号線3もしくは4本で通信するディジタル・デバイス用インターフェースです。バスには複数のデバイスをつないで使えます。A0からA6はアナログ信号の入力端子です。最大7本のアナログ出力のデバイスをつなげられます。
LM35DZやADT7310のデバイス名は代表例です。
学校で利用するのは棒温度計です。目盛りは1℃ごとにふっていますが、たぶん、1/10単位で読んでいたと思います。ちょっと斜めから別の人が見ると、0.5℃ぐらいは異なった温度になります。
0.1℃を分解能といいます。多くの温度センサは小数点第2位は得られます。目で見るのに比べて1桁細かいですね。20℃は本当に20℃でしょうか。もちろん、百葉箱相当の場所で測らないと気温としては正しくありません。気象庁が校正業者を紹介してくれます。20℃が20℃であることは確度という表現で表します。通常20℃は「20℃±0.5℃」の範囲という表現を取ります。まったく同じ条件で100回計ったら、たとえば95回は19.5~20.5の値が得ら、中央値はほぼ20.0℃というような感じです。
さらに、サーミスタであれば、手でつまんだり、息を吹きかけた途端温度が変化します。LM35DZはちょっと遅れます。ずっと手でつまんでいても、なかなか36度までは上がり切りません。デバイスによっては反応速度、レスポンスが大きく異なります。
このように、温度センサの能力は多岐にわたるので、用途に合わせて選択します。また、センサからArduinoのピンヘッダまでどのくらいの距離を延長できるかという点も大きな選択理由です。
●アナログ出力の温度センサを選ぶ
Arduino MKRZEROは電源電圧3.3Vで動くので、アナログ入力A0(~A6)には、0Vから3.3Vの電圧を入力できます。3.3V以上はだめです。12Vとかつないではだめです。電圧が測りたいといってAC100Vは絶対にダメです。
温度センサの定番はLM35DZ(※1)です。安くて確度が高いです。あまりにも有名なので、偽物も出回っています。写真のLM35DZの型名の部分はNSというロゴが印刷されています。今は、テキサス・インスツルメンツ社になったナショナルセミコンダクター社の製品です。
このセンサ、とてもわかりやすいのです。次の写真のように5V(赤色)とGND(黒色)の電源をつないで、センサの出力VoutをDMMで測ります。
約196mVです。これは19.6℃のことです。25℃なら250mVという電圧が出力されます。0℃のとき0Vで、1℃あたり10mVの電圧が発生します。零下を測りたいときには、マイナス電源が必要です(※2)。
STEP1 配線
Arduino MKRZEROとセンサを導線でつなぎます。電気的につなぐことを配線するといいます。導線は電気を流す線で、ほとんどは銅でできています。
①ブレッドボードで配線
②空中配線
③はんだ付けで配線
最初、空中配線でチャレンジします。アナログ入力を一つだけ使うのは、写真のように簡単です。LM35DZのリードの根元はぜい弱なので、ラジオ・ペンチでゆっくりと曲げます。10cmぐらいの短いジャンパ線を使っています(※3)。+Vs端子は5V、GNDはGNDへ、VoutはA0へつなぎます。
回路図(※4)です。
STEP2 スケッチの動作確認
Arduinoのプログラム言語は、C言語とほぼ同じです。Arduino.ccのsoftwareのページに行きます。ほかの記事ではArduino Web Editorを利用しています。ここではArduino IDE1.8.9をダウンロードし、Windows10にインストールして利用します。IDE1.8.8から外観は変わっていませんが、中身は大きく変更されました。
インストールの手順は、
「はじめてマイコン・ボードArduinoを使ってみる(2)」
を参照してください。
動作の確認をします。Arduino MKRZEROとPCをマイクロUSBケーブルで接続します。スケッチ例から01.Basic->Blinkを選びます。
①スケッチの上にある「→」右矢印をクリックします。これは、スケッチをコンパイルしてArduino MKRZEROに書き込む手順を一気に行います。スケッチは、人が読み書きできる高級言語と呼ばれ、マイコンでは直接実行できません。
まず、スケッチをC++言語に変換します。コンパイラgccでオブジェクト・ファイルを作ります。利用している関数に合わせてライブラリを取り込んで実行ファイル(バイナリ)が作られます。それをマイコンに書き込めるフォーマットに変更して、USB経由のシリアル通信でマイコンのフラッシュ・メモリに書き込みます。そのあと、リセットすると書き込んだプログラムが動きます。この一連の作業をボタン一つで行います。
LEDが点滅しました。点滅しているLEDはディジタル・ポート32番につながっています。プログラムでは32番ではなくLED_BUILTINと書いてあります。5年ほど前までは13と書かれていたのですが、Arduinoにいろいろなバリエーションが出てきたので、このスケッチ例のBlinkのプログラムも修正されました。
34行目のdelay(1000) の1000=1秒を100= 0.1秒に変更します。「→」右矢印をクリックします。点滅のタイミングが変わりました。以上で動作確認ができました。
STEP3 初めてのスケッチ
New Sketchボタンをクリックします。スケッチを書く準備ができました。setup()には初期設定事項(一度だけ実行される)、loop()にはメインのプログラムを書きます(※5)。
でも、使えるものは使いましょう。ファイル->スケッチ例->0.1Basics->ReadAnalogVoltageを選びます。アナログ入力A0から電圧を読み取り、シリアルモニタに結果を表示するという内容です。Arduinoには表示機能がありません。開発に利用しているPCの画面に計測結果を表示するのがシリアルモニタです。
ここでは、まだLM35DZはつないでいません。A0からVccにジャンパ線で配線します。
「→」で実行します。シリアルモニタをクリックすると、Serial.println()の実行結果が見れます。A0の電圧は3.3Vですが、実行例は5.0Vとなっています。
このサンプルは、Arduino UNOがベースで作られています。したがって、基準電圧は電源の5.0Vです。
24行目の5.0を3.3に変更して、コンパイル、実行します。
(2020/05/07)1023は間違いなので、1024に変更する。下記のスケッチも修正したが、上記のキャプチャ、実行結果は変更していない
実行結果は3.30Vになりました。
しかし、マイコンSAM D21に内蔵されたA-Dコンバータは12ビットです。Arduino UNOは10ビットです。analogRead()関数は0~1023の数値を返します。MKRシリーズのように12ビットA-Dコンバータでは、analogReadResolution(bits)で分解能を変更してから、analogRead()します。2^12は4096ですから、24行目は次のように変更します。
(2020/05/07)4095は間違いなので、4096に変更した。下記のスケッチも修正したが、実行結果は変更していない
コンパイルして実行すると結果は3.30Vです。確認として基準電圧として利用されている電源電圧をDMMで測定したら3.27Vでした。
STEP4 温度を測るスケッチ
コメントがたくさんあるので、全部消します。//からはコメントです。文頭に//があると、その1行は全部コメントです。スケッチの途中に//があると、そこから文末(リターン・コード、見えない)までがコメントです。
/* と */に挟まれた部分はコメントです。ただし、/* と */の中に/* もしくは*/があると、うまくコメントにならないことがあります。
ここで、USBケーブルを抜きます。LM35DZを接続します。USBケーブルを接続します。「→」で実行します。温度係数は10mV/℃なので、
15行目 voltageに100を掛けます。String()は数値を文字列に変換します。,1は小数点第1位までの表示に制限します。文字列同士は、+でつなげられます。
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
}
// the loop routine runs over and over again forever:
void loop() {
// read the input on analog pin 0:
int sensorValue = analogRead(A0);
// Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
analogReadResolution(12);
float voltage = sensorValue * (3.3 / 4096.0);
// print out the value you read:
Serial.println(String(voltage * 100 ,1) + "℃");
delay(1000);
}
温度センサLM35DZは±0.5℃の確度をもっています。Arduino MKRZEROのアナログ入力端子は12ビットのA-Dコンバータで、変換時に基準電圧源は電源電圧の3.3Vを用います。したがって、最小の電圧は、
3.3[V] / 2^12 = 0.805[mV]
です。LM35DZは1℃あたり10mVなので、MKRZEROのアナログ入力端子は約0.08℃より細かな分解能はありません。したがって、小数点の2位は意味がないので、四捨五入もしくは切り捨て小数点第1位の温度の値にします。
(※1)LM35DZのおもな入手先。秋月電子通商 マルツエレック 共立電子産業 RSコンポーネンツ 千石電商
(※2)零下を測るには、例えば0℃が400mVもしくは500mV出力のMCP9700/9701などを使うのが便利です。
(※3)電子工作でプロトタイプを作るとき、ジャンパ線は欠かせません。できるだけ安価な製品を入手します。市販品では長さが10cm、15cm、20cmをよく見ます。色は7色ぐらいありますが、電源用に赤と黒はよく使うので、多めに購入します。両端についているコネクタは、オス-オス、オス-メス、メス-メスの3種類があります。ブレッドボードで使うときは単線(0.3mmΦ)が適していますが、今回の用途ではより線が使いやすいです。
(※4)電子工作では、今、動くことが大切です。この回路が10年間動き続ける保証は何もありません。電子機器は、電解コンデンサなど寿命のある部品を使うため、10年ぐらいが最長の保証寿命です。10年間動き続ける回路設計や部品の選び方は、ノウハウの塊です。
(※5)loop()は電源が入っているかぎり、ずっと実行されます。どうしても流れを止めたいときは、
while(1);
コラム マイコン内部温度の読み取り
GitHub ElectronicCats_InternalTemperatureZeroからZipファイルをダウンロードし、展開して、ライブラリ->Arduino->librariesにコピーします。Arduino IDEを一度終了し、再立ち上げし、ライブラリ管理から、Electronic Cats Internal Temperature Zero Libraryをインストールします。
サンプルのReadInternalTemperatureを読み込み、コンパイル、実行します。