はじめに
GPIOでLEDを点灯させるLチカはRaspberry PiやM5Stackで試すのが定番ですが、Windows PCではラズパイみたいな汎用GPIOがないので、PC単体だけでブレッドボードLEDやGrove規格のLEDモジュールを直接点灯させることはできません。
しかし、USB-GPIOデバイスを使用すればWindowsから制御してLチカを試すことはできます。
MCP2221Aを搭載するUSBドングル・ブリッジボードをを使用して、Windows上で.NETアプリからのLチカを試してみます。
概要
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用のセンサーも使用してみます。
どの組み合わせで試しているかは以降に記述します。
この辺の製品についてはマルツオンラインとかでも購入可能です。
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);
}
実行結果
処理としては、ピンを出力に設定してSetValue()でHIGH/LOWを切り替えているだけのものです。
LEDが交互に点滅することを確認できます。
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);
}
実行結果
やっていることはUSBドングル/Smdn.Devices.MCP2221版に同じです。
mcp2221_dll_um_x64.dllが提供しているAPIは4ポートまとめて設定するものだったのでそのラッパーを使用していますが、ラッパー層で1ポート単位の処理も用意はしてあります。
温度センサー制御
実行環境
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が載っていますが、とりあえず扱いが単純な温度・湿度の取得だけを行ないます。
プログラム
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);
}
実行結果
プログラム的には、アドレス(0x44がSHT30のアドレス)を指定してI2cWriteでコマンドを送信し、I2cReadでデータを取得しているだけです。
それっぽい値が取得できているので、I2Cの確認もできました。
完全なコード
完全なソースコードは以下にあります。
うさコメ
デバイス制御というとRaspberry PiやM5StackにPythonの話ばかりなので、あえてWindows PC上で.NETを使って制御する例を書いてみました( ˙ω˙)
普通はデバイス制御についてはM5Stackあたりにまかせて、WindowsからはM5Stackを介して制御すれば良い気はしますが、ネタの1つとして。
ところで、機器メーカーの出しているSDK/ソフトウエアでは、サポートプラットフォームが古かったり、API設計が微妙で「ソフトウエア設計がえろう上手おすなぁ。素人さんみたいに初々しくて感心いたしますわ」みたいに感じるものが多かったりで、それって日本のメーカー固有の話なのかと思っていましたが、世界的にもそうなんですかね( ˙ω˙)?
MCP2221のオフィシャルライブラリも、レガシー.NET Framework用のものしか入っていなかったので。
API自体はベタなだけで、京都スラングを使うような内容ではないですが。



