2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Windows PCと.NETでもLチカしてみよう(nanoFrameworkの話じゃないよ)

Posted at

:star: はじめに

GPIOでLEDを点灯させるLチカはRaspberry PiやM5Stackで試すのが定番ですが、Windows PCではラズパイみたいな汎用GPIOがないので、PC単体だけでブレッドボードLEDやGrove規格のLEDモジュールを直接点灯させることはできません。

しかし、USB-GPIOデバイスを使用すればWindowsから制御してLチカを試すことはできます。
MCP2221Aを搭載するUSBドングル・ブリッジボードをを使用して、Windows上で.NETアプリからのLチカを試してみます。

:pencil: 概要

MCP2221Aとは

MCP2221(MCP2221A)はMicrochip社のUSB-各種シリアル/汎用I/Oを橋渡しする小型ブリッジICです。
PCからUSBで接続し、I2C、UART、GPIO、ADC/DAC等を扱えるものです。
Windows PCからはHIDデバイス及びCOMポートとして認識され、HIDのAPIで制御ができます。

環境

項目 概要
OS Windows 11
言語/ランタイム C#/.NET 10
USB-GPIO みんなのラボ MR-GROVE-USBDONGLE
みんなのラボ MR-GROVE-B
Grove LED SeeedStudio GROVE LED
温度センサー M5Stack用温湿度気圧センサユニットVer.3(ENV III)
ライブラリ Smdn.Devices.MCP2221
自作MCP2221ManagedWrapper

USB-GPIOはみんなのラボのUSBドングル及びブリッジボードを使用します。
LEDはブレッドボード上のものとGrove接続のものを使います。

また、後でGPIOではなくI2Cの方も試すためにM5 Stack用のセンサーも使用してみます。
どの組み合わせで試しているかは以降に記述します。

この辺の製品についてはマルツオンラインとかでも購入可能です。

:red_circle: LED制御その1

実行環境

.NETのMCP2221用のライブラリはいくつかありますが、今回はまず以下を使用してみます。

Windows上では内部的にはHidSharpを使っていますが、Linuxでもlibusbを使って動作するようです。

GPIOにはUSBドングルの方を使用して、ブレッドボード上のLEDを制御します。
このUSBドングルではGP2、GP3のポートが使用できます。

プログラム

using System.Device.Gpio;

using Smdn.Devices.MCP2221;

using var device = MCP2221.Open();

device.GP2.ConfigureAsGPIO(PinMode.Output);
device.GP3.ConfigureAsGPIO(PinMode.Output);

while (true)
{
    device.GP2.SetValue(true);
    device.GP3.SetValue(false);
    Thread.Sleep(1000);
    device.GP2.SetValue(false);
    device.GP3.SetValue(true);
    Thread.Sleep(1000);
}

実行結果

IMG_0261.gif

処理としては、ピンを出力に設定してSetValue()でHIGH/LOWを切り替えているだけのものです。
LEDが交互に点滅することを確認できます。

:large_blue_circle: LED制御その2

実行環境

MCP2221の制御用ライブラリですが、オフィシャルからダウンロードできるものもあります。

上記からMCP2221 DLL (v2.2.1)をダウンロードするとその中には.NET用のライブラリもありますが、残念ながらレガシー.NET Framework用のものになります。

しかしUnmanaged用のDLLも含まれているので、それを使うための定義をすれば、最新の.NETからでもP/Invokeで使用できます。
っということで、そのための薄いラッパーライブラリを自前で用意したので、これを使ったサンプルも書いてみます。

このライブラリはダウンロードしたファイル中にmcp2221_dll_um_x64.dllを使うためのものなので、アプリケーションにはmcp2221_dll_um_x64.dllも含める必要があります。

こちらではGPIOにはブリッジボードの方を使用して、LEDはGrove接続のものを使用してみます。
このブリッジボードではGP0~GP3に個別のGroveポートが用意されています。

プログラム

using MCP2221ManagedWrapper;

using var device = Mcp2221.OpenByIndex(0);

// GPIOを出力に設定
device.SetGpioDirection(PinDirection.Output, PinDirection.Output, PinDirection.Output, PinDirection.Output);

while (true)
{
    // Hight/Lowを繰り返してチカチカ
    device.SetGpioValues(PinValue.High, PinValue.Low, PinValue.High, PinValue.Low);
    Thread.Sleep(1000);
    device.SetGpioValues(PinValue.Low, PinValue.High, PinValue.Low, PinValue.High);
    Thread.Sleep(1000);
}

実行結果

IMG_0262.gif

やっていることはUSBドングル/Smdn.Devices.MCP2221版に同じです。
mcp2221_dll_um_x64.dllが提供しているAPIは4ポートまとめて設定するものだったのでそのラッパーを使用していますが、ラッパー層で1ポート単位の処理も用意はしてあります。

:thermometer: 温度センサー制御

実行環境

GPIOでのLチカの確認はできたので、ついでにI2C機能も試してみたいと思います。
GPIOが1本の線でHigh/Lowを扱うものに対して、I2Cは2本の線で複数デバイスとのやりとりができるものです。

Groveのケーブル色でいえば、GPIOは以下の内容で信号線に対してHigh/Lowを設定するもので、Lチカもプログラム的には信号のHigh/Lowを切り替えているだけのものですが。

内容
VCC(電源、+3.3V または +5V)
GND(グランド、0V)
黄と白 SIG(ドングルの場合GP2とGP3に対応)

I2Cでは以下の内容で、アドレスを指定して該当デバイスに対してRead/Writeを行ないます。

内容
SCL(クロック)
SDA(データ)

機器としてはM5Stack用の環境センサーENV IIIを使用してみます。
このユニットには温湿度センサーSHT30と気圧センサーQMP6988が載っていますが、とりあえず扱いが単純な温度・湿度の取得だけを行ないます。

I2C.png

プログラム

using MCP2221ManagedWrapper;

using var device = Mcp2221.OpenByIndex(0);

// 初期設定
device.SetSpeed(100000);
device.SetAdvancedCommParams(timeout: 20, maxRetries: 3);

var data = new byte[6];
while (true)
{
    // コマンドWrite
    device.I2cWrite(0x44, true, [0x2C, 0x06]);

    Thread.Sleep(20); // 計測待ち

    // データRead: T(2) + CRC + RH(2) + CRC
    device.I2cRead(0x44, true, data);

    // 応答解析
    var rawTemperature = (ushort)((data[0] << 8) | data[1]);
    var temperature = (float)(-45.0 + (175.0 * rawTemperature / 65535.0));

    var rawHumidity = (ushort)((data[3] << 8) | data[4]);
    var humidity = (float)(100.0 * rawHumidity / 65535.0);

    Console.WriteLine($"Temperature={temperature:F2}C, humidity={humidity:F2}%");

    Thread.Sleep(1000);
}

実行結果

Temperture.png

プログラム的には、アドレス(0x44がSHT30のアドレス)を指定してI2cWriteでコマンドを送信し、I2cReadでデータを取得しているだけです。
それっぽい値が取得できているので、I2Cの確認もできました。

:hammer_pick: 完全なコード

完全なソースコードは以下にあります。

:rabbit: うさコメ

デバイス制御というとRaspberry PiやM5StackにPythonの話ばかりなので、あえてWindows PC上で.NETを使って制御する例を書いてみました( ˙ω˙)
普通はデバイス制御についてはM5Stackあたりにまかせて、WindowsからはM5Stackを介して制御すれば良い気はしますが、ネタの1つとして。

ところで、機器メーカーの出しているSDK/ソフトウエアでは、サポートプラットフォームが古かったり、API設計が微妙で「ソフトウエア設計がえろう上手おすなぁ。素人さんみたいに初々しくて感心いたしますわ」みたいに感じるものが多かったりで、それって日本のメーカー固有の話なのかと思っていましたが、世界的にもそうなんですかね( ˙ω˙)?

MCP2221のオフィシャルライブラリも、レガシー.NET Framework用のものしか入っていなかったので。
API自体はベタなだけで、京都スラングを使うような内容ではないですが。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?