多機能Arduino RC送信機を自作:ステップバイステップDIYガイド
概要
このチュートリアルでは、Arduinoベースの多機能RC送信機を自作する方法を解説します。自作プロジェクトでワイヤレス制御が必要になることが多いため、ラジコンカー、ドローン、ロボットなどほぼあらゆる用途に使える汎用コントローラーを製作しました。
受信側でわずかな調整を加えるだけで、あらゆるArduinoプロジェクトをワイヤレス制御可能です。また、市販のRC送信機と同様に、RC玩具、カー、ドローンの制御にも使用できます。その場合は、市販RCデバイス用の適切な信号を生成するシンプルなArduino受信機が必要です。
このガイドでは、Arduinoロボットカーの制御、前回の動画で作成したArduinoアリロボットの制御、ESCとサーボモーターを使ったブラシレスDCモーターの制御という3つの実例を通じて仕組みを説明します。

無線通信にはNRF24L01トランシーバーモジュールを使用し、アンテナ増幅版を使えば開放地で最大700メートルの安定した通信距離を実現します。コントローラーは14チャンネルを備え、うち6つがアナログ入力、8つがデジタル入力です。

操作部は2つのジョイスティック、2つのポテンショメーター、2つのトグルスイッチ、6つのボタンで構成され、さらに加速度センサーとジャイロスコープからなるIMU(慣性計測ユニット)を内蔵。傾きや動きで直感的な操作も可能です。
回路図
このRCコントローラーの頭脳はArduino Pro Miniです。2セルLiPoバッテリー(約7.4V)で駆動し、Pro MiniのRAWピンに直接接続できます。オンボードのレギュレーターが5Vに降圧します。なお、Pro Miniには5V版と3.3V版があるため注意してください。

NRF24L01モジュールは厳密に3.3V駆動が必要で、専用の電源から供給することが推奨されます。そのため、7.4Vを3.3Vに変換する3.3Vレギュレーターをバッテリーに接続します。また、モジュールのすぐ近くにデカップリングコンデンサーを配置し、電圧を安定させることで通信品質を向上させます。NRF24L01はSPIプロトコルでArduinoと通信し、MPU6050加速度・ジャイロモジュールはI2Cプロトコルを使用します。
必要な部品
- NRF24L01トランシーバーモジュール
- NRF24L01 + PA + LNA(アンテナ増幅版)
- ポテンショメーター
- サーボモーター
- トグルスイッチ
- ジョイスティック(ブレークアウトボード付き - ジョイスティック部分を取り外し必要)
- ジョイスティック(ブレークアウトボードなし)
- Arduino Pro Mini(PCB V2またはV3版用)
- Arduino Pro Mini(筆者使用モデル - PCB V1用)
- HT7333 3.3Vレギュレーター(ローカル電子部品店 - PCB V1 & V2用)
- AMS1117 3.3Vレギュレーター(PCB V3用)
PCB設計
Arduino Pro Miniの全アナログ・デジタルピンを使用するため、ジャンパーワイヤーで配線すると非常に煩雑になります。そこで、EasyEDA無料オンライン設計ツールでカスタムPCBを設計しました。

人間工学を考慮し、両手で持ちやすく、全操作部が指の届く範囲に配置されるよう設計。エッジを丸め、3mm穴を設けて後でマウント可能にしました。Arduino書き込み用ピンヘッダーを上面に配置し、再プログラミング時に容易にアクセスできるようにしています。RX/TXピンはジョイスティックボタン用に使用していますが、スケッチ書き込み時にはこれらを切り離す必要があるため、ジャンパーキャップで簡単に接続/切断できるようピンで中断しています。

重要: 使用するArduino Pro Miniのバージョンに合ったPCBを選択するか、PCB設計を修正してください。上記写真はArduinoとレギュレーターの組み合わせによる3バージョンの比較です。プロジェクトファイル(3バージョン別タブで開きます)から必要なものを選べます。
設計完了後、製造用ガーバーファイルを生成し、今回のスポンサーであるJLCPCBに発注。黒色PCBを選択し、初回注文なら10枚でわずか$2というリーズナブルな価格で入手できます。



PCB組み立て
はんだ付けはArduino Pro Miniのピンヘッダーから開始。ブレッドボードに差して固定すると作業しやすいです。側面ピンの位置はメーカーによって異なる場合があるため注意してください。筆者のモデルでは片側5ピンずつ使用し、1つのGNDピンはPCB裏面の配線スペースとして空けています。


Pro Miniを直接PCBにはんだ付けし、ピンの余分な部分をカット。すぐ隣にMPU6050モジュールを実装します。3.3Vレギュレーターとコンデンサー、NRF24L01モジュール近くのコンデンサーをはんだ付け。NRF24L01は3バージョンいずれも使用可能です。


書き込み用ピン、RX/TXピン、電源ピン、電源スイッチをはんだ付け。ポテンショメーターはピンヘッダーでピンを延長してから実装します。ノブの長さをカットしてキャップが嵌まるようにしていますが、実際の高さが確定するまでポテンショメーターのはんだ付けは後回しにします。

トグルスイッチ2つとジョイスティック2つを挿入・はんだ付け。最後に4つのプッシュボタンを実装しますが、高さが足りないためピンヘッダーで延長しています。

ケース製作
PCBが見えるよう透明アクリル板(4mm厚)でカバーを作成。保護フィルムが付いた状態では青く見えます。PCB形状に合わせて上下2枚のプレートを切り出し、PCBを挟み込む構造です。



金属ノコギリで大まかに切り、ヤスリで微調整。2枚ともPCBにぴったり合うように仕上げます。

部品用の開口部をマークし、3mmドリルで4隅の固定穴(皿取り加工)、6mmドリルでトグルスイッチとポテンショメーター用、25mmフォースナービットでジョイスティック用の穴を開け、ヤスリで整えます。


電源ピンヘッダーは裏面からアクセスできるよう逆向きにはんだ付けしてあります。

保護フィルムを剥がし、上部プレートにポテンショメーターを固定、3mmボルトと11mmスペーサーを取り付け、上部プレートとPCBをボルトで固定。この時点でポテンショメーターをPCBにはんだ付けします。


裏面プレートにバッテリーホルダーを2本ボルトで固定し、4本のマウントボルトで裏面プレートをPCB裏面に固定してケース完成。

バッテリー配線を電源ピンに接続、ポテンショメーターにノブを取り付け、ジョイスティックキャップを装着、NRF24L01にアンテナを取り付ければハードウェアは完成です。

プログラミング
Pro Miniへの書き込みにはUSB-シリアル変換アダプターが必要です。上面の書き込みヘッダーに接続し、Arduino IDEでボード「Arduino Pro or Pro Mini」、プロセッサー、ポート、書き込み装置「USBasp」を選択してアップロードします。


送信機コードの解説
まず、無線通信用のSPIおよびRF24ライブラリ、IMU用のWireライブラリをインクルード。デジタル入力ピン、変数、ラジオオブジェクト、通信アドレスを定義します。
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Wire.h>
// デジタル入力定義
#define jB1 1 // ジョイスティックボタン1
#define jB2 0 // ジョイスティックボタン2
#define t1 7 // トグルスイッチ1
#define t2 4 // トグルスイッチ2
#define b1 8 // ボタン1
#define b2 9 // ボタン2
#define b3 2 // ボタン3
#define b4 3 // ボタン4
const int MPU = 0x68; // MPU6050 I2Cアドレス
// ... 変数宣言 ...
RF24 radio(5, 6); // nRF24L01 (CE, CSN)
const byte address[6] = "00001"; // 通信アドレス
NRF24L01のバッファー制限(32バイト)に収まるよう、14入力値を格納する構造体を定義します。
// 最大32バイト - NRF24L01バッファー制限
struct Data_Package {
byte j1PotX; byte j1PotY; byte j1Button;
byte j2PotX; byte j2PotY; byte j2Button;
byte pot1; byte pot2;
byte tSwitch1; byte tSwitch2;
byte button1; byte button2; byte button3; byte button4;
};
Data_Package data;
setup()ではMPU6050を初期化し、必要に応じてIMU誤差を校正。無線通信を初期化し、全デジタル入力に内部プルアップ抵抗を有効化、全変数に初期値を設定します。
void initialize_MPU6050() {
Wire.begin();
Wire.beginTransmission(MPU);
Wire.write(0x6B); Wire.write(0x00); // リセット
Wire.endTransmission(true);
// 加速度計設定: ±8g
Wire.beginTransmission(MPU);
Wire.write(0x1C); Wire.write(0x10);
Wire.endTransmission(true);
// ジャイロ設定: 1000dps
Wire.beginTransmission(MPU);
Wire.write(0x1B); Wire.write(0x10);
Wire.endTransmission(true);
}
// 無線設定
radio.begin();
radio.openWritingPipe(address);
radio.setAutoAck(false);
radio.setDataRate(RF24_250KBPS);
radio.setPALevel(RF24_PA_LOW);
// プルアップ有効化
pinMode(jB1, INPUT_PULLUP); // ... 全デジタルピン同様 ...
loop()では全アナログ入力を読み取り、0-1023を0-255(1バイト)にマッピングして構造体に格納。デジタル入力も読み取ります(プルアップ使用のため、ボタン押下時はLOW)。
// アナログ入力読み取り・マッピング
data.j1PotX = map(analogRead(A1), 0, 1023, 0, 255);
data.j1PotY = map(analogRead(A0), 0, 1023, 0, 255);
data.j2PotX = map(analogRead(A2), 0, 1023, 0, 255);
data.j2PotY = map(analogRead(A3), 0, 1023, 0, 255);
data.pot1 = map(analogRead(A7), 0, 1023, 0, 255);
data.pot2 = map(analogRead(A6), 0, 1023, 0, 255);
// デジタル入力読み取り
data.j1Button = digitalRead(jB1);
data.j2Button = digitalRead(jB2);
data.tSwitch2 = digitalRead(t2);
data.button1 = digitalRead(b1);
// ... 他ボタン同様 ...
radio.write()で構造体全体を送信。トグルスイッチ1がON(LOW)の場合、ジョイスティック1の代わりにIMUの角度データを使用します。
if (digitalRead(t1) == 0) {
read_IMU(); // IMUデータでジョイスティック1を置き換え
}
// 角度(-90〜+90°)を0-255にマッピング
data.j1PotX = map(angleX, -90, +90, 255, 0);
data.j1PotY = map(angleY, -90, +90, 0, 255);
radio.write(&data, sizeof(Data_Package));
IMU読み取り関数では、加速度計とジャイロのデータを相補フィルターで融合し、ドリフトを補正しながら角度を算出しています。
完全な送信機コード
完全なArduinoコードはこちら(記事末尾に掲載)
受信機コード
シンプルな受信回路(Arduino + NRF24L01)でデータを受信し、シリアルモニターに表示して動作確認できます。送信側と同じ構造体定義、同じ無線設定で、radio.startListening()で受信モードにします。

loop()ではradio.available()で受信チェック、データを構造体に格納。millis()で最終受信から1秒以上経過したら接続断とみなし、デフォルト値にリセットするフェイルセーフ機能を実装しています(ドローンのスロットルが開いたまま飛び去るのを防止)。
// 受信チェック
if (radio.available()) {
radio.read(&data, sizeof(Data_Package));
lastReceiveTime = millis();
}
// 接続断検出・リセット
if (millis() - lastReceiveTime > 1000) {
resetData();
}
応用例: Arduinoロボットカーのワイヤレス制御

受信データを読み取り、ジョイスティック1の値で車両を駆動。前回の動画で作成したロボットカーに適用可能です。
応用例: Arduinoアリロボット/六脚ロボットの制御

同様に受信データに基づき、前進、左右旋回、噛みつき、攻撃などの動作関数を実行。
応用例: ESCとサーボの制御(市販RCデバイスへの応用)

標準的なRC受信機システムとは互換性がないため、Arduino + NRF24L01で自作受信機を作り、そこからサーボ用PWM信号(0-180°)やESC用50Hz PWM(1000-2000μs)を生成します。

// サーボ制御
servo1Value = map(data.j2PotX, 0, 255, 0, 180);
servo2Value = map(data.j2PotY, 0, 255, 0, 180);
servo1.write(servo1Value);
servo2.write(servo2Value);
// ESC制御(ブラシレスモーター)
escValue = map(data.pot1, 0, 255, 1000, 2000);
esc.writeMicroseconds(escValue);
この送信機は汎用性が高く、様々なプロジェクトのワイヤレス制御基盤として活用できます。質問があればコメント欄へどうぞ。Arduinoプロジェクトコレクションもご覧ください。
製造プロセス
- カズー:古代ミルリトンから現代プラスチック玩具へ — 歴史、製造、未来
- 自作LUMAZOID:Arduino音楽ビジュアライザーDIYガイド
- 自宅で作るDIY宿題自動筆記マシン:AxiDraw風ペンプロッターの自作ガイド
- Arduinoとスマホで作るスマート電圧計 – 簡単DIYプロジェクト
- コンパクト気象ステーション:Arduino Nano & ESP8266 + BMP280 + OLED/Nokia LCD
- Arduino、Google Cardboard、Bluetoothで作るDIY VRスケートボード
- DIY ArduinoラジオニクスEMR治療デバイスの構築
- Arduino NanoとSG90サーボで作るDIY 2軸モーションレーシングシミュレータ
- Arduinoで作るポータブルRFIDドアロック - ステップバイステップガイド
- DIY 3軸CNCフライス盤:精密加工機を自作する
- Arduino NanoとGY-906で作る非接触赤外線温度計