検索
連載

温度センサーを使い、「温度が一定以上になると“自動で動く”UWPアプリ」を作るラズパイ3&Toradex、Windows 10 IoT Coreで楽しみながら検証するIoT実践入門(5)(3/4 ページ)

ITエンジニアに向け、「ビジネスに貢献するIoT活用」の第一歩を踏み出す「ひらめき」を得てもらうための本連載。今回は、IoTハードウェアと温度センサーを使い、温度に応じてUWPアプリを制御するシステムを作ってみよう。

Share
Tweet
LINE
Hatena

書き出したプロジェクトをVS2015で開き、コードの修正を行う

 先ほど作成した「SkeletonDanceScript.cs」のコードを修正する。

 まず、VS2015のソリューションエクスプローラーの「参照」で右クリック→「参照の追加」を選択する。表示される参照マネージャーから、「Universal Windows」→「拡張」→「Windows IoT Extension for the UWP 10.0.10240.0」を選択する。選んだAPIがソリューションエクスプローラーの「参照」内に追加される(図1)。

photo 図1 参照マネージャーから「Windows IoT Extension for the UWP 10.0.10240.0」を選択する

コードの修正

 ソリューションエクスプローラーから「SkeletonDanceScript.cs」を開く。最初は、エラーを示す赤い波線が幾つか表示されるが、気にしなくてもいい。

 SkeletonDanceScript.csのコードを、以下のように追加修正する(リスト3)。

using UnityEngine;
using System;
using Windows.Devices.I2c;
using Windows.Devices.Enumeration;
using System.Threading;
public class SkeletonDanceScript : MonoBehaviour
{
    private I2cDevice ADT7410;
    private Timer periodicTimer;
    static public int Temperature;
  
    GameObject obj;
    void Start()
    {
        obj = GameObject.Find("skeletonDark");
        InitADT7410();
    }
     void Update()
    {
        if (Temperature >= 25)
        {
            obj.GetComponent<Animation>().Play("dance");
        }
        else
        {
            obj.GetComponent<Animation>().Play("idle");
        }
    }
    private async void InitADT7410()
    {
        string aqs = I2cDevice.GetDeviceSelector();
        var dis = await DeviceInformation.FindAllAsync(aqs);
        var settings = new I2cConnectionSettings(0x48);
        settings.BusSpeed = I2cBusSpeed.FastMode;
        ADT7410 = await I2cDevice.FromIdAsync(dis[0].Id, settings);
        periodicTimer = new Timer(this.TimerCallback, null, 0, 1000);
    }
    private void TimerCallback(object state)
    {
        byte[] readBuf = new byte[2];
        ADT7410.Read(readBuf);
        int valh = ((int)readBuf[0]);
        int vall = ((int)readBuf[1]);
        double temperature = CalcTemperature(valh, vall);
        Temperature = (int)(temperature);
    }
    private static double CalcTemperature(int valh, int vall)
    {
        int val = (valh << 5) + (vall >> 3);
        if (val > 4096)
        {
            val = -1 * (8192 - val);
        }
        double temperature = val * 0.0625;
        return temperature;
    }
}
リスト3 追加修正した「SkeletonDanceScript.cs」の中身

 修正した「SkeletonDanceScript.cs」のポイントは以下の通りだ。

名前空間の読み込み

 アプリケーションから内蔵回路(I2C)バスを介して接続された周辺機器との通信に使用するクラスの含まれる、Windows.Devices.I2c名前空間を読み込んでおく。

メンバー変数の宣言

 I2cDevice型のメンバー変数TMPSENSOR、Timer型のmyTimerメンバー変数を宣言。続いて、Unity 5.3内で宣言しておいたグローバルな変数Temperature、同じくUnity 5.3内で宣言しておいたGameObject型のobj変数を宣言している。

Start()メソッドの処理

 I2C関連の初期化処理を記述したInitADT7410();メソッドを実行する。

Update()メソッドの処理

 グローバルな変数Temperatureの値が「25以上」だったら(温度がセ氏25度以上だったら)、ガイコツキャラが踊る。それ以外の値では、キャラの動きが停止する。

I2C関連の初期化処理

//  Raspberry Pi3上のI2Cコントローラーに関する情報を取得
	string aqs = I2cDevice.GetDeviceSelector();  (1)
//  上記で取得した情報文字列に一致するDeviceInformationオブジェクトを列挙する。
	var dis = await DeviceInformation.FindAllAsync(aqs);  (2)
//  ※I2Cデバイスセンサーの接続設定として、デバイスアドレスと速度を設定する。
	var settings = new I2cConnectionSettings(0x48);  (3)
	settings.BusSpeed = I2cBusSpeed.FastMode;   (4)
//  ※上記の接続設定を使用して、I2Cコントローラー上のI2Cデバイスセンサーオブジェクトを取する。
	TMPSENSOR = await I2cDevice.FromIdAsync(dis[0].Id, settings);  (5)
I2Cデバイスを使用する際のテンプレートとなる処理

 上記5行の処理は、I2Cデバイスを使用する際のテンプレートとなる処理なので覚えておこう。

  • var settings = new I2cConnectionSettings(0x48);

 と記述している箇所のアドレスを変更すれば、他のセンサーにも応用ができる。デバイスのアドレスについては、各センサーのデータシートまたはPDFマニュアルなどに記載されているはずだ。筆者が購入した温度センサーの説明書には、図2のように記載されていた。よって、アドレスには「0x48」を指定している。この他、Raspberry Pi 3の標準OSであるRaspbianにて、センサーを接続して「i2cdetect -y 1」を実行してもアドレスを取得できる

photo 図2 デバイスのアドレスは、センサーのデータシートやマニュアルなどに記載されている

 最後に、myTimer = new Timer(this.TimerCallback, null, 0, 1000);と記述して、1秒ごとにセンサーからの値を読み取るように、タイマー処理を実装する。

TimerCallback()メソッドの処理

 ここでは、1秒ごとにセンサーからの値を読み取っている。

 グローバルな変数Temperatureに、変数temperatureの値を格納する。この処理によって、Unity 5.3上では取得データがないために「0」と表示されていた場所に、現在の温度がリアルタイムに表示される。

 温度データを含む2バイト(0x00、0x01)を、InitADT7410メソッド内のADT7410から読み出している。高位の1バイトをvalh、低位の1バイトをvallとして、CalcTemperature()で実際の温度に変換している。

CalcTemperature()メソッドの処理

 ここでは、valhを左へ5ビット、vallを右へ3ビットシフトしている。戻り値として、現在の温度の入ったtemperatureを返している。なお、シフト演算はかなり難しいので、以下の解説サイトも参照するとよいだろう。

(参考サイト)シフト演算について



Copyright © ITmedia, Inc. All Rights Reserved.

ページトップに戻る