NETMF : I2C 接続のセンサーモジュール活用例(三軸加速度センサー ADXL345 の場合)

I2C の使用例としてキャラクターディスプレイモジュールについてすでに紹介しました。
キャラクターディスプレイは出力モジュールなので、マイコンボードからのコマンドも出力方向のみ(キャラクターディスプレイからデータを読み打差宇ことはない)でした。

今回は双方向のデータ通信について紹介します。センサーデバイスですね。
センサーデータを要求するコマンドをマイコンボードからモジュールに送信し、センサーデータをマイコンボードで受け取るという通信です。
モジュールによって通信に使う領域(レジスター)は異なりますが、送受信ともに既定の領域を使ってデータをやりとりします。


今回使用するモジュール

センサーモジュールの例として、今回は ADXL345 を使用します。3軸の加速度センサーです。
安価で入手しやすいモジュールです。
PinKit のセンサーボードをお持ちの方は以下のコードがそのまま使えます。
GR-PEACH のみで購入して PinKit のセンサーボードを持っていない方は秋月あたりでモジュールを購入できます。

WP_20150313_006WP_20151103_003

※写真では実験用シールドに ADXL345 を載せていますが、もちろん普通のブレッドボードなどを使ってもかまいません。加速度センサーは持ち上げて傾けるのでブレッドボードが分かれているよりマイコンボードと一体化しているほうがやりやすいというだけの理由です。


ADXL345 固有の情報

ADXL345 を使うにあたって必要な(モジュール固有の情報)をまとめておきます。

I2C アドレスは、私が使った上記のモジュールでは 0x1d です。

レジスタ(通信のための領域)のうち、最低限必要なものは以下です。

  • 0x2d・・・電源管理(センサーデータ取得でも使います)
  • 0x31・・・データフォーマット(加速度の測定範囲を設定)
  • 0x32~0x37・・・x, y, x 方向の加速度データ

I2CDevice の継承クラス

.NET Micro Framework の I2CDevice クラスは少しだけ不便なところがあるので、少し拡張してあげます。
これは I2C キャラクターディスプレイの例で紹介したものと同じです。

using Microsoft.SPOT.Hardware;

namespace AccelTest01
{
    public class I2CDeviceEx
    {
        private readonly I2CDevice _i2C;
        private readonly int _timeout;

        private readonly byte[] _adata = new byte[1];   // アドレス指定用のバイトデータ領域
        private readonly byte[] _rdata = new byte[1];   // データ受信用のバイトデータ領域
        private readonly byte[] _wdata = new byte[2];   // データ送信用のバイトデータ領域

        private I2CDevice.I2CTransaction[] _trRegRead;      // データ受信用のトランザクションデータ
        private I2CDevice.I2CTransaction[] _trRegWrite;     // データ送信用のトランザクションデータ

        public I2CDeviceEx(ushort i2CAddress, int clockRateKhz = 100, int timeout = 1000)
        {
            _i2C = new I2CDevice(new I2CDevice.Configuration(i2CAddress, clockRateKhz));
            _timeout = timeout;

        }

        protected byte RegRead(byte reg)
        {
            _adata[0] = reg;
            _trRegRead = new I2CDevice.I2CTransaction[] {
                I2CDevice.CreateWriteTransaction(_adata),
                I2CDevice.CreateReadTransaction(_rdata) };
            _i2C.Execute(_trRegRead, _timeout);
            return _rdata[0];
        }

        protected void RegReads(byte reg, ref byte[] data)
        {
            _adata[0] = reg;
            _trRegRead = new I2CDevice.I2CTransaction[] {
                I2CDevice.CreateWriteTransaction(_adata),
                I2CDevice.CreateReadTransaction(data) };
            _i2C.Execute(_trRegRead, _timeout);
        }

        protected void RegWrite(byte reg, byte val)
        {
            _wdata[0] = reg;
            _wdata[1] = val;
            _trRegWrite = new I2CDevice.I2CTransaction[] { I2CDevice.CreateWriteTransaction(_wdata) };
            _i2C.Execute(_trRegWrite, _timeout);
        }

        protected void RegWriteMask(byte reg, byte val, byte mask)
        {
            var tmp = RegRead(reg);
            _wdata[0] = reg;
            _wdata[1] = (byte)(tmp & ~(int)mask | ((int)val & (int)mask));
            _trRegWrite = new I2CDevice.I2CTransaction[] { I2CDevice.CreateWriteTransaction(_wdata) };
            _i2C.Execute(_trRegWrite, _timeout);
        }
    }
}

 


ADXL345 固有のクラス

ADXL345 固有の機能をクラスにまとめるとこうなります。

アプリからは Measure メソッドを呼び出したあとに GetXYZ メソッドを呼び出すと加速度データが得られます。
なお ADXL345 では測定範囲は設定により変更できますが、今回はサンプルということで 4G に固定しています。
このあたりの変更は GrFamilyLibrary のソースコードを参考にしていただければ。

public class Adxl345 : I2CDeviceEx
{
    private const byte PowerCtl = 0x2d;
    private const byte DataFormat = 0x31;
    private const byte DataX0 = 0x32;

    private byte[] _xyz = new byte[6];

    public Adxl345(ushort adxl345Address, int defaultClockRateKhz, int timeout) :
        base(adxl345Address, defaultClockRateKhz, timeout)
    {
        Thread.Sleep(1000);

        SetRange4G();
        ToWakeup();
    }

    public void Measure()
    {
        RegWriteMask(PowerCtl, 0x08, 0x08);
    }

    public void GetXYZ(out Int16 x, out Int16 y, out Int16 z)
    {
        RegReads(DataX0, ref _xyz);
        x = (Int16)(((UInt16)_xyz[1] << 8) + (UInt16)_xyz[0]);
        y = (Int16)(((UInt16)_xyz[3] << 8) + (UInt16)_xyz[2]);
        z = (Int16)(((UInt16)_xyz[5] << 8) + (UInt16)_xyz[4]);
    }

    private void SetRange4G()
    {
        // 4Gまで測定するには第2引数を 0x01
        // 2G・・・0x00, 4G・・・0x01, 8G・・・0x10
        RegWrite(DataFormat, 0x01);     
    }

    private void ToWakeup()
    {
        RegWriteMask(PowerCtl, 0x00, 0x04);     // 通常モードに入る(スリープモードではない)
    }
}

 


アプリケーションのコード例

ADXL345 を使うアプリケーションのコード例は以下の通り。

1秒間隔で加速度データを読み出しています。

.NET っぽくイベントハンドラーを使いたいなどは、(ここでもやはり)GrFamilyLibrary を参照してください。

public class Program
{
    private const ushort Adxl345Address = 0x1d;     // ADXL345のアドレス
    private const int DefaultClockRateKhz = 100;    // 転送速度 (KHz)
    private const int Timeout = 1000;               // 送受信ごとのタイムアウト

    public static void Main()
    {
        var prog = new Program();
        prog.Run();
    }

    private void Run()
    {
        var accel = new Adxl345(Adxl345Address, DefaultClockRateKhz, Timeout);

        while (true)
        {
            Int16 x;
            Int16 y;
            Int16 z;

            accel.Measure();
            accel.GetXYZ(out x, out y, out z);
            Debug.Print("X = " + x + ", Y = " + y + ", Z = " + z);

            Thread.Sleep(1000);
        }
    }
}

 


念のため、結線について

I2C は本当に結線が簡単ですが、念のため紹介しておくと以下のようにします。
※PinKit のセンサーボードをお持ちの方は、もちろん GR-PEACH に載せるだけ。

2016-01-16-18-23-51WP_20151103_004

GR-PEACH の Fritzing 用パーツを公開しました

GR-PEACH の Fritzing パーツを公開しました。

マイコンボードを使った回路を保存したり公開したりしたいと思った場合、当然ですが、まずは回路図を書く必要があります。
その時に便利なのが Fritzing ですね。無償ですし、直感的に使えます。
(なお、本稿では Fritzing 自体の使い方は紹介しません。ネット上にたくさん情報があるので、そちらを参照してください)

GR-PEACH を買った方、IoT ALGYAN のハンズオンなどで GR-PEACH を手に入れた方は、ぜひ活用してたくさんのデバイスを開発して、情報を公開してください。


パーツを Fritzing にインポートする手順

GR-PEACH パーツを Fritzing で使用するにはインポートする必要があります。
その手順については紹介しておきます。

  1. パーツをダウンロード
  2. Fritzing を起動(ダウンロードは こちらのサイト から)
  3. My Parts を開く
    2015-12-28 9-54-17
  4. My Parts のメニューまたは右クリックで [Import …] を選択
    2015-12-28 9-54-49
  5. ダイアログでダウンロードしたパーツを選択
    2015-12-28 9-55-332015-12-28 9-56-35
  6. My Parts のメニューまたは右クリックで [Save Bin] を選択
    2015-12-28 9-56-46

以上です。
これで GR-PEACH が Fritzing で使えるようになります。

2015-12-28 10-03-432015-12-28 10-03-55

 


制限事項

公開したパーツは以下の制限事項があります。

  • Arduino 互換ピン(外側の1列のピン)のみ定義しています。GR-PEACH はピンが3列並んでいますが、これらについては実装していません。
  • 3.3V ピンに配線すると、回路図ビューで GR-PEACH のピンの途中から結線されることがあります。パーツの svg を修正すればいいのですが、回路図上は問題ないのでそのまま残しています。

ダウンロードしたパーツの fzpz ファイルの拡張子を zip に変更すると svg ファイルが見えます。気になる方は修正していただければ。

 


■  (おまけ)パーツ作成の経緯

GR-PEACH ありの回路図を Fritzing で作る場合、Arduino Uno R3 で代替することが考えられます。デバイスのインターフェイスが GPIO の場合には問題ありません。

ところが I2C 対応のデバイスを使うと困ってしまいます。Arduino の I2C ポートは A4, A5 ピンと共用なんですよね。
GR-PEACH は違います。専用のピンを持っています。
ハンダジャンパーで A4, A5 ピン共用に変更できるので、Arduino のシールドを使いたいなどの理由があればハンダジャンパーで A4, A5 ピン共用にできますが、それ以外では意味はないでしょう。

2015-12-28 10-04-46

ということで、自分が GR-PEACH で I2C な回路を組んで回路図がほしくなったために、Fritzing 用パーツを作ったのでした。

いざ作り始めると Fritzing の パーツの仕様、Parts Editor のクセとか SVG エディタ(Inkscape を使いました)の使い方やらで、結構苦労しました。
ようやく公開にこぎ着けたという感じです。

NETMF : NTP サーバーから日時を取得するメソッドを GR ファミリー用クラスライブラリに追加

だいぶ間が空いてしまいましたが(NETMF のクラスライブラリ ネタは 2ヶ月ぶり!)、GR ファミリー用クラスライブラリに機能を追加しました。

 

NTP サーバーから日時を取得してマイコンボードのシステム時計に設定する機能です。


.NET Micro Framework は TimeService というクラスを元々持っています。これが NTP サーバーから日時を取得をする機能を持っています。
持っているはずなのですが、なぜか動作しないマイコンボードがあるようなんです。

・・・ほしいですよね、日時の取得。
IoT を考えると、正確な日時は必須と言っていいはず。

ということで、クラスライブラリに実装しました。
実装しましたとは行ったものの、元ネタはネットにちゃんとあって、例えば Stackoverflow あたりで見つかります

 

これを GR ファミリー用のクラスライブラリにも入れました。
Static なメソッドで実装しているので、

SystemTimeInitializer.InitSystemTime();

とすれば、マイコンボードのシステム時計に現在日時を設定してくれます。
利用の際は、GrFamily.Utility.NetworkUtility.dll を参照設定してください。

あとは日時が必要になるたびに、みんな大好き DateTime.Now を呼びだしてください。

 


クラスライブラリは、

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

で公開しています。「ソースは不要」という方はビルド済みの DLL をあわせて公開しているので、これを使ってください。
ただしドキュメント整備が全くできていないので(すみません)、サンプルアプリのソースコードはチラッと眺めてみることをお勧めします。

 

PS. もしかしたら、いずれ GR-PEACH 用のファームの中に組み込まれるかも。その時が来たらこの実装を公式のファームに昇格させて、クラスライブラリからは卒業させるかも、です。

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 を楽しんでください。