NETMF : .NET Micro Framework v4.4 が RTW しました。が、v4.3 開発者は Visual Studio の更新プログラムに注意

.NET Micro Framework v4.4 が RTW (=Release To Web) しました。
新バージョンのリリースです。まずはおめでたいですね。

が、v4.3 QFE2 開発者の皆さんはちょっと注意が必要です。
GR-PEACHGHI Electronics の FEZ シリーズも、現在はどちらも v4.3 対応なので要注意。

Visual Studio の [拡張機能と更新プログラム] に “.NET Micro Framework project system” がありますが、これの [この拡張機能を自動的に更新する] のチェックを外してください。

2015-10-24 20-15-49

GR-PEACH にしても FEZ にしても、現在は v4.3 QFE2 対応です。NETMF の SDK はこのバージョンをインストールしているはず。
が、VS 拡張機能の設定によっては Visual Studio のプロジェクトテンプレートが自動的に v4.4 版に更新されてしまいます。
この状態で新規プロジェクトを作ると、Microsoft SPOT の参照が見えない、NETMF のエミュレータも USB デバイスも見えない、という状態になります。
※すみません、画面キャプチャ撮っていません・・・。

上記の [この拡張機能を自動的に更新する] のチェックを外すことで、v4.3 用のプロジェクトテンプレートを継続して使えます。もうしばらく v4.3 での開発をしましょう。

もし v4.4 用のテンプレートに更新されてしまった場合は、

  1. 拡張機能をアンインストール
  2. v4.3 QFE2 SDK をアンインストール (※私の環境では、修復インストールでは正しく戻せませんでした。ということで一旦アンインストール)
  3. v4.3 QFE2 SDK を再インストール
  4. v4.3 QFE2 のnetmfvs14.vsix を再インストール
  5. Visual Studio を起動して、”.NET Micro Framework project system” の [この拡張機能を自動的に更新する] のチェックを外す

の手順で、無事 v4.3 QFE2 環境に戻せます。

いや~、最初分からずに苦労した・・・


追記 (10/25)

設定変更までのタイミングのせいか、v4.4 用のテンプレートに更新されてしまうことがあるようです。(詳しい原因は分かっていませんが)
ひとまず Visual Studio のオプション設定で、自動更新をオフにしておくのがよさそうです。
これにすると、拡張機能ダイアログでは自動更新のチェックボックスが表示されなくなります。他の拡張機能の自動更新もオフになってしまいますが、この設定で乗り切れそうです。

2015-10-25 9-51-042015-10-25 10-19-31

NETMF : アナログ入力の方法(AnalogInput)

これまで、汎用のデジタル入出力(GPIO) の方法を紹介してきました。

今回は .NET Micro Framework のアナログ入力の方法を紹介します。
温度にしろ加速度にしろ、または他の値にしても、センサーモジュールから取得する値は True / False だけということは少なく、多くの場合は連続値を取ります。

もちろんボタンのように bool を取るモジュールもあります。アナログ入力は連続値を取るといいながら実際には A/D 変換したデジタルデータです。
また I2C や SPI のようなインターフェイス(いずれ、また)で値を取得するモジュールもあります。

それでもやはり、アナログ入力の理解は必須です。そこでデジタル入出力に続いて紹介します。


アナログ入力には AnalogInput を使用します。

var input = new AnalogInput(<アナログチャンネル>);

の形でインスタンスを生成します。

データを読み取るには ReadRaw メソッド、または Read メソッドを利用します。

  • ReadRaw メソッド・・・ A/D コンバーターの出力値を読み出します。
    GR-PEACH, GR-SAKURA では A/D コンバーターの分解能は 12ビットなので 0~4095 の値が返ってきます。(分解能はマイコンボードによって異なります)
  • Read メソッド・・・0~1.0 の値が返ってきます。

アナログチャンネルはマイコンボードによって定義が異なります。

GR-PEACH

ピン アナログチャンネル
A0 0
A1 1
A2 2
A3 3
A4 5
A5 7

GR-SAKURA

ピン アナログチャンネル
AD0 0
AD1 1
AD2 2
AD3 3
AD4 4
AD5 5

GR-PEACH ではピン番号とアナログチャンネルとが一致していません

クラスライブラリを利用すると、

var input = new AnalogInput(Pins.ANALOG_0);

のように記述することができます。


CdS セルを使用したサンプルを用意しました。(クラスライブラリを利用しています)
CdS セルは明るさによって抵抗値が変わる部品です。非常に安価で回路がシンプルになるので、アナログ入力のちょっとした実験には便利です。(安価なぶんだけ、通信販売だと逆に買いづらかったりしますが・・・)

using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using GrFamily.MainBoard;

namespace CdsTrial
{
    public class Program
    {
        public static void Main()
        {
            var cdsInput = new AnalogInput(Pins.ANALOG_0);

            while (true)
            {
                var reg = cdsInput.ReadRaw();
                Debug.Print(reg.ToString());

                Thread.Sleep(1000);
            }
        }
    }
}

実行結果は以下の通り。

CdS_result

回路は以下を参考にしてください。

CdS_CircuitWP_20151018_001

IoT ALGYAN の PinKit をお持ちの方は、すでに AnalogInput のセンサーデバイスをお持ちです。ハンズオンで大活躍の温度センサー(サーミスター)も AnalogInput を使っています。これについてはまた改めて。

NETMF : GPIO 接続のキャラクターディスプレイの使い方と、GR ファミリー用クラスライブラリへの追加

前の記事 で GR ファミリーの Arduino 互換ピンの定義を紹介しました。
そこでのサンプルは GR-PEACH、GR-SAKURA の LED とボタンとを使いましたが、もちろん Arduino 互換ピンを含む、他の GPIO ポートでも同じ使い方ができます。

今回のテーマは、GPIO 接続のキャラクター液晶ディスプレイ (CLCD = Charactor Liquid Crystal Display) のプログラミングです。
なおすでに公開している GR ファミリー用のクラスライブラリ には、本稿で紹介する CLCD の機能を実装しています。本稿で GPIO や CLCD の背景を理解したあとは、クラスライブラリを使って簡単にプログラミングを楽しんでください。
(難しくはないのですが、初期化も文字出力も面倒です)


■ (復習) .NET Micro Framework の GPIO

.NET Micro Framework の GPIO は以下のクラスが対応しています。

デジタル出力 OutputPort OutputPort(<ポート番号>, <出力の初期値>);
デジタル入力 InputPort InputPort(<ポート番号>, <グリッチフィルターの設定>, <プルアップ/ダウン抵抗>);
デジタル出力 (値変更時のイベント発行付き) InterruptPort InterruptPort(<ポート番号>, <グリッチフィルターの設定>, <プルアップ/ダウン抵抗>, <イベント対象の方向>);

■ キャラクター液晶ディスプレイモジュールのプログラミングモデル

市販されているほとんどの CLCD は HD44780 互換のプログラミングモデルを採用しています。
つまり HD44780 の仕様を理解すれば、デバイスごとに仕様を覚える必要はないということです。
市販のモジュールは物理的なサイズ、色などいろいろな種類があるので、好みにあわせてハードウェアを選択できます。

HD44780 については、こちらのページ の解説が分かりやすいと思います。
またモジュールを買うと付いてくるデータシート(Web 上でも公開されていると思います) でも同様の解説が載っていると思います。

ポイントは、ビットモード制御命令、それにモジュールの初期化手順です。

  • ビットモード・・・HD44780 では、8ビットモードまたは4ビットモードを選択して使用します。8ビットモードは、データ用の GPIO が8個必要です。(他に、コントロール用に2個または3個の GPIO が必要です)
    Arduino 互換ピンは数が少ないので、CLCD への表示データだけで8個のピンを使うのはあまりうれしくないです。
    今回は、ライブラリでは4ビットモードだけ実装しています。
  • 制御命令・・・表示クリア、カーソル移動、表示オン・オフなどの制御命令が決まっています。
  • 初期化手順・・・CLCD の初期化手順は意外と面倒です。4ビットモードでは12回のデータ送信が必要です。こちらのページ やデータシートなどで確認してみてください。

制御命令や表示データをモジュールに送信するには、

  1. 制御命令の場合は RS ピン (Register Select) の信号レベルを L にする、文字コード出力時は RS ピンの信号レベルを H にする
  2. E ピン (Enable) の信号レベルを H にする
  3. D4~D7 ピンに送信したいレベルの信号を設定する(4ビットモードの場合)
  4. E ピンの信号レベルを L にする
  5. (文字コード出力の場合) 手順 1~4 を D0~D3 ピンに対しても実行する

という手順を踏みます。なお制御命令によっては次の制御命令を送る前にミリ秒程度の待ち時間が必要なものもあります。


■ 実際のコード例 (抜粋)

実際のコードのポイントを紹介します。
データシートなどと対比しながら読むと、実際にどの制御命令をどの順番で送信しているかが分かると思います。
なお動作する完全なコードは、クラスライブラリのソースコードを参照してください。

制御コマンド送信

private void WriteCommand(bool db7, bool db6, bool db5, bool db4, int wait = 1)
{
    _pinRs.Write(false);

    _pinEnable.Write(true);
    _pinDb7.Write(db7);
    _pinDb6.Write(db6);
    _pinDb5.Write(db5);
    _pinDb4.Write(db4);

    _pinEnable.Write(false);
    Thread.Sleep(wait);
}

初期化

public void InitDevice(int wait = 0)
{
    Thread.Sleep(1000);

    WriteCommand(false, false, true, true, wait + 5);       // 8ビットモードにセット + 5msウェイト
    WriteCommand(false, false, true, true, wait);           // 8ビットモードにセット
    WriteCommand(false, false, true, true, wait);           // 8ビットモードにセット (2回目)
    WriteCommand(false, false, true, false, wait);          // 4ビットモードにセット
    WriteCommand(false, false, true, false, wait);          // 行数とフォントの設定1
    WriteCommand(true, false, false, false, wait);          // 行数とフォントの設定2
    WriteCommand(false, false, false, false, wait);         // 表示をオフ1
    WriteCommand(true, false, false, false, wait);          // 表示をオフ2
    WriteCommand(false, false, false, false, wait);         // 表示データをクリア1
    WriteCommand(false, false, false, true, wait);          // 表示データをクリア2
    WriteCommand(false, false, false, false, wait);         // カーソルと表示のシフト設定1
    WriteCommand(false, true, true, false, wait);           // カーソルと表示のシフト設定2
    WriteCommand(false, false, false, false, wait);             // 表示をオン1
    WriteCommand(true, _displayOn, _cursorOn, _blinkOn, wait);  // 表示をオン2

    _commandWait = wait;

    Thread.Sleep(100);
}

文字コード出力

public void Write(byte data)
{
    _pinRs.Write(true);

    _pinEnable.Write(true);
    _pinDb7.Write((data &amp;amp; 0x80) != 0);
    _pinDb6.Write((data &amp;amp; 0x40) != 0);
    _pinDb5.Write((data &amp;amp; 0x20) != 0);
    _pinDb4.Write((data &amp;amp; 0x10) != 0);
    _pinEnable.Write(false);

    _pinEnable.Write(true);
    _pinDb7.Write((data &amp;amp; 0x08) != 0);
    _pinDb6.Write((data &amp;amp; 0x04) != 0);
    _pinDb5.Write((data &amp;amp; 0x02) != 0);
    _pinDb4.Write((data &amp;amp; 0x01) != 0);
    _pinEnable.Write(false);
}

文字列送信

public void Print(string msg)
{
    for (var i = 0; i < msg.Length; i++)
    {
        Write((byte)msg[i]);
    }
}

■ クラスライブラリの実行結果

クラスライブラリは汎用にしたので、GR-PEACH でも GR-SAKURA でも同じコードが動作します。

WP_20151011_003WP_20151011_002

また別の CLCD モジュールに対しても同じコードが動作します。
なお、プログラミングモデルは同一でも、モジュールによって物理的なピン配置が異なる(例えば下の CLCD モジュールでは、ピン配置が 15, 16, 1, 2, …, 13, 14 と並んでいます)、給電は 3.3Vか 5V か異なる、などに注意が必要です。
(私はこれでハマって、文字列を表示してくれないことにしばらく悩みました)

WP_20151011_001

上記の写真の CLCD モジュールとマイコンボードや VR との接続は以下を参考にしてください。

CLCD_CircuitCLCD_Pins

NETMF : GR-PEACH, GR-SAKURA の GPIO のピンアサイン

※自分の備忘録を兼ねて。

少し間が空きましたが、以前 GPIO (InputPort, OutputPort, InterruptPort) について紹介しました。

前に紹介した例ではメインボードに載っている LED とボタンとを使いましたが、もちろん、それ以外のポートも同じ方法で使えます。
GR-PEACH や GR-SAKURA には Arduino 互換ピンが載っているので、今回はこの Arduino 互換ピンのピンアサインを紹介します。これで(GPIO 接続の)好きなモジュールを接続できるようになります。

念のため簡単に復習すると、.NET Micro Framework ではデジタル入出力に以下のように生成したオブジェクトを使用します。

デジタル出力 OutputPort(<ポート番号>, <出力の初期値>);
デジタル入力 InputPort(<ポート番号>, <グリッチフィルターの設定>, <プルアップ/ダウン抵抗>);
デジタル入力(変更時にイベント発行) InterruptPort(<ポート番号>, <グリッチフィルターの設定>, <プルアップ/ダウン抵抗>, <イベント対象の方向>);

さてポート番号の具体的な値はというと、GR-PEACH、GR-SAKURA ではそれぞれ以下のように決まっています。

以下ではアナログポートも含めて、GR-PEACH、GR-SAKURA の Arduino 互換ピンのピンアサインを紹介します。

GR-PEACH

(参考) http://www.core.co.jp/product/m2m/gr-peach/index.html#full-pin-1

ピン 別名 ポート
D0 P2_15 0x2f
D1 P2_14 0x2e
D2 P4_7 0x47
D3 P4_6 0x46
D4 P4_5 0x45
D5 P4_4 0x44
D6 P8_13 0x8d
D7 P8_11 0x8b
D8 P8_15 0x8f
D9 P8_14 0x8e
D10 P10_13 0xad
D11 P10_14 0xae
D12 P10_15 0xaf
D13 P10_12 0xac
D14 P1_3 0x13
D15 P1_2 0x12
A0 P1_8 0x18
A1 P1_9 0x19
A2 P1_10 0x1a
A3 P1_11 0x1b
A4 P1_13 0x1d
A5 P1_15 0x1f

ピンとポートとの関係ですが、GR-PEACH では別名のピン番号の “P” のあとの数値がポートの上位バイトアンダースコアの後ろの数値がポートの下位バイトとして定義されています。

例えば D0 ピンは別名が P2_15 です。そこで、上位バイトが 2、下位バイトが 15 = f なので、0x2f となります。


GR-SAKURA

(参考) http://sakuraboard.net/GR_Family_AdvanceInformation_Brief_rev002.pdf

ピン 別名 ポート
IO0 P21 17
IO1 P20 16
IO2 P22 18
IO3 P23 19
IO4 P24 20
IO5 P25 21
IO6 P32 26
IO7 P33 27
IO8 PC2 98
IO9 PC3 99
IO10 PC4 100
IO11 PC6 102
IO12 PC7 103
IO13 PC5 101
AD0 P40 48
AD1 P41 49
AD2 P42 50
AD3 P43 51
AD4 P44 52
AD5 P45 53

GR-SAKURA では、別名の Pxx の上位(P のあとの数値)×8 + 下位(最後の数値) で定義されています。

例えば IO0 は別名が P21 なので、2×8 + 1 = 17 となります。


毎回、これらのポートを調べてコーディングするのも面倒です。ということで GR ファミリー用のクラスライブラリでは、上記のピンアサインを隠蔽しています。
背景を理解した上でクラスライブラリを活用して .NET Micro Framework 開発、IoT を楽しんでください。

NETMF : GR ファミリー用のクラスライブラリを公開しました

GR ファミリー (GR-PEACH / GR-SAKURA) 用のクラスライブラリを公開しました。
GR-PEACH だけだともったいないので(?)、GR-SAKURA 用のライブラリも一緒に公開です。PinKit のセンサーボードのライブラリも入れました。

https://github.com/netmf-lib-grfamily/GrFamilyLibrary

ベースは3月の IoT ALGYAN キックオフイベント用のコンテンツとして提供したソースコード。
それをクラスライブラリ化したものの、PEACH の諸々の状況からなかなか公開に至らなかったという不遇なソースコードです。
そこから数ヶ月メンテナンスしておらずファーストリリースの勢い(ノリ)のままで整理できていないのですが、もったいないので公開することにしました。
本当の理由は、これを使ったプログラミング例を紹介したいので(こっち絡みで)、ライブラリも公開せざるを得なくなったということだったりします。(素の NETMF のコードをゴリゴリ書くのが辛い /笑)

現在の公開では、実は一点問題が残ってまして。
ライブラリ部分はVisual Studio 2013 でビルドしなければなりません。2015 でビルドすると、ライブラリを利用するアプリケーションの実行時にエラーが発生して、アプリが動作しません。
ライブラリさえ Visual Studio 2013 でビルドすれば、それを利用するアプリケーションは Visual Studio 2015 で開発しても問題ありません。
ビルドオプションの変更で解決できるのかなと思っていますが、ここの調査はこれからです。まずは As-Is で公開してしまいました。 (Visual Studio 2015 でビルドできるようになってます)


せっかく .NET / C# / Visual Studio を使った開発ができるのだから、マイコンボードでもそれっぽいコードを書きたいわけです。
展示会の説明員をしていてデモをすると一番食いつきがいいのがイベントハンドラー。それから VS のデバッグ機能です。
マイコンボードも C# っぽいコーディングができるようにとクラスライブラリを作りました。

マイコンボードのプログラミングは、比較的定型的なコードがたくさん出てきます。ソースを見ていただけると分かるとおり、超簡単なコードです。それでも、

var debugLed = new OutputPort(なんちゃら~); // ハードウェア固有の値
debugLed.Write(true);
Thread.Sleep(100);
debugLed.Write(false);

と書くよりは、

var _peach = new Peach(); // ハードウェア固有の値は Peach クラスに隠蔽
_peach.PulseDebugLed(100);

と書きたいわけです。

入力だって、Thread.Sleep しながらポーリングするコードを書くよりは、

_peach.Button.ButtonPressed += Button_ButtonPressed;

と書きたいわけです。


IoT 開発の際にはぜひこれを活用して、自分の実現したいデバイス・ガジェットに集中してください。
ハードウェアの初期化やポーリングのためのコーディングは少しでも減らして、メインの部分に注力していただけるとうれしいです。

たくさんの人がたくさんのデバイスを開発して、IoT 界隈が賑やかになればいいなと思っています。ライブラリはこれからも少しずつ整備していきます。
小さなライブラリですが、IoT 発展の一助になればうれしいです。