無事、RasPi2 上で Hello world が出せたので、今度は Lチカをやってみます。Lチカ等のサンプルは、win-iot の github にあって、https://github.com/ms-iot/samples/tree/develop/Blinky/CS なところに C# のサンプルコードがあります。RasPi2 で Windows 10 IoT を使う利点としては、画面上に何か出すの非常に簡単(ストアアプリと同じように XAML を書けばよい)が挙げられます。いまのところ、HDMI 経由のサンプルしかないのですが、そのうちキャラクタ液晶に出力するサンプルも出るかもしれません。
Raspberry Pi 2 のピン
Windows IoT – RPi2 Pin Mappings にマッピングが表示されています。以下にそのまま引用します。
ここの GPIO x のところにピンを差して Lチカをします。Arduino と違ってオスピンになっているので、ジャンパーピンのオス・メスを使わないといけないところなのですが、面倒なので HDD で使われているフラットケーブルを使います。こんな風に、フラットケーブルを差しておくと、普通のオス・オスのピンが使えるようになります(左右が逆になるので注意が必要ですが)。Raspberry Pi 電子工作レシピ に載っていた方法です。
ここでは、GPIO 13 と GPIO 26 に繋げて交互に Lチカをさせています。
Lチカのソースコード
さっくりとワンソースで書くとこんな感じになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | public sealed partial class MainPage : Page { public MainPage() { this .InitializeComponent(); this .Loaded += MainPage_Loaded; } private void MainPage_Loaded( object sender, RoutedEventArgs e) { /// プログラム開始 main(); } const int LED1_PIN = 13; const int LED2_PIN = 26; /// <summary> /// メインループ /// </summary> void main() { var gpio = GpioController.GetDefault(); var LED1 = gpio.OpenPin(LED1_PIN); var LED2 = gpio.OpenPin(LED2_PIN); LED1.SetDriveMode(GpioPinDriveMode.Output); LED2.SetDriveMode(GpioPinDriveMode.Output); LED1.Write(GpioPinValue.Low); LED2.Write(GpioPinValue.Low); new Task( async () => { while ( true ) { LED1.Write(GpioPinValue.High); await Task.Delay(500); LED1.Write(GpioPinValue.Low); await Task.Delay(500); LED2.Write(GpioPinValue.High); await Task.Delay(500); LED2.Write(GpioPinValue.Low); await Task.Delay(500); } }).Start(); } } |
- using Windows.Devices.Gpio; で名前空間を指定する。
- gpio.OpenPin で指定ピンをオープンする
- SetDriveMode で、出力(GpioPinDriveMode.Output)に設定する。
- 初期値は、消えている状態(GpioPinValue.Low)にしておく。
- Task クラスを使って、スレッドでぐるぐる廻します。間隔は Task.Delay が使えます。
C# を使うと、Task も使えるしラムダ式も使えるし簡単ですね。普通のストアアプリのように書くことができます(実は、.NET micro でも同じように書けます)。Visual Studio を使うとデバッグで一時停止させることもできるので、途中で値を確認することが可能です。
わざわざ、this.Loaded の時に Lチカを開始しているのは、今後画面アクセスをするときの開始タイミングをずらすためです。MainPage のコンストラクタで開始をしてしまうと、画面表示をしようとしてもまだ画面が作成させていない場合があるからですね。このあたりは、WPFやストアアプリと同じノウハウが使えます。
TA7267BP を使ってモーター制御をする
Lチカだけだとつまらないので、もう少しだけやっておきます。本当は、Raspberry Pi のモーター制御用のハット(Arduino のシールド)を使いたかったのですが、どうやら Windows 10 IoT の場合は、SPI 用のピンを GPIO のピンに差し換えできるような仕組みはないらしく、手元のハットが使えませんでした。仕方がないので、手元にあるモータードライバーで動作確認だけやっておきます。
配線はこんな感じで、モータードライバーを GPIO 5 と 6 を使って制御します。GPIO 5 が ON の時にはモーターが前進、GPIO 6 が ON のときはモーターが後進するようにプログラムを作ります。TA7267BP 自体は、ロジックの電源とモーターを流すための電源とを別々に取れるのですが、ここでは面倒なので、両方とも RasPi から取るようにしています。本来はコンデンサを挟まないといけないところですが、実験なのでこのままで。
モーター制御するコード
先に動かした LED のコードにモーター制御のコードを追加していきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | public sealed partial class MainPage : Page { public MainPage() { this .InitializeComponent(); this .Loaded += MainPage_Loaded; } private void MainPage_Loaded( object sender, RoutedEventArgs e) { /// プログラム開始 main(); } const int IN1_PIN = 5; const int IN2_PIN = 6; const int LED1_PIN = 13; const int LED2_PIN = 26; /// <summary> /// メインループ /// </summary> void main() { var gpio = GpioController.GetDefault(); var LED1 = gpio.OpenPin(LED1_PIN); var LED2 = gpio.OpenPin(LED2_PIN); var IN1 = gpio.OpenPin(IN1_PIN); var IN2 = gpio.OpenPin(IN2_PIN); LED1.SetDriveMode(GpioPinDriveMode.Output); LED2.SetDriveMode(GpioPinDriveMode.Output); LED1.Write(GpioPinValue.Low); LED2.Write(GpioPinValue.Low); IN1.SetDriveMode(GpioPinDriveMode.Output); IN2.SetDriveMode(GpioPinDriveMode.Output); IN1.Write(GpioPinValue.Low); IN2.Write(GpioPinValue.Low); new Task( async () => { while ( true ) { LED1.Write(GpioPinValue.High); IN1.Write(GpioPinValue.High); await Task.Delay(500); LED1.Write(GpioPinValue.Low); IN1.Write(GpioPinValue.Low); await Task.Delay(500); LED2.Write(GpioPinValue.High); IN2.Write(GpioPinValue.High); await Task.Delay(500); LED2.Write(GpioPinValue.Low); IN2.Write(GpioPinValue.Low); await Task.Delay(500); } }).Start(); } } |
やっていることはLチカと変わりませんね。モーターを制御する IN1/2 が両方ONにならないように注意すれば、モーターの正反転が簡単にできます。ここでは一つだけのモーターを使いましたが、2つ制御できれば車輪を使ったロボットが動かせるわけです。
無線化をする
このままだと常に有線LANがつながった状態になるので、無線化をします。xbox のコントローラーを使うか、Bluetooth でスマートフォンから制御するか、は後から調べることになるのですが、ms-iot のサンプルを見る限り、既に xbox コントローラで動かしたサンプルがあるので、それを流用すると楽かもしれません。ということで、こっちのほうは後日。
ピンバック: Raspberry Pi 2にWindows 10 IoT Core Insider Previewをインストール