Raspberry Pi Pico+ArduinoとTWELITE UARTを使って無線通信する

Raspberry Pi Pico (RP2040) と Arduino フレームワークで TWELITE UART を使った無線通信を行う方法のメモです。
Arduino フレームワークは arduino-pico (いわゆる earlephilhower 版)の 2.7.1 で動作を確認しています。
用意するもの
| 部品名 | 入手先 |
|---|---|
|
TWELITE UART BLUE または RED、アンテナ内蔵または同軸コネクタタイプ |
内蔵: BLUE RED 同軸: BLUE RED |
|
アンテナ 同軸コネクタタイプでは必須 |
平面 ダイポール 薄型 |
|
TWELITE R R2 または R3 |
R2 R3 |
|
MONOSTICK BLUE または RED |
BLUE RED |
| Raspberry Pi Pico | 秋月 |
他にブレッドボード、ピンヘッダ、配線材などが必要です。
ソフトウェア
-
VSCode + PlatformIO
Arduino IDE での開発でも可能ですが、こちらがオススメです。 -
TWELITE STAGE APP
インストール方法 に従って導入してください。 -
CoolTerm
PlatformIO 付属のターミナルでは使いづらいので、こちらを使っています。
準備
MONOSTICK(親機)の準備
- MONOSTICK を PC に接続する
- TWELITE STAGE APP(TWELITE_Stage.exe)を起動し、MONOSTICK を選択します
- インタラクティブモードを選択します。その旨を確認する画面になりますので、ENTER を押して続行します
-
CONFIG/TWE UART APPから始まる設定画面が表示され、各項目が以下のようになっていることを確認する
a: set Application ID (0x67720103)
i: set Device ID (120=0x78)
c: set Channels (18)
x: set RF Conf (3)
r: set Role (0x0)
l: set Layer (0x1)
b: set UART baud (38400)
B: set UART option (8N1)
m: set UART mode (E)
k: set Tx Trigger (sep=0x0d0a, min_bytes=0 dly=0[ms])
h: set header format [;U;%t;%i;0x%A;%q;%s;<*;%X;\n]
C: set crypt mode (0)
o: set option bits (0x00000100)
TWE UART APP と表示されていない場合
- ESC を押してメニューに戻る
- アプリ書換を選択する
- BIN から選択を選択する
- App_Uart_*** もしくは App_Uart_TWELITEUART_*** のどちらかのバイナリを選択する
- 書き込みが始まり、完了したら Enter を押してインタラクティブモードに入る
設定項目が異なる場合
- 設定項目と同じキーを押して個別に変更するか、もしくはリセットのためにRキー(Shift+R)を押す
- すると変更される項目に
*が表示されるので、Sキー(Shift+S)を押す - 書き込みが終わると自動でメニューに戻されます
- TWELITE STAGE APPを閉じる
TWELITE UART(子機)の準備
親機と異なり、設定の変更が必要です。
- TWELITE UART と TWELITE R を写真のように接続する(方向注意)
- TWELITE STAGE APP(TWELITE_Stage.exe)を起動し、TWELITE R を選択する
- インタラクティブモードを選択し、その旨を確認する画面になりますので、ENTERを押して続行します
-
CONFIG/TWE UART APPから始まる設定画面が表示され、以下の項目を変更します
(該当箇所のみ記載)
h: set header format [;%A;%q;*;\n]
o: set option bits (0x00010100)
変更したオプションの意味
-
ヘッダフォーマットは TWELITE UART から返される応答の出力書式になります。
%Aがメッセージの送り主のアドレス(シリアルナンバー)、%qが電波強度(自ら発信した場合は000)、*がメッセージ本文です。- その他の書式は公式のドキュメントを参照してください。
-
オプションビットは
0x00010000と0x00000100の組み合わせです。-
0x00010000は BPS ピンの設定と関係なく、設定画面に表示されている UART baud(ボーレート) を使うようになります。TWELITE UART には BPS ピンがないため、このビットを設定しないとボーレートは 115200 で固定されます。 -
0x00000100は Tx Trigger の sep で設定された文字列をUARTで受け取ったときに送信を開始するよう設定されます。デフォルトでは sep には0x0d0a(\r\n) が設定されています。 - その他のオプションビットの意味は公式のドキュメントを参照してください。
-
TWE UART APP と表示されていない場合
MONOSTICK(親機)と同様に ESC を押してメニューに戻り、アプリの書き換えを行ってください。バイナリは
App_Uart_*** もしくは App_Uart_TWELITEUART_*** のどちらかになります。
- 変更項目に
*がついていることを確認したら、S(Shift+S)を押して設定を保存する
- 保存後は自動でメニューに戻されます
ボーレートを変更したあとのインタラクティブモードの入り方
上記の設定を行うと TWELITE UART のボーレートが 115200 から 38400 に変更されます。TWELITE STAGE APP では 115200 がデフォルト設定で接続を行います。必要であれば以下の方法で設定を変えます。
ボーレートの変更方法
- メニューの TWELITE STAGE の設定を選択する
- 設定メニューの 0 を押して共通設定に入る
- B(Shift+B)を押す
- 38400 を押して Enter を押す
- ボーレートの項目に正しいレートと
*が表示されていることを確認してS(Shift+S)を押す
結線
TWELITE R を PC から外し、TWELITE UART も外します。Raspberry Pi Pico と TWELITE UART を以下のように接続します。

Raspberry Pi Pico と TWELITE UART を接続した様子
| Raspberry Pi Pico | TWELITE UART |
|---|---|
| GND | GND |
| GP12(UART0 TX) | RXD |
| GP13(UART0 RX) | TXD |
| 3V3(OUT) | VCC |
プログラム
公式ドキュメントにて掲載されているサンプルスケッチを Raspberry Pi Pico 用に書き換えたものになります。主な動作に変更はないため、解説は公式ドキュメントを参照してください。
#include <Arduino.h>
#include <SoftwareSerial.h>
SoftwareSerial MWSerial(13, 12); // RX, TX
#define BLOCK_MAX 10
// データ列を区切り文字で分割してString型の配列に入れる。
int split(char* source, char delimiter, String* result) {
char* p = source;
char tmp[81];
memset(tmp, 0, sizeof(tmp));
int n = 0;
int block = 0;
// ヌル文字が来るか分けたブロック数がBLOCK_MAXになったらやめる。
while (*p != 0 && block < BLOCK_MAX) {
// 区切り文字が来たら、String型に変換する。
if (*p == delimiter) {
// 分割したデータが0バイトの時は何もしない。
if (n > 0) {
// 念のためヌル文字を末尾に代入。
tmp[n] = 0;
result[block] = String(tmp);
block++;
n = 0;
memset(tmp, 0, sizeof(tmp));
}
} else {
tmp[n] = *p;
n++;
}
p++;
}
return block;
}
void setup() {
Serial.begin(38400);
MWSerial.begin(38400);
}
void loop() {
while (MWSerial.available()) {
static char buf[256] = { 0 };
static char* p = buf;
char before = *p;
*p = MWSerial.read();
if (before == '\r' && *p == '\n') {
*p = 0; // 末尾をNull文字にする
String str[BLOCK_MAX]; // 区切り文字で分割した文字列を入れる
int block = split(buf, ';', str); // データの分割
if (block == 3) {
Serial.print("Message: ");
Serial.println(buf);
Serial.print("Serial No.: ");
Serial.println(str[0]);
Serial.print("LQI: ");
Serial.println(str[1]);
Serial.print("Data: ");
Serial.println(str[2]);
Serial.println();
}
p = buf;
memset(buf, 0, sizeof(buf));
} else {
if (*p >= 0x20) {
p++;
}
}
}
while (Serial.available()) { MWSerial.write(Serial.read()); }
}
動作確認
以下は CoolTerm を使った方法になります。Options から設定が以下のようになっているか確認してください。
- Serial Port Options ページ
- Data Bits: 8
- Parity: None
- Stop Bits: 1
- Terminal Options ページ
- Terminal Mode: Line Mode
- Enter Key Emulation: CR+LF
設定が正しければ CoolTerm を2つ開き、親機の MONOSTICK と子機の Raspberry Pi Pico に接続します。
| 接続先 | ボーレート |
|---|---|
|
MONOSTICK 親機 |
115200 |
|
Raspberry Pi Pico 子機 |
38400 |

左: MONOSTICK、右: Raspberry Pi Pico
親機から子機へ通信
親機の MONOSTICK 側に適当な文字列を送信します。hello raspi と入力します。

親機から hello raspi を送信
すると親機のターミナルには送信ログが表示されます。
;U;05666;219;0x8201BFFB;000;001;1,1,hel...;74;
送信側では受信強度は 000 となり、メッセージ本文は省略されます。一方、受信側では以下のような表示になります。
Message: ;8201BFFB;168;hello raspi;
Serial No.: 8201BFFB
LQI: 168
Data: hello raspi
メッセージ本文が省略されずに表示されます。LQIは受信強度です。
子機から親機へ送信
逆に子機から送信を行います。hi monostick と入力します。

子機から hi monostick を送信
すると子機のターミナルには送信ログが表示されます。
Message: ;810A5A33;000;20,1,hi ...;
Serial No.: 810A5A33
LQI: 000
Data: 20,1,hi ...
親機には子機から受信したメッセージ本番が省略されずに表示されます。
;U;05715;120;0x810A5A33;135;020;hi monostick;7F;
うまくいかない場合
ターミナルが文字化けする
ボーレートが合致していないと文字化けやデータが正しく表示されません。この記事で設定したボーレートは複数ありますので、今一度まとめておきます。
| 接続先 | ボーレート |
|---|---|
| MONOSTICK | 115200 |
| Raspberry Pi Pico の Serial | 38400 |
| Raspberry Pi Pico の SoftwareSerial | 38400 |
| TWELITE UART | 38400 |
ターミナルで文字を送っても何も起きない
改行文字が \n のままになっているかもしれません。MONOSTICK、TWELITE UART ともに \r\n を送らないと送信をしない設定になっているため、ターミナル側で改行文字を正しく設定してください。
通信の最初にNULLが入る

TWELITE UART から通信をすると、最初の通信にこのように NULL 文字(00)が入ってしまうことがあります。これは Raspberry Pi Pico のハードウェアリセットがかかっても TWELITE UART はリセットされず、バッファの一部が漏れてしまうためです。スケッチの書き換え直後に頻発します。
TWELITE UART には RST ピンがあります。アクティブローですので GND にショートするとリセットされます。配線を以下のように1本追加します。
| Raspberry Pi Pico | TWELITE UART |
|---|---|
| GND | GND |
| GP12(UART0 TX) | RXD |
| GP13(UART0 RX) | TXD |
| GP16 | RST |
| 3V3(OUT) | VCC |
スケッチの setup 関数に以下のようにリセット処理を追加します。MWSerial.begin よりも後にリセット処理をかけることがポイントです。delay はそれぞれ100ミリ秒、500ミリ秒と TWELITE UART の初期化に十分な時間を見越して指定しています。
void setup() {
Serial.begin(38400);
MWSerial.begin(38400);
pinMode(16, OUTPUT);
digitalWrite(16, HIGH);
digitalWrite(16, LOW);
delay(100);
digitalWrite(16, HIGH);
delay(500);
}
参考文献
-
TWELITE STAGE APP
STAGE アプリの公式ドキュメントです。アプリの書き換えや設定変更以外にも様々な機能があります。 -
シリアル通信アプリ ユーザーズガイド
こちらは TWELITE UART の公式ドキュメントです。
Discussion
記事を参考にさせていただいています。
恐縮ですが質問させていただきます。
記事内のプログラムはPicoに保存して、その後、CoolTermでPicoとStickに接続すればいいのでしょうか?
プログラムをどこに保存?または実行すればいいのかわかりませんでした。
また、プログラムはMicroPythonに書き換えれば動作しますか?
プログラムをどこで使えばいいか教えていただけると幸いです。
よろしくお願いします。
記事内のプログラムは Raspberry Pi Pico に書き込んでください。記事中ではVSCodeとPlatformIOを使っていますが、この場合は「PlatformIO: Upload」というコマンドが書き込みになります。
本文中では触れていませんが、TWELITE R または MONOSTICK をUSBでPCと接続すると、それらのデバイスに誤ってプログラムを書き込んでしまうことがあります。プログラムを書き込む際は Raspberry Pi Pico のみPCに接続すると確実です。プログラムを書き込んだのち、CoolTerm で Raspberry Pi Pico と MONOSTICK に接続してください。
プログラムは MicroPython に書き換えても動作すると考えています。ただし MicroPython では SoftwareSerial に対応してないようなので、HardwareSerial(通常のシリアル通信)として扱う必要があります。
具体的には以下のような書き始めになると考えています(注意: 実機で検証していません)。
Raspberry Pi Pico のシリアル通信についての記事も参考までに紹介しておきます。