Deep Insider の Tutor コーナー
>>  Deep Insider は本サイトからスピンオフした姉妹サイトです。よろしく! 
.NET対応組み込みデバイス「Netduino」入門(3)

.NET対応組み込みデバイス「Netduino」入門(3)

Netduinoアナログ入力の基本(温度センサー活用)

2015年4月13日

Lチカができたら、アナログ入力を使ってみよう。温度センサーの値をNetduinoで取得するサンプルを作成し、アナログ入力の基礎を説明する。

Microsoft MVP for .NET 初音 玲
  • このエントリーをはてなブックマークに追加

環境センサーはアナログ入力を使え

 前回で、基本的な回路の組み方とアプリの組み方を解説した。

 今回は、Netduinoの入出力機能の中からアナログ入力について取り上げる。例えば気温センサー(=温度センサー)などから値を取得するときには必須の入力方法だ。

Netduinoのアナログ入力

 Netduinoのボード右下にある6ピンがアナログ入力だ(図1)。このアナログ入力には、0~3.3vの電圧を入力できる。

図1 Netduinoのアナログ入力

 今回のサンプルでは、このアナログ入力の0番ピンに温度センサーの値を入力する。

温度センサーについて

 温度センサーにはいろいろあるが、今回は入手のしやすさ、測定できる温度範囲の広さ、必要な回路が単純なことから、LM61CIZ(図2)を使う。

LM61CIZ
図2 温度センサー「LM61CIZ」

LM61CIZは、ナショナル セミコンダクター社(現在はテキサス・インスツルメンツ社の一部門として吸収合併されている)の温度センサーだ。そのためか、製品データシートなどを見ると表紙こそテキサス・インスツルメンツ社だが、中のページのヘッダーには「ナショナル セミコンダクター」と記載されている。

 LM61CIZの性能としては、測定レンジは-30~100℃、測定誤差の最大値は±4℃(25℃では±3℃)の精度がある。また、待機時消費電力は最大125μA(25℃時)であり自己発熱は0.2℃以下に抑えられているので、自己発熱で回りを温めてしまうことによる測定誤差が生じたりはしない。

 より高い測定精度が必要なときには、LM35DZなどを使うとよいだろう。LM35DZであれば測定レンジ-55~150℃、測定誤差の最大値は±0.75℃(25℃では±0.5℃)、待機時消費電力は最大60μA(25℃時)で自己発熱は0.1℃以下が可能だ。しかし、氷点下を測りたいときはマイナス電源が必要になるなど回路が複雑になるので、今回は採用を見送った。

 ただし、「回路が複雑になる」といっても、今回取り上げるLM61CIZを使った回路でLM35DZに差し替えるだけでも、2~150℃の範囲であれば測定できる。アプリ側のコードも多少相違はあるが、基本は一緒なので、LM35DZを購入してサンプルコードを試すことも可能だ。相違点についてはコード解説時に説明する。

Netduino+LM61CIZのハード構成

LM61CIZの物理仕様

 LM61CIZ(LM60BIZも同様)は3本の端子(これを「足」と呼ぶ)がある。それぞれの役目は、LM61CIZのデータシートに記載がある(図3)。

図3 足の役目

 図3は、下からLM61CIZを見たときの図だ。よって平らな面を正面にして足を下にしたときに向かって左から電源(+2.7~+10V)、測定値出力(300~1600mV)、GND(0V)となる。

 よって、LM61CIZとNetduinoを接続するときには、左足をNetduinoの5Vピン、真ん中の足をアナログ入力の0番ピン、右足をGNDに接続すればよい。もちろん5Vピンではなく3.3Vピンでもよいが、LM35DZの電源電圧が+4~+30Vであるため、回路の共通化という意味もあり5Vピンに接続する。

LM61CIZ接続回路図

図4 LM61CIZ接続回路図

 図4のLM61CIZ接続回路図を見ると、今までの説明にはない「0.1μF(100nF)のコンデンサー」が登場する。これは電源用パスコン(=バイパスコンデンサー)だ。

 IC(集積回路)は、動作するときに電流が微量ではあるが変化する。この変化を緩和しないと、供給される電圧が一時的に変化してしまう。そこで、電圧が追いつくまでのタイムラグを埋めるためにパスコンを配置する。パスコンは、通常は充電を行い(電気をためておき)、消費電流が増えたときに放電して電圧の低下を防止する。このようにICごとにパスコンを入れることで、回路全体の動作が安定する。また同様に微弱な変化である電源ノイズのフィルターにもなる。

 今回の実装で使用したパスコンの詳細仕様は、50V0.1μFのセラミックコンデンサー(同様のものを購入するならこちら)である。

ブレッドボード実装

 回路図を基にしてブレッドボードに部品を配置する。

図5 LM61CIZブレッドボード配置

ブレッドボードのそれぞれの穴には、「アルファベットと数字」(以下、穴番号)が割り振られており、この図では薄く小さい文字で左側に「A」「B」「C」……、上側に「1」「5」「10」……と記載されている。例えばこの図の「A」行「8」列目の穴(本連載ではA8と表記)には赤いピンが刺さっている。

 Netduinoからの5Vラインは、赤いラインを通ってブレッドボードの一番下に接続する。ここは内部的には横の穴が全て接続されているブレッドボードのプラス電源ラインだ。GNDからの線も同様に青いラインを通って下から二番目に接続する。ここも内部的に横の穴がつながれているブレッドボードのGNDラインだ。

 ブレッドボードのプラス電源ラインからは、A8 に接続されている。A8B8C8D8E8(=各列の「A」~「E」行)は内部的に接続されているので、そこのどこかにパスコンの片足とLM61CIZの+Vs(=向かって一番左足)を刺す。なお、図では見やすさの都合上、パスコンをLM61CIZとは別列に配置してその間をジャンパー線で接続している。実用上はこの両者の間は短い方がいいので、LM61CIZの+VsC8に刺してしまえばよい。

 次に、ブレッドボードのGNDラインからをA10に接続し、E10にパスコンのもう片足、C10にLM61CIZのGNDを差し込む。

 最後にLM61CIZのVoutとNetduinoのアナログ0番ピンを黄色い線で接続すれば完成だ。

 実際に接続すると次のようになる。

図6 LM61CIZ実装写真

 なお、ブレッドボード上の配線にはジャンパーワイヤー、ブレッドボードとNetduinoの間はジャンパーコードを使用した。ブレッドボード上にきれいな配線を行うのに便利なものなので参考にしてほしい。

Netduino+LM61CIZのプログラミング

 回路が完成したら、アプリのプログラミングを始める。

 最初に行う手順は、Visual Studioの[新しいプロジェクト]ダイアログで[Micro Framework]カテゴリの[Netduino Plus 2 Application]テンプレートを選択して、新規にプロジェクトを作成することだ(本稿の例では、プロジェクト名はVB.NET用は「LM61TemperatureVB」、C#用は「LM61TemperatureCS」とした)。

アナログ入力用クラスライブラリの参照設定の追加

 アナログ入力を行う場合、テンプレートにより追加済みのクラスライブラリに加えて、AnalogInputのクラスライブラリへの参照設定も追加する。

 ソリューションエクスプローラーでプロジェクトを右クリックして、(表示されるメニューから)[追加]-[参照]を選択してダイアログを表示し、そこで図7のように「SecretLabs.NETMF.Hardware.AnalogInput」クラスライブラリを選択して[OK]ボタンをクリックする。

図7 AnalogInputクラスライブラリへの参照設定の追加

センサー値の理解

 LM61CIZが、測定した温度をどのようなアナログ値で出力するかもデータシートに記載がある(図8)。

図8 LM61CIZのセンサー値

 600mVを0℃として、300~1600mVの値がアナログ出力される。また測定値が1℃変わるとセンサー値は10mV変化することもデータシートに記載がある。よって次の式で測定温度が求まる。
温度=(アナログ出力値-600)/10

アプリ作成

 Netduinoのアナログ入力を使ったアプリを作るときに覚えておきたいことがある。それは、アナログ入力ピンは0~3300mVの入力が可能だが、コードで取得するときの値は規定値では「0~1023」の1024段階だという点だ。温度、センサー値、アナログ入力値を比較すると次の表になる。

温度 センサー値 アナログ入力値
100℃ 1600mV 496
25℃ 850mV 263
1℃ 610mV 189
0℃ 600mV 186
-25℃ 350mV 108
表1 温度/センサー値/アナログ入力値の比較

 0~3300mvのセンサー値がそのままアナログ入力値として取り出せると、アプリのコードは格段に読みやすくなる。それを可能にするのがSetRange(0, 3300)だ。詳しくは次のコードを見ていただきたい。

Visual Basic
Imports Microsoft.SPOT
Imports SecretLabs.NETMF.Hardware.Netduino
Imports System.Threading
 
Module Module1
 
  Sub Main()
    Dim lm61 = New SecretLabs.NETMF.Hardware.AnalogInput(Pins.GPIO_PIN_A0)  '1
 
    lm61.SetRange(0, 3300)                      '2Netduinoアナログ出力は(0~3.3V)
    While (True)
      Dim value = (lm61.Read() - 600) / 10.0F   '3600mV = 0℃ , 1℃=10mV
      Debug.Print(value.ToString)
      Thread.Sleep(500)                         '4
    End While
 
  End Sub
 
End Module
C#
using Microsoft.SPOT;
using SecretLabs.NETMF.Hardware.Netduino;
using System.Threading;
 
namespace LM61TemperatureCS
{
  public class Program
  {
    public static void Main()
    {
      var lm61 = new SecretLabs.NETMF.Hardware.AnalogInput(Pins.GPIO_PIN_A0); //1
 
      lm61.SetRange(0, 3300);                     //2Netduinoアナログ出力は(0~3.3V)
      while(true)
      {
        var value = (lm61.Read() - 600) / 10.0F;  //3600mV = 0℃ , 1℃=10mV
        Debug.Print(value.ToString());
        Thread.Sleep(500);                        //4
      }
    }
  }
}
リスト1 LM61CIZ温度センサーからの出力値を確認するためのサンプルコード
  • 1アナログ入力0番ピン用の変数lm61を宣言。
  • 2SetRangeメソッドにより、アナログ入力ピンからの取得値は03300とする。
  • 3アナログ入力値から温度へ変換。
  • 40.5秒の測定待ち。

 310.0Fとしているのは、lm61.Read()での戻り値が整数型なので、演算結果が浮動小数点型になるように明示的に定数の型を指定している。

LM35DZを使う場合の変更点

 もし、LM61CIZではなくLM35DZを使った場合は、3の計算式が変わる。LM35DZのデータシートから3の式は次のようになるので、LM35DZで使う場合は参考にしてほしい。

Visual Basic
Dim value = lm61.Read() / 10.0F   '3 0mV = 0℃ , 1℃=10mV
C#
var value = lm61.Read() / 10.0F;  //30mV = 0℃ , 1℃=10mV
リスト2 LM35DZでの計算式

アプリ実行

 以上でサンプルアプリは完成だ。実際に動かしてみると、[出力]ウィンドウに気温が表示される。

Netduino+LM61CIZのノイズ対策強化版ハード構成

 LM61CIZのデータシートを読んでみると、「ノイズが激しい環境ではパスコンに加えて(どちらかというとパスコンより先に)VoutGNDの間に、1μFのコンデンサーを入れてローパスフィルター(低域通過回路)を設置するように」という旨が書かれている。ローパスフィルターというのは、特定の周波数以上の信号をカットするフィルターのことであり、高周波ノイズを除去することで、ノイズが多い環境でも出力にノイズが乗って測定値が暴れるのを防ぐという効果がある。

 実際にローパスフィルターを設定した場合の回路図は図9のようになる。

図9 ノイズ対策を加えたLM61CIZ接続回路図

Netduino+LM61CIZの出力電圧増幅版ハード構成

 入力された電圧をアプリで扱うときは、SetRangeメソッドで指定したとしても、内部的には01023の整数値として取り出している。つまり、「1℃」の変化でセンサー値は3変化するので、センサー値1の変化は「約0.3℃」に相当することになる。どんなに温度センサーの精度を上げたとしても、0.3℃より小さな変化は捉えられないということになる。

 また、LM61CIZのセンサー値の範囲は350~1600mVであり、0~3300mVというアナログ入力のレンジを活用していない。そこで登場するのが、センサー値の出力電圧を増幅してアナログ入力のレンジをフル活用することで精度を向上させるという方法だ。

 具体的には出力電圧を2倍にすると次のような形になる。

温度 センサー値 アナログ入力値
100℃ 3200mV 992
25℃ 1700mV 527
1℃ 1220mV 378
0℃ 1200mV 372
-25℃ 700mV 217
表2 出力電圧の増幅

 これにより「1℃」の変化でセンサー値は6変化する。つまり、センサー値1の変化は「約0.16℃」に相当する。

出力電圧を増幅する方法

 出力電圧を増幅するには、オペアンプというICを使う。今回はプラス電圧をそのまま2倍にしたいので非反転増幅回路を組む(図10)。

図10 オペアンプによる非反転増幅回路

 増幅率は2つの抵抗値の比率で調整する。
増幅率N=1+(Rf[Ω])/(Rg[Ω])

 抵抗は100Ω前後を用いるときが多いので、2倍にしたいのであれば、100Ωの抵抗を両方に付ければよい。

出力電圧増幅回路図

 オペアンプとしてOPA277PAを使って非反転増幅回路を作成してLM61CIZと組み合わせたときの回路図は次のようになる。

図11 出力電圧増幅回路図

出力電圧増幅ブレッドボード実装

 回路図が出来上がったのでブレッドボードに実装する。OPA277PAは2列4ピン合計8ピンのICなのでブレッドボードに刺すときにはEとFをまたがるように刺す。

図12 出力電圧増幅ブレッドボード実装

 ブレッドボードは、EFの間は同じ列でも内部結線されていないので、OPA277PAのようなICはここに刺して上下に配線を伸ばす。なお、端の下2列と上2列は電源ラインGNDラインなので、横に内部結線されている。

 部品点数も多くなり回路も複雑になってきたのでブレッドボード上も混み合ってきたが、Fritzing上で納得いくまで配置を決めてから実装すると思い通りの配線で実装できる。きれいな配線(図13)は配線ミス防止にも役立つので画面上で試行錯誤してほしい。

図13 きれいに配線された出力電圧増幅実装の写真

出力電圧増幅対応アプリ作成

 LM61CIZをこの回路に組み込んだときも、SetRangeメソッドを使えばセンサー値をそのままアナログ入力値として使うことができる。2倍になるので、温度「0℃」=センサー値「1200mV」=アナログ入力値1200だ。また、温度「1℃」の変化もアナログ入力値20となる。よって、計算するコードは次のようになる。

Visual Basic
Dim value = (lm61.Read() - 1200) / 20.0F   '3 1200mV = 0℃ , 1℃=20mV
C#
var value = (lm61.Read() - 1200) / 20.0F;  //31200mV = 0℃ , 1℃=20mV
リスト3 2倍増幅時のLM61CIZでの計算式

 もしくはLM35DZをこの回路に組み込んだときは上限が100℃で1000mVになるので、3倍増幅しても100℃で3000mVとなりセンサー値930とオーバーフローせずに済む。センサー自体の精度もいいので氷点下を無視してLM35DZを3倍増幅で使うというのも手だろう。このときの温度変換コードは次のようになる。

Visual Basic
Dim value = lm61.Read() / 30.0F   '3 0mV = 0℃ , 1℃=30mV
C#
var value = lm61.Read() / 30.0F;  //30mV = 0℃ , 1℃=30mV
リスト4 3倍増幅時のLM35DZでの計算式

 以上でアプリは完成なので、実行すると、より精度の高い値が出力される。

まとめ

 等倍回路と2倍増幅回路での温度測定の結果をグラフにしてみた。

図14 測定比較(LM61CIZを2つ使って等倍と2倍増幅を同時に取得した結果)

 同時測定できるように回路を組んでオペアンプにも0.1μFのパスコンを挟み込んでみたのですが、2倍増幅時の方が増減が激しいように見て取れる。

図15 測定比較時のブレッドボード実装

 これはLM61CIZの測定精度自体が等倍回路の精度で十分測定できる範囲であり、増幅によりセンサーの測定精度付近での揺らぎを拾ってしまっているのではないかと考える。LM35DZであればカタログ上は0.5℃の測定精度があるはずなので、2倍増幅や3倍増幅することでアナログ入力の1024段階に丸められたときに消えてしまう変化も検出できるだろう。

 このようにアナログ入力を使う場合は、センサーの精度や回路上のノイズの考慮などさまざまな要因を検討しなければならない。例えば1回の測定で測定値とするのではなく、5回の平均で測定値にするなどの工夫も必要だ。このあたりは実際に試して実感していくことでノウハウがたまるので、ぜひサンプルを使って試してほしい。

 次回はI2C接続を使ったセンサー入力を取り上げる予定だ。使用する部品としては、ADT7410温度センサーモジュールを予定している(この部品は、はんだ付けが必要なので、はんだごてが手元にない場合は、「goot 電子工作用はんだこてセット X-2000E」などを購入しておいてほしい)。また、次々回ではAQM0802A-RN-GBW液晶+ブレッドボード用ピッチ変換基盤を使用予定なので、こちらもまとめて購入しておくのがお勧めだ。

※以下では、本稿の前後を合わせて5回分(第1回~第5回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。

.NET対応組み込みデバイス「Netduino」入門(3)
1. Netduino、知ってますか?

電子工作キットの“Arduino”と“Netduino”は何が違うのか? Netduinoの概要と、開発環境の準備方法を解説する。

.NET対応組み込みデバイス「Netduino」入門(3)
2. Netduino、まずは基本のLチカ

初めてのNetduinoアプリ開発。まずは基本の基本であるオンボードのLチカから。次にブレッドボード上の外部LEDのLチカも行う。また、ファームウェアの更新方法も説明する。

.NET対応組み込みデバイス「Netduino」入門(3)
3. 【現在、表示中】≫ Netduinoアナログ入力の基本(温度センサー活用)

Lチカができたら、アナログ入力を使ってみよう。温度センサーの値をNetduinoで取得するサンプルを作成し、アナログ入力の基礎を説明する。

.NET対応組み込みデバイス「Netduino」入門(3)
4. Netduinoシリアル通信(I2C)の基本

アナログ入力の次はシリアル通信(I2C)の基礎を習得しよう。I2C対応の温度センサーの値をNetduinoで取得するサンプルを作成する。

.NET対応組み込みデバイス「Netduino」入門(3)
5. Netduinoシリアル通信(I2C)でLCD表示

シリアル通信(I2C)をさらに学ぼう。I2C通信で液晶ディスプレイ(LCD)に文字を出力するサンプルを作成する。

サイトからのお知らせ

Twitterでつぶやこう!