.NET Gadgeteer で入力値の取得方法 3種類

組み込み開発を理解する上で、ごく基本的な内容で「何を今さら」的なことですが、大事なポイントとしてセンサー等の入力値をどうやって取るのかというものがあります。
※本稿は、初心者向けの記事と考えてください。プログラミングテクニックをお持ちの方には当たり前の内容です。

先日、Windows 女子部の勉強会にお邪魔してきたわけですが(SNS 上でやっかみ発言多数w)、その時にもデモの前にお話ししました。

そもそも、コンピューターは基本的には 「何か入力があって、それを内部で処理して、外部に出力する」の繰り返し です。何か計算などをして、終わったらプロセス終了、というものもあるでしょうが、多くの場合は基本の動きをグルグルと繰り返していると思います。

2013-06-23 14-52-15

入力を受けての処理は要件・仕様に応じて適切なロジックを組み立てる必要があります。出力はアプリの都合で適宜画面なりネットワークなりに出力することになります。
では、入力は?というと大きく分けて3通りの定石があります。

2013-06-23 14-52-51

  • モジュールが自発的にデータの変化を教えてきてくれる・・・イベントハンドラー
  • 繰り返しコードの側からセンサーに対して値をもらいに行く・・・Thread を作って適宜 Sleep を入れながら while (true) の無限ループで値を取得する
  • 定期的に時間の経過を教えてもらい、センサーに入力値をもらいに行く・・・Timer クラス

ごく当たり前の内容なので全く難しいものではありませんが、今一度これを確認してみてください。その上で Gadgeteer プログラミングを進めるとハードルが一段低くなるかと思います。

実際にコードを見ながら考えてみます。
簡単にメインボードに LED を接続しただけの構成です。(最後の1つでは Button モジュールも繋げますが)
メインボードの種類に依存するような内容ではないので、どの Gadgeteer ボードでもOKですが、今回はなんとなく Cerbuino です。深い意味はありません。

imageWP_000870

 


1. Timer を使う

分かりやすい方法ですね。タイマーで定期的に時間の経過を教えてもらう方法です。そのタイミングで処理と出力とを実行します。LED を点灯/消灯するだけの処理・出力ですが、ロジックの基本となる形ですね。

  1. using Microsoft.SPOT;
  2. using GT = Gadgeteer;
  3.  
  4. namespace LedDemo01
  5. {
  6.     public partial class Program
  7.     {
  8.         // This method is run when the mainboard is powered up or reset.   
  9.         void ProgramStarted()
  10.         {
  11.             var timer = new GT.Timer(500);
  12.             timer.Tick += timer_Tick;
  13.             timer.Start();
  14.  
  15.             // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
  16.             Debug.Print("Program Started");
  17.         }
  18.  
  19.         private bool _isLightOn = false;
  20.  
  21.         void timer_Tick(GT.Timer timer)
  22.         {
  23.             _isLightOn = !_isLightOn;
  24.             if (_isLightOn)
  25.                 led7r.TurnLightOn(7, true);
  26.             else
  27.                 led7r.TurnLightOff(7);
  28.         }
  29.     }
  30. }

 

Gadgetter では GT 名前空間内に Timer クラスがあります。間隔を引数にインスタンス化して、時間経過後のイベントハンドラーを定義してからタイマーを起動します。
動画を載せるまでもないですね、500ミリ秒ごとに LED が点灯/消灯します。

 

2. Thread でループを回す

タイマーで定期的に時間経過を教えてもらう代わりに、専用のスレッドを作り、そこで適宜 Sleep を入れながら、繰り返し(while (true) で)センサーに値をもらいに行く方法もあります。
LED をチカチカさせる程度であれば、タイマーでやってもスレッドを使ってもほとんど差はありませんが、スレッドのほうが 「他の処理を気にせずに定期的に入力値を取りに行くことに専念できる」 というメリットがあります。自分の処理が重い・時間がかかるとか、他で何か重い処理をしているとかがあっても、スレッドを分けることでお互いに影響せずに入力値を取得できます。PC に比べると組み込みでは CPU パワーが貧弱なので、PC プログラミング以上にここに気を遣うといいと思います。
※実際、別のデモを検討している際、タイマーよりもスレッドのほうがサクサク動いてくれた、ということもありましたし。

  1. using System.Threading;
  2. using Microsoft.SPOT;
  3. using GT = Gadgeteer;
  4.  
  5. namespace LedDemo01
  6. {
  7.     public partial class Program
  8.     {
  9.         // This method is run when the mainboard is powered up or reset.   
  10.         void ProgramStarted()
  11.         {
  12.             new Thread(LightLed).Start();
  13.  
  14.             // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
  15.             Debug.Print("Program Started");
  16.         }
  17.  
  18.         private void LightLed()
  19.         {
  20.             while (true)
  21.             {
  22.                 led7r.TurnLightOn(7, true);
  23.                 Thread.Sleep(500);
  24.                 led7r.TurnLightOff(7);
  25.                 Thread.Sleep(500);
  26.             }
  27.         }
  28.     }
  29. }

 

3. イベントハンドラー

モジュールによっては、デバイスの側が自発的にイベントを発行してくれるものがあります。わかりやすい例では Button モジュールの Pressed イベント、Released イベントがあります。

それに対して、センサーモジュールではアプリの側から入力値を読みに行くものが多いです。例えば深度センサーは「正面のモノまで何センチ?」と聞かれると「○○センチだよ」 と教えてくれます。それに対してロジックの側で 「50センチより近くなったらカメラで撮影する」 といった判断を加える、という使い方をします。
※実際には、Barometer (気温センサー)のように 「あらかじめ指定してくれれば定期的に温度を報告してあげるよ」 というものもあります。

Button モジュールも追加で接続してみます。

image

  1. using System.Threading;
  2. using Microsoft.SPOT;
  3. using GT = Gadgeteer;
  4.  
  5. namespace LedDemo01
  6. {
  7.     public partial class Program
  8.     {
  9.         // This method is run when the mainboard is powered up or reset.   
  10.         void ProgramStarted()
  11.         {
  12.             button.ButtonPressed += (sender, state) => led7r.TurnLightOn(7, true);
  13.             button.ButtonReleased += (sender, state) => led7r.TurnLightOff(7);
  14.  
  15.             // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
  16.             Debug.Print("Program Started");
  17.         }
  18.     }
  19. }

 

動画を載せるまでもないデモですが、勉強会での約束 (笑) なので一応載せておきます。


以上、センサー等の入力値を取得する方法3通りの紹介でした。

当たり前のコードのようですが、デバイスの機能が複雑になっても上記のいずれかの方法を使って値を取ることに変わりはありません。ここで一度確認しておくといいと思います。

広告
カテゴリー: .NET Micro Framework タグ: , パーマリンク

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中