第3回 Windows IoTと押しボタンスイッチでLEDを点滅させる:Windows 10 IoT Coreで始めるIoT入門(2/2 ページ)
これまでに準備したボードコンピューターとIoTアプリ開発環境を使って、いよいよ実際にハードウエアを制御してみる。まずは押しボタンスイッチでLEDを点滅させる簡単な仕組みから実践しよう。
プロジェクトの準備
ブレッドボードの準備ができたら、次はVisual Studioでプログラムを作成してみる。まず[ファイル]メニューの[新規作成]−[プロジェクト]で新しいプロジェクトを開始する。利用するテンプレートは前回と同じく、[Visual C#]−[Windows]−[ユニバーサル]の中にある「空白のアプリ(ユニバーサルWindows)」を利用する。
プロジェクトを作成したら、最初にソリューションエクスプローラーで「参照の追加」を実行する。次の手順を実行するか、[プロジェクト]メニューの[参照の追加]を実行する。
参照マネージャーが起動するので「Windows IoT Extensions for the UWP」を選択して追加しておく。これを追加していないとWindows.Devices.Gpioクラスが利用できない。
Windows IoT用の拡張機能の追加
Windows.Devices.Gpioクラスなどを利用するためには、Windows IoT用の拡張機能(Windows IoT拡張SDK)への「参照」を手動で追加する必要がある。
(1)「Universal Windows」の下にある「拡張」を選択する。
(2)この項目を探して、チェックボックスをオンにすること。
以上でVisual Studioのプロジェクトの準備は完了である。後はページのデザインやコードの追加を行えばよい。
プログラムコードの記述
今回のプログラムだと、まずXAMLのデザイナー画面でLEDを表す円(Ellipse)を描き、スイッチの状態などに応じて描画を更新するコードを追加していく。GUI描画などの部分は通常のWindowsプログラミングと同じだが、GPIOポートを利用する部分はWindows IoT独自のクラス呼び出しなどが必要なので、先ほどのWindows IoTのサンプルプログラムを参考にして記述していく。
GUI部品の追加
ソリューションエクスプローラーでMainPage.xamlファイルを開き、「デザイン」タブを選択して画面をデザインする。画面左端のタブから「ツールボックス」を開き、円(Ellipse)を追加しているところ。このあたりは通常のWindowsのアプリケーション作成と同じだ。Windows IoT Core固有の機能は、サンプルプログラムを活用しよう。
プログラムの詳細はコードを見ていただくとして、ここではWindows IoTに固有の部分だけをいくつか取り上げ、簡単にコメントしておく。
●GPIOの初期化
Raspberry PiのGPIOを利用するためには、最初にGPIOピンの初期化作業が必要になる。利用するピンごとに入力にするのか出力にするのかを決め、出力にするなら初期状態(HにするかLにするか)もセットする。入力にするなら、Raspberry Piに内蔵されているプルアップ抵抗を利用するかどうかなどを設定する。今回のプログラムでは、LEDの出力用にピンを3本、スイッチの入力用にピンを2本利用している。
// LED駆動用(出力用)にGPIOピンを初期化する例
// LED pin
pinLedR = gpio.OpenPin(PIN_LED_R);
pinLedRValue = GpioPinValue.Low;
pinLedR.Write(pinLedRValue);
pinLedR.SetDriveMode(GpioPinDriveMode.Output);
●タイマーでループする
Windows IoTのプログラムは、例えばデータを取得しながらずっと動くだけ、といったものが少なくない。これを実現するために、Windows IoTのサンプルでは、タイマーによる周期的なタスクの繰り返しや、イベントによるメッセージの通知などが使われている。この辺りは定型なので、サンプルからコピーして使うとよいだろう。
今回のプログラムでは、青色LEDはスイッチに関係なく、この周期的なタイマーイベントを使って点滅させている。
●スイッチデータの読み取り
ユーザーがスイッチをオン/オフすると、GPIO端子の入力レベルがHigh(1)もしくはLow(0)になるので、それを読み取ればスイッチの状態が分かるのだが、現実のスイッチ部品では「チャタリング(chattering)」という現象が起きるため、その対策が必要である。チャタリングとは、スイッチをオン/オフしてもすぐに値が落ち着くことなく、しばらく「バタバタ」と暴れている状態のことである。スイッチの接点が汚れたりしていると特に激しくなる。
以下にチャタリングの例を示す。これは今回使用した回路にチャタリングが多めのスイッチを接続して、GPIO端子の部分をオシロスコープで見たところだ。信号レベルが落ち着くまでに4msec弱かかっているし、その間に何度もHighとLowレベルの変化を繰り返している。
チャタリングの観測例
上側はアナログ波形として見たスイッチ信号、下側はそれをデジタル的に見た状態。スイッチを押したり離したりした瞬間はこのような状態になっている。これは特にひどいスイッチの例だが、ほとんどのスイッチでは多かれ少なかれ、このようなチャタリングが発生する。何の対策もしないと誤入力だらけになる。
チャタリング対策の方法はいろいろあるが、一般的には、信号の変化を検知してから数msec〜数十msecだけ入力信号を無視し、その後改めて信号入力を検知し直す、という処理を行うことが多い。
Windows IoTでは、スイッチ入力をイベントとして取り扱うようになっているが、さらにスイッチ入力の場合は、指定された時間だけスイッチ入力イベントの処理を無視するという機能が用意されている。これを使ってチャタリングを除去する。
// Switch pin
pinButtonR = gpio.OpenPin(PIN_BUTTON_R);
pinButtonR.DebounceTimeout = TimeSpan.FromMilliseconds(20); // 20ミリ秒待つ
pinButtonR.ValueChanged += pinButtonR_ValueChanged; // スイッチ入力イベントの登録
pinButtonR_ValueChanged()は、スイッチ入力イベントがあった場合に呼び出されるルーチンである。今回のスイッチ回路では、、信号の「エッジ(変化)」が「High→Low」ならスイッチが押された、「Low→High」ならスイッチが離された、と判断できる。
サンプルプログラムでは、赤のスイッチでは立ち上がりと立ち下がりのエッジを処理しているが、緑のスイッチは立ち下がりエッジのみを処理している。そのため、赤のスイッチだと押している間だけLEDが点灯するが、緑のスイッチは、押すたびに点灯と消灯が切り替わる。
サンプルプログラムの実行
起動するとすぐに青いLEDが点滅する。赤のスイッチを押すと押している間だけ赤のLEDが光り、緑のスイッチを押すと、押すたびに点灯と消灯を交互に繰り返す。スイッチも接続方法も同じだが、処理が異なる。
今回はRaspberry Pi 2 Model Bにパーツを接続して制御してみた。といってもLEDやスイッチは、デジタル的にオン/オフするだけの非常にシンプルなデバイスであり、プログラム的にも特に面倒なことは何もない。次回はもう少し複雑な制御が必要なデバイスを接続してみよう。
Copyright© Digital Advantage Corp. All Rights Reserved.