Arduino Wiring の移植ガイド
Arduino Wiring のスケッチやライブラリは、Visual Studio 内の Arduino Wiring プロジェクトにコピーして貼り付けることで、Raspberry Pi 2、Raspberry Pi 3、または Minnowboard Max で動作させることができます。 この際、Windows 環境や使用しているボードとの互換性を高めるために、場合によってはこれらのファイルに若干の修正を加える必要があります。 このガイドでは、このような修正について、および Arduino Wiring プロジェクトをデプロイする際に発生する可能性のある一般的な問題について説明します。
移植
ピンを更新する
言うまでもなく、多くのスケッチやライブラリ (特に arduino シールド用のもの) には、Arduino デバイスの特定のコネクタ ピンへの参照が含まれていることがあります。 そのため、作業しているデバイスや使用している構成に適したコネクタ ピンを使用するようにスケッチをカスタマイズする必要があります。
最終的に、Arduino Wiring で「ピン」を参照する機能を使用するには、物理的なコネクタのピン番号が必要になります。 これらの番号を直接使用することもできますが、特定のボードのコネクタ ピンに対応している、いくつかの定義済みのピン名も提供しています。
たとえば、Raspberry Pi 2 および 3 の物理コネクタ ピン 29 は、GPIO5
とも呼ばれます。 次のコマンドのいずれかを使用することで、Raspberry Pi 2 および 3 で GPIO ピン 5 を HIGH 状態に設定できます。
pinMode( 29, OUTPUT );
digitalWrite( 29, HIGH );
or
pinMode( GPIO5, OUTPUT );
digitalWrite( GPIO5, HIGH );
定義済みのピン名は pins_arduino.h に記載されており、これはすべての Arduino Wiring プロジェクトに含まれています。しかし、構築するハードウェアのセットアップに応じて利用可能な物理コネクタ ピンが異なるため、ここでは、各デバイスで利用可能なピン名を説明するための表も記載しています。
Raspberry Pi 2 および 3
ピン定義 | 対応するピン番号 |
---|---|
LED_BUILTIN | オンボード LED |
GPIO* where * refers to [0, 27] |
ピンの配置図を参照 |
GCLK | 7 |
GEN* where * refers to [0, 5] |
*ピン配置図を参照 |
SCL1 | 5 |
SDA1 | 3 |
CS0 (または CE0 または SS) | 24 |
CS1 (または CE1) | 26 |
SCLK (または SCK) | 23 |
MISO | 21 |
MOSI | 19 |
RXD | 10 |
TXD | 8 |
Minnowboard Max
ピン定義 | 対応するピン番号 |
---|---|
GPIO* where * refers to [0, 9] |
ピンの配置図を参照 |
SCL | 13 |
SDA | 15 |
CS0 (または CE0 または SS) | 5 |
SCLK (または SCK) | 11 |
MISO | 7 |
MOSI | 9 |
CTS1 | 10 |
RTS1 | 12 |
RX1 | 8 |
TX1 | 6 |
RX2 | 19 |
TX2 | 17 |
一般的な問題
Visual Studio で "Arduino Wiring Application" の Visual C++ プロジェクト テンプレートが見つからない
原因: Visual Studio 用の Windows IoT プロジェクト テンプレート拡張機能がインストールされていません。
解決策: Visual Studio で Arduino Wiring プロジェクトを作成するには、Windows IoT プロジェクト テンプレート用の Visual Studio 拡張機能をインストールする必要があります。 Windows IoT Core プロジェクト テンプレート拡張機能ページに移動して、Visual Studio ギャラリーから拡張機能をダウンロードします。
関数を呼び出す際に "識別子が見つかりません" というエラーが発生する
原因: このエラーは、ドキュメントでまだ宣言されていない関数が呼び出された場合、リンカー プロセス中に発生します。
解決策: C++ では、関数を呼び出すにはまずそれを宣言する必要があります。 スケッチ ファイルで新しい関数を定義した場合、その宣言または関数の実装全体のいずれかが、その関数が呼び出されるより上部 (通常はドキュメントの先頭) に記載されている必要があります。
例:
次のコード ブロックを実行すると、"'myFunction': 識別子が見つかりません" というエラーが発生します
void setup()
{
}
void loop()
{
myFunction();
}
void myFunction()
{
//do something
}
これに対する解決策は 2 つあります。 まず、呼び出しより上部で関数を宣言します。 通常、この宣言はファイルの先頭で行われます。
// Declare function here
void myFunction();
void setup()
{
}
void loop()
{
myFunction();
}
// And, define the function here
void myFunction()
{
//do something
}
または、関数の実装全体を呼び出しより上部に移動することもできます。 これにより、関数の宣言と定義の両方が同時に実行されます。
void setup()
{
}
void myFunction()
{
//do something
}
void loop()
{
myFunction();
}
初期化中にソリューションが無限にハングする
初期化時に C++ ソリューションが無限にハング (デッドロック) するという既知の問題が確認されています。 ソリューションが無限にハングしていると思われ、さらにデバッガーを使用して Arduino Wiring アプリケーションの setup() や loop() セクションのステートメントに "侵入" できない場合は、この問題が発生している可能性があります。
原因: ソリューションの初期化が完了する前に、オブジェクトの作成や関数の呼び出しが行われたことにより、非同期アクションが発生しています。 これは、オブジェクトのコンストラクターによって pinMode
などの API 関数が呼び出されていることが原因と考えられます。
Solution: オブジェクトのコンストラクターや関数の呼び出しを、コードの初期化セクションから離して setup()
ブロックに移動します。
例 1:
このスケッチの実行では、ソリューション自体が初期化される前に setPinModes()
という関数が呼び出されています。 ソリューションは見かけ上は実行されていますが、無限にハングします。
bool setPinModes();
int pin = GPIO5;
bool initialized = setPinModes();
void setup()
{
}
void loop()
{
if( initialized )
{
//do something
}
}
bool setPinModes()
{
if( pin < 0 ) return false;
pinMode( pin, OUTPUT );
return true;
}
解決策は以下の通りです。ここでは、setPinModes()
の実行を setup()
関数に移しています。
bool setPinModes();
int pin = GPIO5;
bool initialized;
void setup()
{
initialized = setPinModes();
}
void loop()
{
if( initialized )
{
//do something
}
}
bool setPinModes()
{
if( pin < 0 ) return false;
pinMode( pin, OUTPUT );
return true;
}
例 2:
このスケッチを実行すると、setup()
が呼び出される前にスタック上にオブジェクトが作成されます。 このオブジェクトはコンストラクターで pinMode
を呼び出しているので、これもデッドロックの原因となります。 これは一般的な問題ではありませんが、特定のライブラリ (Arduino LiquidCrystal
ライブラリなど) のオブジェクトで発生する可能性があります。
class MyObject
{
public:
MyObject()
{
pinMode( GPIO5, OUTPUT );
}
void doSomething()
{
//...
}
};
MyObject myObject;
void setup()
{
}
void loop()
{
myObject.doSomething();
}
この解決策は次のとおりです。 ここでは、オブジェクトをオブジェクト ポインターに変更し、オブジェクトの初期化を setup()
に移しています。
class MyObject
{
public:
MyObject()
{
pinMode( GPIO5, OUTPUT );
}
void doSomething()
{
//...
}
};
MyObject *myObject;
void setup()
{
myObject = new MyObject();
}
void loop()
{
myObject->doSomething();
}
Serial.print()
と Serial.println()
を使用する
多くの Arduino スケッチでは、シリアル コンソール (開いている場合) へのデータ出力や、シリアル回線 (USB または tx/rx) への書き込みに Serial
が使用されています。
Lightning SDK の以前のバージョンではハードウェア Serial
がサポートされていなかったため、Visual Studio のデバッガ出力ウィンドウに出力する Log()
関数が用意されていました。 Serial.print*()
や Serial.write()
は削除する必要がありました。
しかし、Lightning SDK v1.1.0 からは、Hardware Serial
のサポートが追加され、Serial.print*()
や Serial.write()
関数の両方が完全にサポートされるようになりました。 そのため、Arduino 用に構築されたスケッチをコピーする際に、Windows IoT バージョンのスケッチで、これらの Serial への参照を置き換える必要はありません。
さらに、Serial.print()
と Serial.println()
の機能が拡張され、ハードウェアのシリアル ピンへの書き込みに加えて、デバッガが接続されている場合には、デバッガ ウィンドウに出力されるようになりました。
スケッチを実行する際、ほとんどのユーザーがその出力の読み取りを行うと考えているため、デバッグ出力は既定で設定されています。 しかし、この機能は無効にすることもできます。例えば、パフォーマンスを向上させるためには、Serial.enablePrintDebugOutput(false);
を呼び出して、スケッチ内でこれを無効にします。 再び有効にするには、Serial.enablePrintDebugOutput(true);
を呼び出します。 ハードウェアのシリアル ピンへの書き込みは、これらの呼び出しの影響を受けません。
なお、デバッガ ウィンドウへの出力を取得するために、FTDI などの周辺機器をシリアル ピンに取り付ける必要はありません。 ただし、アプリケーションがデバッグされている間は、デバッガ ウィンドウが開いていることを確認する必要があります。
Windows IoT Core Project Templates の拡張機能ページのプロジェクトテンプレートが更新され、ハードウェア Serial
をすぐに使用できるようになりました。 ただし、Arduino Wiring アプリケーションを古いバージョンのプロジェクト テンプレートですでに作成している場合は、1) プロジェクトを最新の Lightning SDK v1.1.0 以降にアップグレードし、2) Serial
を使用できるようにするために必要なハードウェア Serial デバイス機能を AppxManifest に追加する必要があります。
ハードウェア Serial デバイス機能の要件
Windows 10 IoT Core のハードウェア Serial 機能を使用するには、AppX マニフェストにデバイス機能の宣言を追加する必要があります。
ソリューション エクスプローラーでファイル名を入力して、プロジェクト内の Package.appxmanifest
というファイルを検索します。 次に、ファイルを右クリックして [プログラムから開く] を選択します。 [XML (Text) Editor] を選択し、[OK] をクリックします。
appx マニフェスト ファイル エディターで、以下の XML スニペットのように serialcommunication
DeviceCapability をプロジェクトに追加します。
<Capabilities>
<Capability Name="internetClient" />
<!-- General Arduino Wiring required capabilities -->
<iot:Capability Name="lowLevelDevices" />
<DeviceCapability Name="109b86ad-f53d-4b76-aa5f-821e2ddf2141"/>
<!-- The serialcommunication capability is required to access Hardware Serial. -->
<DeviceCapability Name="serialcommunication">
<Device Id="any">
<Function Type="name:serialPort"/>
</Device>
</DeviceCapability>
</Capabilities>
プロジェクトを最新の Lightning SDK にアップグレードする
Arduino Wiring プロジェクトは、必要な Arduino Wiring の機能や宣言、Lightning ドライバーとのインターフェースを実装するために、Lightning SDK Nuget パッケージに依存しています。 最新の Lightning SDK には、最新の機能強化とバグ修正が含まれています。 最新の Lightning SDK にアップグレードするには、以下の手順を実行します。
- ソリューション エクスプローラーで、プロジェクトを右クリックし、[NuGet パッケージの管理] をクリックします。
- NuGet パッケージ マネージャーの [インストール済み] タブに移動して、Microsoft.IoT.Lightning パッケージがインストールされていることを確認します。
- 利用可能なバージョンは、[バージョン] コンボボックス内に表示されます。
- 最新バージョンを選択し、[更新] をクリックしてパッケージを更新します。
- なお、プレリリース版にアップグレードする場合は、[リリース前のパッケージを含める] チェックボックスにもチェックを入れてください。