という訳で(どういうわけで?) netduino ですよ。
我ながら上はクラウドから下は電子工作まで、スケーラビリティありすぎるとか思ってたりもしないでも無いのですが、 netduino plus が手元に届いたのでフィジカルコンピューティングに手を出すわけでございます。
という訳で最初はメカニカルスイッチ、プッシュスイッチとかタクトスイッチとか、言い方は色々ありますが、結局の所、線が繋がれば電気が流れるという最も単純な部品でございます。
こいつを扱うに当たって、正論理入力、負論理入力の2通りでの回路の組み方と、それを netduino で受けるプログラムを取り上げたいと思います。
まず、回路の組み方にあたって、デジタル回路の原則を一つ。
入力に使うPINは必ず何かに接続しなければならない。
今回はメカニカルスイッチなので、導通状態でない場合、PINは電気的に浮いてしまい、この原則に違反してしまいます。
このPINを浮かせない様にする方法として、スイッチとPINの間で電流制限の為の抵抗を介して電源側、またはGND(0V側)へ接続する事になり、これをそれぞれプルアップ、プルダウンと言います。
最初にプルダウンでの正論理デジタル入力回路を

スイッチを押していない状態の場合、JP1からR1の電流制限抵抗を介してGNDへ電流が流れ出ています、このためJP1で示される値はLOになります。スイッチを押すと、JP1で示されるPINにS2を介して+3V3から電流が流れ込み、これによってJP1の値はHIとなります。R1で示される制限抵抗が無い、またはJP1の入力抵抗より小さい場合には電流はJP1からR1を介してGNDへ流れ続けますので、LOになり続けます。PINの入力抵抗と電圧を元にR1の値を決める必要があります。(4K7あたりを使う事が多いでしょうか)
このようにスイッチを押している場合に HI 、押していない場合にLOという事で「押す」という事に対して一致しています。このような一致関係になる物を正論理と言います。
では正論理入力ポートの設定です。
var exSwIn = new InputPort(
Pins.GPIO_PIN_D1,
false,
Port.ResistorMode.Disabled)
{GlitchFilter = true};
ポイントは Port.ResistorMode を Disabledにするという事です。そして回路図通りの部品構成で回路を組み、入力は以下のコードで受けます。GlitchFilterの設定はお好みで、trueにした方が入力の処理は単純になります。
var value = exSwIn.Read();
InputPort.Readはtrue/false で値をポートのHI/LOそれぞれを示し、回路が正論理ですので、そのまま処理に使えます。
続いて、負論理のデジタル入力回路を示します。

スイッチを押していない状態の場合、PINには電流制限抵抗を介して電流が流れ込みますので、HIレベルとなります。スイッチを入れると抵抗無しでGNDへ接続されますので、+3V3とPINからGNDへ電流が流れます。このPINから電流が流れ出る事によりPINはLOレベルとなります。
では負論理入力ポートの設定です。
var exSwIn = new InputPort(
Pins.GPIO_PIN_D1,
false,
Port.ResistorMode.PullUp)
{GlitchFilter = true};
このようにResisterModeでPullUp を指定する事で、IC内部のプルアップ抵抗を使え、単純にスイッチを介してGNDにつなぐだけでよくなります。
そして入力を受ける所では負論理である事を元に Read の結果を反転して使う事になります。
で、「ResistorModeにPullDownあるのに、なんで使わなかったの?」の答えは、IC内にPullDown抵抗が無いからです。PullDownは.NET Micro Framework上には定義がありますが、ハードウェアの実装に含まれているかは関係が無いため、ハードウェアにそれがあるかは確認しなければならず、またハードウェアに無い機能は使えませんので、netduinoでそれを指定するとポートの初期化時に例外が発生します。
んでは、まとめサンプルを。
部品点数が少なくて済む為、負論理入力を使います。このスイッチの状態をnetduino基板上のLEDに反映するという場合には以下のようになります。
public class Program
{
public static void Main()
{
var led = new OutputPort(Pins.ONBOARD_LED, false);
var exSwIn = new InputPort(Pins.GPIO_PIN_D0,
false,Port.ResistorMode.PullUp)
{GlitchFilter = true};
while (true)
{
led.Write(!exSwIn.Read());
Thread.Sleep(10);
}
}
}
Thread.Sleepは適度に、あまり寝ないで働くとデバッガで介入できなくなったりとかするそうですのでご注意を。