.NET Micro Framework の入出力ポートの紹介、第3回目。
今回は InterruptPort がテーマ、GPIO の使い方の3回目です。
第1回 ・・・ OutputPort
第2回 ・・・ InputPort
第3回 (今回) ・・・ InterruptPort
■ InterruptPort
InterruptPort はデバイスのデータを入力するためのポートです。
と言うと、「InputPort との違いは何?」という疑問がわくと思います。
InterruptPort の特徴は、入力値の H / L が切り替わったタイミングでイベントを発行してくれる点です。
コンストラクターの引数によって、H→L、L→H、またはその両方でイベントを投げてくれるように指定できます。
InputPort は定期的にセンサーデータを読み出したい場合に使用し、InterruptPort は必要なデータが得られるタイミングが不定期な場合に使用するといいと思います。
例えば、定期的に室温を測定したい場合は InputPort を使い、周囲の温度が何度以上になったら何かアクションが必要な場合は InterruptPort を使うなどの使い分けです。
前回、ボタンのオンオフを InputPort を使って紹介しましたが、ボタンについては実は今回の InterruptPort のほうが適することが多いです。
■ InterruptPort の使い方
InterruptPort は次のように使います。
var button = new InterruptPort(<ポート番号>, <グリッチフィルターの設定>, <プルアップ/ダウン抵抗>, <イベント対象の方向>);
第3引数までは InputPort と同じですね。そう言えば、前回は説明を省略したのですが、GR-PEACH ではプルアップ抵抗が実装されています(このあたりは回路図を見て確認する部分です)。よって、第3引数には “Port.ResistorMode.PullUp” を指定してもいいです。
イベントの方向ですが、HからLに変わる時か、LからHに変わる時か、または両方かを指定します。
値 | イベント発行のタイミング |
InterruptEdgeBoth | 信号の立ち上がり/立ち下がりの両方 |
InterruptEdgeHigh | 信号の立ち上がり時 |
InterruptEdgeLow | 信号の立ち下がり時 |
InterruptEdgeLevelHigh | 信号が High の時 |
InterruptEdgeLevelLow | 信号が Low の時 |
InterruptNone | イベントを受け取らない |
InterruptEdgeHigh / Low では、信号の変化のタイミングでイベントが発行されます。
それに対して、InterruptEdgeHighLevel / LowLevel では信号の値によってイベントが発行されます。これらのイベント受信後には ClearInterrupt メソッドを呼んでください。
■ InterruptPort のコード例 ~ GR-PEACH / GR-SAKURA のボタン操作 ~
最後に、InterruptPort のコード例として GR-PEACH のボタン操作のコードを載せます。ボタンを押すとユーザー LED が点灯します。
これまでと同様、Microsoft.SPOT.Hardware の参照を追加する必要があります。
またこれも今までと同様、GR-SAKURA ではコメントを参考に一部書き換えてください。
なお一つ注意として、GR-PEACH では OnInterrupt イベントハンドラでは、ボタンが押されていれば data2 が 0 、離されていれば data2 が 1 になります。
using System; using System.Threading; using Microsoft.SPOT.Hardware; namespace PeachInterruptPortDemo { public class Program { // GR-PEACH private const Cpu.Pin ButtonPin = (Cpu.Pin)0x60; // ボタン private const Cpu.Pin UserPin = (Cpu.Pin)0x6c; // ユーザーLED // GR-SAKURA //private const Cpu.Pin ButtonPin = (Cpu.Pin)0x57; // ボタン //private const Cpu.Pin UserPin = (Cpu.Pin)0x56; // LED4 private static OutputPort _led; public static void Main() { var button = new InterruptPort(ButtonPin, true, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth); button.OnInterrupt += button_OnInterrupt; _led = new OutputPort(UserPin, false); (new Thread(() => { Thread.Sleep(Timeout.Infinite); })).Start(); } static void button_OnInterrupt(uint data1, uint data2, DateTime time) { var isPressed = data2 == 0; _led.Write(isPressed); } } }
「NETMF : InterruptPort の使い方とGR-PEACH / GR-SAKURAでのボタン操作のコード例」への4件のフィードバック