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

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

Netduinoシリアル通信(I2C)で複数機器接続

2015年5月22日

シリアル通信(I2C)で2つ以上の機器を同時に使用するサンプルを作成する。温度センサーから室温を取得して液晶ディスプレイ(LCD)にリアルタイム表示してみよう。

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

 前回の予告通り、温度センサーの値をLCDに表示する。

使用部品について

 I2C対応機器として、これまでの連載の中で使用した次のものを同時使用する。

接続回路図

図1 接続回路図

 複数のI2C対応機器を接続する場合、4本のラインをそれぞれ分岐して各機器に接続する。SCLSDAに設置する10kΩのプルアップ抵抗は機器ごとではなく1組だけ設置すればよい。

ブレッドボード実装

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

図2 ブレッドボード上に配置

 Netduinoからの5Vラインは赤いラインを通ってブレッドボードの一番下のプラス電源ラインを通ってLCDのVDDRESETそして温度センサーのVDD、1組のプルアップ抵抗へと5Vを供給する。NetduinoのGNDからの線も同様に青いラインを通って下から二番目のGNDラインに接続し、LCDと温度センサーのGNDに接続する。

 SCLSDAの2つの信号線は、SCLがA23、SDAがA22でNetduinoに接続し、ここからB13C14に分岐してLCD側に接続する。また、プルアップ用の10KΩ抵抗でA13A14からプラス電源ラインの間を接続する。

 実際に接続すると、ブレッドボード上の実装は次のようになる。

図3 実装写真

 今回使用したLCDと温度センサーは端子の向きが左右逆転している。もし、端子の左右を揃えて左から順にVDDSDASCLGNDと揃えたいのであれば、温度センサーを裏表逆に差し込んで回路を組み直すといいだろう。

Netduinoでの複数I2C機器のプログラミング

 回路が完成したら、Visual Studioの[新しいプロジェクト]ダイアログで[Netduino Plus 2 Application]テンプレートを選択して、新規にプロジェクトを作成して(本稿の例では、プロジェクト名はVB.NET用は「TemperatureVB」、C#用は「TemperatureCS」とした)、アプリのプログラミングを始める。

クラス構成

 今回のサンプルコードのクラス構成をVisual Studioのコードマップ機能で確認する。なお、前回まではVBならばModule.vbファイル、C#ならProgram.csファイルの中にあったLCDや温度センサー用のクラスも、今回からは別クラスファイルにしている(そのため、Privateprivateとして実装していたクラスはFriendinternalに変更しなければならないので注意してほしい。その他、名前空間名の違いにも注意されたい)。

図4 クラス構成

 I2C用クラスであるI2CLibクラスを基本クラスとして、LCD用AQM0802Libクラス、温度センサー用ADT7410Libクラスに派生させてから呼び出している。これらのクラスは、前回および前々回に作成したものと同じなので、本稿では説明を割愛する。

 複数I2C機器を同時に使うときの注意点としては、プログラムで接続する際のI2Cアドレスが複数あるということだ。I2CLibクラスの中で使っているI2CDeviceクラスは1度に1つのアドレスしか指定できず、オブジェクトを生成したまま、I2Cアドレスを切り替えることができない。そこで機器ごとに、つまり、LCDを使うときはAQM0802Libクラスからオブジェクトを生成して表示データを送信したら速やかに解放(Dispose)し、温度センサーから温度を読み出すときはADT7410Libクラスからオブジェクトを生成してデータを読み取ったら速やかに解放(Dispose)するようにしなければならない。つまりリスト1のように、I2CLibクラスのDisposeメソッド内に、I2CDeviceオブジェクトをDisposeするコードを追加する。

Visual Basic
……省略……
Friend Class I2CLib
  Implements IDisposable
  ……省略……

  Protected Overridable Sub Dispose(disposing As Boolean)
    If Not Me.disposedValue Then
      If disposing Then
        Me.I2c.Dispose()
      End If

    End If
    Me.disposedValue = True
  End Sub

  ……省略……
End Class
C#
……省略……
namespace ADT7410TemperatureCS
{
  internal class I2CLib : IDisposable
  {
    ……省略……

    public void Dispose()
    {
      this.I2c.Dispose();
      GC.SuppressFinalize(this);
    }

    ……省略……
  }
}
リスト1 I2CDeviceオブジェクトを速やかにDisposeするコード(上:I2CLib.vb、下:I2CLib.cs)より抜粋

 このようなことができるのは、LCDも温度センサーもNetduinoからの接続が切れても電源さえ切れなければ状態を維持して動作し続けるからだ。

AQM0802用クラスの改良

 前回作成したAQM0802Libクラスでは、クラスからオブジェクトが生成されるときに初期化も行っていた。今回のように生成と解放を繰り返す使い方をしたいときには、最初の1回だけ初期化すれば状態が維持されるので毎回初期化するのは非効率だ。そこで初期化部分をInitメソッドとして切り出しておこう。具体的には次のようなコードになる。

Visual Basic
Public Sub New()
  MyBase.New(&H3E, 100, 500)
  Thread.Sleep(40)       ' 40ms待つ
End Sub
 
Public Sub Init()
  ' 画面サイズ指定
  Me.WriteCommand(LCD_FUNCTIONSET Or LCD_8BITMODE Or LCD_2LINE)
  ' 拡張コマンド設定開始
  Me.WriteCommand(LCD_FUNCTIONSET Or LCD_8BITMODE Or LCD_2LINE Or ISBit)
  ' AQM0802用固定設定
  Me.WriteCommand(&H14)  ' Internal OSC Frequency
  Me.WriteCommand(&H70)  ' Contrast set
  Me.WriteCommand(&H52)  ' Power/ICON/Contrast control(5V用)
  Me.WriteCommand(&H6C)  ' Follower control
  ' 拡張コマンド設定終了
  Thread.Sleep(200)
  Me.WriteCommand(LCD_FUNCTIONSET Or LCD_8BITMODE Or LCD_2LINE)
  '
  Me.WriteCommand(LCD_DISPLAYCONTROL Or LCD_DISPLAYON)  ' DISPLAY ON
  Me.WriteCommand(&H6)   ' Entry mode set
  Me.ClearDisplay()
End Sub
C#
public AQM0802Lib()
  : base(0x3e, 100, 500)
{
  Thread.Sleep(40);         // 40ms待つ
}
 
public void Init()
{
  // 画面サイズ指定
  this.WriteCommand(LCD_FUNCTIONSET | LCD_8BITMODE | LCD_2LINE);
  // 拡張コマンド設定開始
  this.WriteCommand(LCD_FUNCTIONSET | LCD_8BITMODE | LCD_2LINE | ISBit);
  // AQM0802用固定設定
  this.WriteCommand(0x14);  // Internal OSC Frequency
  this.WriteCommand(0x70);  // Contrast set
  this.WriteCommand(0x52);  // Power/ICON/Contrast control(5V用)
  this.WriteCommand(0x6C);  // Follower control
  // 拡張コマンド設定終了
  Thread.Sleep(200);
  this.WriteCommand(LCD_FUNCTIONSET | LCD_8BITMODE | LCD_2LINE);
  //
  this.WriteCommand(LCD_DISPLAYCONTROL | LCD_DISPLAYON);  // DISPLAY ON
  this.WriteCommand(0x6);   // Entry mode set
  this.ClearDisplay();
}
リスト2 LCD接続のためのサンプルコード(上:AQM0802Lib.vb、下:AQM0802Lib.cs)より抜粋

メインプログラムの作成

 クラスの用意ができたら、MainメソッドからADT7410LibクラスとAQM0802Libクラスの呼び出しを作成する。

Visual Basic
Module Module1
  Sub Main()
    Using lcd As New AQM0802Lib
      lcd.Init()                            ' ……1
    End Using
    While (True)
      Dim value As Single
 
      Using adt7410 As New ADT7410Lib
        value = adt7410.ReadTemperatre      ' ……2
      End Using
      Using lcd As New AQM0802Lib
        lcd.Locate(0, 0)
        lcd.WriteMessage(value.ToString())  ' ……3
      End Using
      Thread.Sleep(1000)                    ' ……4
    End While
  End Sub
End Module
C#
public class Program
{
  public static void Main()
  {
    using (AQM0802Lib lcd = new AQM0802Lib())
    {
      lcd.Init();                            // ……1
    }
    while (true)
    {
      Single value;

      using (ADT7410Lib adt7410 = new ADT7410Lib())
      {
        value = adt7410.ReadTemperature();   // ……2
      }
      using (AQM0802Lib lcd = new AQM0802Lib())
      {
        lcd.Locate(0, 0);
        lcd.WriteMessage(value.ToString());  // ……3
      }
      Thread.Sleep(1000);                    // ……4
    }
  }
}
リスト3 メインルーチン(上:Module.vb、下:Program.cs)より抜粋
  • 1LCD初期化(usingブロックの間だけ接続)。
  • 2温度センサーからの値取得(usingブロックの間だけ接続)。
  • 3LCDに温度表示(usingブロックの間だけ接続)。
  • 41000ms=1秒の待ち合わせ。

アプリ実行

 アプリを実行すると、1秒ごとに気温を更新表示する。

【動画】Netduino plus 2+LCD

まとめ

 測定結果をブレッドボード上のLCDで確認できるようになった。プログラムの動作が確認できたらPCからUSBを外して別電源から7.5V~9.0Vを供給すると自動的にブートされてプログラムが起動し気温をLCDに表示し続けてくれる。

 次回は、今回作成した回路とプログラムを使ってMicrosoft AzureのEventHubにデータを送信してクラウド側でデータ表示する方法を取り上げる。いわゆるIoTの世界だ。

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

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

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

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

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

.NET対応組み込みデバイス「Netduino」入門(6)
6. 【現在、表示中】≫ Netduinoシリアル通信(I2C)で複数機器接続

シリアル通信(I2C)で2つ以上の機器を同時に使用するサンプルを作成する。温度センサーから室温を取得して液晶ディスプレイ(LCD)にリアルタイム表示してみよう。

.NET対応組み込みデバイス「Netduino」入門(6)
7. Netduinoの計測結果をクラウド集計

Netduinoで計測した室温データをクラウドに送信してWebから見えるようにしてみよう。

.NET対応組み込みデバイス「Netduino」入門(6)
8. GR-PEACHボードとAzure Event Hubでクラウド集計

ついに発売開始されたGR-PEACHを利用。Microsoft Azure Event Hubを使って室温データをクラウドに送信してWebから見えるようにしてみよう。

サイトからのお知らせ

Twitterでつぶやこう!