ArduinoとBluetoothでレゴ パワーフンクションを完全制御
必要な部品と材料
| Arduino UNO | ×1 |
| Texas Instruments L293D デュアルHブリッジドライバー | ×1 |
| ブレッドボード | ×1 |
| 9V バレルジャックコネクター | ×1 |
| レゴ パワーフンクション延長ケーブル(品番8886) | ×3 |
| HC-05 Bluetoothモジュール | ×1 |
プロジェクト概要
レゴ パワーフンクション(モーター、サーボ)搭載モデルをお持ちですか?このチュートリアルでは、最小限の電子部品でArduinoからレゴモデルを制御する方法を、初心者にもわかりやすく解説します。MIT App Inventorで自作Androidリモコンアプリも作成。あなたの裏庭にレゴ火星探査車が誕生します!
筆者の最初のArduinoプロジェクトです。息子のレゴテクニックカー(9398 4×4クローラー、サーボ1個でステアリング、Lモーター2個で走行)を使用(モーターケーブルは切断せずに延長ケーブルで接続)。完成プロトタイプのテスト動画を参照。
パワーフンクション配線の理解
まずレゴ パワーフンクション延長ケーブル(品番8886)を購入し、切断します(「ブレイクアウト」ケーブルを作るため)。片側はレゴコネクター、もう片側はピンヘッダーにします。

- GND: バッテリーボックスのマイナス端子(アノード)
- C1, C2: 極性切替でモーター/サーボの正逆制御
詳細な解説動画: TechnicRobotのYouTube動画参照。(自己責任で実施。破損等の責任は負いません。)
- サーボ用コネクター(ライトグレー): 4線すべてにピンをはんだ付け
- 電源用コネクター(ダークグレー、オス): +9VとGNDのみ使用(バッテリーボックス接続用)
- モーター用コネクター(ライトグレー): C1, C2のみ使用

L293Dチップでレゴモーターを制御
DCモーターは可変速度制御、サーボは位置制御が必要。両方ともPWM(パルス幅変調)で実現。ArduinoではanalogWrite(pin, dutyCycle)(dutyCycle: 0〜255)で簡単。PWMピンは「~」印あり。
Arduino出力は5V/最大30mAだが、レゴモーターは9V/100mA以上必要。間に「スイッチングデバイス」が必要。正逆制御も必要。これらはHブリッジで解決。L293Dは1チップに2つのHブリッジを内蔵。片側にモーター2個(並列)、もう片側にサーボ1個を接続可能(モーターを独立制御するならL293Dをもう1個追加)。
重要: L293D内部でレゴ9V系とArduino 5V系は完全分離。**決して接続しないこと**(破損の原因)。ただし**すべてのGNDは共通接続**すること(L293DのGNDピンも含む)。

Arduinoピン割り当て:
- モーター速度: ピン9(PWM)、方向: ピン2, 5
- サーボ位置: ピン3(PWM)、方向: ピン6, 8
定数・変数定義
// モーター制御ピン
const int controlPin1A = 2;
const int controlPin2A = 5;
const int ENablePin = 9;
// サーボ制御ピン
const int controlPin3A = 6;
const int controlPin4A = 8;
const int servoENablePin = 3;
// モーター制御変数
int motorSpeed = 0; // 0..255
int motorDirection = 1; // 1=前進, 0=後進
// サーボ制御変数
int steering = 0; // 0..255
int steeringDirection = 0; // 0=左, 1=右
setup()
void setup() {
pinMode(controlPin1A, OUTPUT);
pinMode(controlPin2A, OUTPUT);
pinMode(ENablePin, OUTPUT);
pinMode(controlPin3A, OUTPUT);
pinMode(controlPin4A, OUTPUT);
pinMode(servoENablePin, OUTPUT);
digitalWrite(ENablePin, LOW);
digitalWrite(servoENablePin, LOW);
}
L293Dの方向制御ロジック
| EN1,2 | 1A | 2A | 動作 |
|---|---|---|---|
| High | High | Low | モーター正転(前進) |
| High | Low | High | モーター逆転(後進) |
| EN3,4 | 3A | 4A | 動作 |
|---|---|---|---|
| High | High | Low | サーボ左 |
| High | Low | High | サーボ右 |
モーター/サーボ制御サブルーチン
void SetMotorControl() {
if (motorDirection == 1) { // 前進
digitalWrite(controlPin1A, HIGH);
digitalWrite(controlPin2A, LOW);
} else { // 後進
digitalWrite(controlPin1A, LOW);
digitalWrite(controlPin2A, HIGH);
}
analogWrite(ENablePin, motorSpeed);
if (steeringDirection == 0) { // 左
digitalWrite(controlPin3A, HIGH);
digitalWrite(controlPin4A, LOW);
} else { // 右
digitalWrite(controlPin3A, LOW);
digitalWrite(controlPin4A, HIGH);
}
analogWrite(servoENablePin, steering);
}
ジョイスティック付きシンプルRC Androidアプリ(MIT App Inventor 2)
完成アプリを試すだけなら: Google Play「Arduino RC car bluetooth」
MIT App Inventor 2はWebベースのビジュアルプログラミング環境。GoogleのMark FriedmanとMITのHal Abelson教授が開発。
- Androidに「MIT AI2 Companion」アプリをインストール
- PCでブラウザ(Firefox/Chrome推奨)でアプリプロジェクトを開く(Gmailでログイン必要)
- Companionアプリでリアルタイムプレビュー可能
デザイナー画面: 下部にオレンジ色のパッドと青いジョイスティックボール。
ブロック画面: ジョイスティックドラッグを追跡するwhenブロックが核心。


指位置をcurrentX, currentYで取得し、steering, speed(-100〜0〜+100)に変換。パッド外なら±100にクリップ、内部なら計算。
コマンド文字列形式: RC,steering,speed\n\0(改行でコマンド終了を通知)。BluetoothでArduinoへ送信。画面にも表示。
BluetoothコマンドをArduinoで受信
HC-05 Bluetoothモジュールを接続。ピン配置確認:

- VCC: 5V接続OK(6V耐圧)
- GND: 共通GND
- TXD → Arduino RX (ピン0) ※クロス接続
- RXD ← Arduino TX (ピン1) ※**要レベル変換**
注意: HC-05は3.3Vロジック。Arduino TX (5V) を直接RXDに繋ぐと破損。**3つの1kΩ抵抗で分圧回路**(2/3 = 3.3V)を作って接続。逆にHC-05 TXD (3.3V) → Arduino RXD は直結OK(Arduinoは3.3VをHIGHと認識)。
ピン0,1はUSBと共有のため、スケッチ書き込み時はRXD/TXDを外すこと。
ペアリング: AndroidでBluetoothオン → アプリ起動 → 「Bluetooth connect」 → HC-05選択 → ペアリングコード「1234」 → 「connected」表示で完了。
受信コード
#define INPUT_SIZE 30
void loop() {
char input[INPUT_SIZE + 1];
byte size = Serial.readBytesUntil('\n', input, INPUT_SIZE);
input[size] = 0; // ヌル終端
// "RC,steering,speed\n\0" をパース
char* command = strtok(input, ","); // "RC"
char* RCsteering = strtok(NULL, ","); // -100..100
char* RCspeed = strtok(NULL, ","); // -100..100
int iRCsteering = atoi(RCsteering);
int iRCspeed = atoi(RCspeed);
// 制御変数に反映(×2.55で0..255スケーリング)
steeringDirection = (iRCsteering > 0) ? 1 : 0;
steering = int(2.55 * abs(iRCsteering));
motorDirection = (iRCspeed > 0) ? 1 : 0;
motorSpeed = int(2.55 * abs(iRCspeed));
SetMotorControl();
}
今後の展開
- 超音波センサー追加で障害物回避ロボット化
- Bluetooth圏外検出で自動停止機能
- ブレッドボードからAdafruit Motor Shield等へ移行(端子台接続で信頼性向上、デジタルピン節約)
- センサーシールド活用
あなたのエキサイティングなプロジェクトを教えてください!
完全スケッチ
/* Lego Powerfunctions car model controlled over bluetooth
Arduino Uno controls motors and servo
Remote controlled with android app developed with MIT App Inventor 2
Circuit:
* Serial communication (uses Uno pin 0,1) Bluetooth-module attached (detach when uploading over USB)
* L293D with motor (uses Uno digital pins 2,5,9)
* L293D with servo (uses Uno digital pins 6,8,3)
*/
#include
#include
#define INPUT_SIZE 30
const int controlPin1A = 2;
const int controlPin2A = 5;
const int ENablePin = 9;
const int controlPin3A = 6;
const int controlPin4A = 8;
const int servoENablePin = 3;
int motorSpeed = 0;
int motorDirection = 1;
int steering = 0;
int steeringDirection = 0;
void setup() {
Serial.begin(9600);
Serial.setTimeout(1000);
pinMode(controlPin1A, OUTPUT);
pinMode(controlPin2A, OUTPUT);
pinMode(ENablePin, OUTPUT);
pinMode(controlPin3A, OUTPUT);
pinMode(controlPin4A, OUTPUT);
pinMode(servoENablePin, OUTPUT);
digitalWrite(ENablePin, LOW);
digitalWrite(servoENablePin, LOW);
}
void loop() {
char input[INPUT_SIZE + 1];
byte size = Serial.readBytesUntil('\n', input, INPUT_SIZE);
input[size] = 0;
char* command = strtok(input, ",");
char* RCsteering = strtok(NULL, ",");
char* RCspeed = strtok(NULL, ",");
int iRCsteering = atoi(RCsteering);
int iRCspeed = atoi(RCspeed);
if (iRCsteering > 0) steeringDirection = 1; else steeringDirection = 0;
steering = int(2.55 * abs(iRCsteering));
if (iRCspeed > 0) motorDirection = 1; else motorDirection = 0;
motorSpeed = int(2.55 * abs(iRCspeed));
SetMotorControl();
}
void SetMotorControl() {
if (motorDirection == 1) {
digitalWrite(controlPin1A, HIGH);
digitalWrite(controlPin2A, LOW);
} else {
digitalWrite(controlPin1A, LOW);
digitalWrite(controlPin2A, HIGH);
}
analogWrite(ENablePin, motorSpeed);
if (steeringDirection == 0) {
digitalWrite(controlPin3A, HIGH);
digitalWrite(controlPin4A, LOW);
} else {
digitalWrite(controlPin3A, LOW);
digitalWrite(controlPin4A, HIGH);
}
analogWrite(servoENablePin, steering);
}
GitHubリポジトリ
Arduinoソース、Fritzing回路図、MIT App Inventor用アプリソース: https://github.com/Notthemarsian/Lego-car-Arduino
回路図
GitHubリポジトリ内のFritzingファイル(Lego rc car v2.fzz)を参照。
製造プロセス