XMP-1 の構築:低コスト XMOS-Raspberry Pi モバイルプラットフォーム
はじめに
Farnell(または Newark)でわずか 12 ポンド(VAT 込み)で入手できる XMOS startKIT は、クレジットカードサイズのコンパクトなプラットフォームで、Raspberry Pi とシームレスに連携します。ドライバー、ワイヤーカッター、ペンチのみの最小限のハンダ付けで、開発者は XMOS のマルチコア、低ジッター並列処理を活用した機能的なロボティクスプロトタイプを組み立てられます。
この記事では、Raspberry Pi と XMOS startKIT 間の高速双方向通信をシリアルペリフェラルインターフェース(SPI)で実現するシンプルなモバイルプラットフォーム XMP-1(XMOS Mobile Platform)の構築を解説します。また、XMOS ボードから直接生成される PWM でホビーサーボを制御する方法と、リアルタイムでロボットを操作する Web ベースのユーザーインターフェースの公開方法も紹介します。
オリジナル投稿にはビデオデモが含まれます。最初の動画は XMP-1 が経路を学習する様子、2 つ目は連続回転サーボを使って経路を再生しようとする様子を捉えています。これらは現在のハードウェアとファームウェアの可能性と限界の両方を示しています。
もう少し詳細
この投稿は XMOS startKIT 実験シリーズの第 2 回です。第 1 回では XMOS 用語、アーキテクチャ、サンプルプログラム付きのクイックスタートガイドを提供しました。XMOS が初めての方は、第 1 回を読んでここで議論される概念を理解することをお勧めします。第 3 回(タイトル「XMOS startKIT: XMOS and Raspberry Pi Oscilloscope XAE 1000」)では SPI フレームワークを再訪し、ADC 使用とリアルタイムブラウザグラフィックスを導入します。
XMP-1 の構築と運用にのみ関心がある方は、拡張議論をスキップして記事末尾のコードセクションに進んでください。ファームウェアは第 1 回で説明した通りにコンパイル・フラッシュ可能で、Raspberry Pi コードは Node.js で動作します。
ソリューション概要 – ハードウェアとソフトウェア
図 1(非表示)は、完成した XMP-1 を示します。5 V レギュレーターで給電され、2 つの連続回転ホビーサーボで駆動されます。Raspberry Pi はすべてのネットワークを処理し、index.html を提供する軽量 Web サーバーを実行、ユーザーコマンドをモーター速度/方向メッセージに変換します。
通信フローは図 2(非表示)に示す通り。Pi はサーボ用 PWM 信号を生成するために SPI パケットを XMOS startKIT に送信。startKIT は SPI スレーブとして動作し、パケットをデコードして適切な PWM パルスでサーボを駆動します。
シリアルペリフェラルインターフェース(SPI)
SPI は 4 線(SS、SCLK、MOSI、MISO)に依存。このセットアップでは Raspberry Pi がマスターで、クロックを提供し MOSI でデータを送信。XMOS ボードは MOSI でデータを受信し、MISO でステータスまたは確認応答を返します。SS 線はアクティブロー、Pi の CE1 ピンで startKIT を選択します。
オシロスコープトレース(Tektronix MSO2024B で取得)が SPI 転送の整合性を確認。3 バイトのデータ(0x02、0x00、0x10)が Pi から startKIT に送信され、オプションでゼロ長レスポンスあり。
ホビーサーボモーターの制御
ホビーサーボは 1-2 msec の PWM パルス幅を 0-180° の機械的回転に変換し、1.5 msec パルスでシャフトを中央に保持。連続回転サーボはポテンショメーターとエンドストップを除いたバリエーションで、パルス幅を速度コマンドとして解釈:1.5 ms で中立、1 ms で全速後退、2 ms で全速前進。
XMP-1 の各ホイールは連続回転サーボで駆動。このセットアップは配線を簡素化(外部 H ブリッジ不要)しますが、DC モーターと比べて精密な速度制御は制限されます。
開発開始 – ボードの接続
ファームウェア開発用に、Raspberry Pi と startKIT を 26 ピンリボンケーブル(IDC コネクター付き)で接続。予備の IDC コネクターをデバッグインターフェースとして、マルチメーターやオシロスコープで信号をプローブするのに使用できます。
XMOS startKIT 上での SPI 実装(spi_process)
xTIMEcomposer IDE を使用し、内蔵 SPI スレーブライブラリをインポート、ソースファイルを spi-test/src ディレクトリに配置。以下の初期化ルーチンでクロックソース、MOSI/MISO ポート、SPI スレーブインターフェースを設定:
void spi_slave_init(spi_slave_interface &spi_if) {
int clk_start;
set_clock_on(spi_if.blk);
configure_clock_src(spi_if.blk, spi_if.sclk);
configure_in_port(spi_if.mosi, spi_if.blk);
configure_out_port(spi_if.miso, spi_if.blk, 0);
start_clock(spi_if.blk);
return;
}
spi_slave_interface 構造体で SPI ピンを XMOS ポートにマッピング:
typedef struct spi_slave_interface {
clock blk;
in port ss;
in buffered port:8 mosi;
out buffered port:8 miso;
in port sclk;
} spi_slave_interface;
着信 SPI データを以下のルーチンでバッファーに読み込み。シンプルなタグ・長さ・値(TLV)プロトコルで可変長メッセージを実現:
void spi_slave_in_buffer(spi_slave_interface &spi_if, unsigned char buffer[], int num_bytes) {
unsigned int data;
unsigned int vlen=0;
clearbuf(spi_if.miso);
clearbuf(spi_if.mosi);
for (int i = 0; i < num_bytes; i++) {
spi_if.mosi :> data;
data=data<<24;
buffer[i]=bitrev(data);
if (i==2) {
vlen=((unsigned int)buffer[1])<<8 | (unsigned int)buffer[2];
if (vlen==0) break;
}
if (i >= vlen+2) {
break;
}
}
}
パケットの最初のバイトはタグ(0-255)。次の 2 バイトでペイロード長(最大 4096 バイト)をエンコード。奇数タグは Raspberry Pi がレスポンスを期待、偶数タグはレスポンス不要を示します。
プロセス間通信
XMOS コアはシンプルなチャネルではなくトランザクションベースのインターフェースで通信。このアプローチにより、単一インターフェース呼び出しで複数のデータ型と戻り値を扱え、SPI 処理コア、データ処理コア、PWM 生成コアの調整に最適です。
インターフェース定義例:
interface program_display {
void backlight(int state, int color);
void plot(int x, int y, int color);
}
SPI コンテンツを処理する IPC アーキテクチャの設計
spi_process コアは着信 SPI データを 4099 バイトバッファーに取り込み、ムーバブル配列トランザクションで data_handler コアにポインターを転送。処理後、data_handler はバッファーにレスポンスを設定し、spi_process に次の SPI 交換で送信可能であることを通知。
interface to_rpi { void code(unsigned char c); };
interface from_rpi { unsigned char* movable array_data(unsigned char* movable bufp); };
コアロジック抜粋:
void spi_process(interface to_rpi server s, interface from_rpi client c) {
unsigned char storage[4099];
unsigned char* movable buf=storage;
buf=c.array_data(move(buf));
select {
case s.code(unsigned char c):
if (c==SEND) {
spi_slave_out_buffer(spi_sif, buf, 4099);
}
break;
}
}
void data_handler(interface to_rpi client c, interface from_rpi server s) {
select {
case s.array_data(unsigned char* movable vp) -> unsigned char* movable vq:
vq[0]=0x22; // tag
vq[1]=0x00; // length
vq[2]=0x00;
vq=move(vp);
tosend=1;
break;
}
if (tosend) {
c.code(SEND);
}
}
このアーキテクチャにより、Raspberry Pi と XMOS startKIT 間の汎用的で双方向の通信チャネルが実現され、幅広いロボティクスや IoT プロジェクトに適応可能です。
startKIT 上での PWM 実装(servo_handler)
サーボ制御ルーチンは専用 XMOS コアで実行され、最大 8 つのサーボを管理。各サーボの PWM 信号は、20 ms ごとに適切なデューティサイクルで出力ピンをトグルし、マイクロ秒分解能で微細な速度調整を実現。初期値は中央(連続回転サーボの場合は停止)に設定され、IPC フレームワーク経由で受信した最新コマンドに基づいて各サイクルで信号を更新します。
現在の XMP-1 では 2 つの連続回転サーボのみを使用しますが、ファームウェアは追加モーターや H ブリッジインターフェース経由の DC モーター制御への拡張をサポートしています。
完全なソースコードとコンパイル手順は記事末尾を参照してください。
製造プロセス
- シームレスMQTT統合:NodeMCU DHT22センサーとRaspberry Pi 3 B+ブローカー
- Raspberry PiとPythonでリモート温度センサーを構築 – ステップバイステップガイド
- EzTempでRaspberry Pi上の温度・湿度をシームレスに監視
- Raspberry PiとDS18B20でマルチセンサー温度・光監視システムを構築
- Raspberry Piでセンサーとアクチュエータを制御:加速度計、サーボ、データストリーミング
- Raspberry Piと湿度センサーで作る自動エアロポニックスシステム
- Raspberry Pi 3 B+ – アップデートされた機能、仕様、購入ガイド
- Bridge Shield でスマートロボットを構築:Raspberry Pi と Arduino の統合
- ValentFX が BeagleBone と Raspberry Pi 向けオープンソース FPGA アドオンを発表
- MonkMakes RRB2 キットで自作 Raspberry Pi ロボット – 詳細ガイド
- DIY Wall-E 風 Raspberry Pi CD ボックスロボット