ジェスチャー制御ロボット製作:モーションセンシングボットを自作
部品と材料
| Arduino UNO | ×1 |
| Arduino Nano R3 | ×1 |
| RF-433 送信機/受信機 | ×1 |
| HT12 エンコーダー/デコーダー | ×1 |
| Adafruit アナログ加速度センサー ADXL335 | ×1 |
| Arduino Uno用モーターシールド | ×1 |
| DCモーター(汎用) | ×1 |
必要な工具
- はんだごて(汎用)
このプロジェクトについて
ジェスチャー制御ロボットは、ホビイストや学生がマイコン知識を実践的なプロジェクトで理解・実装するために最もよく作られるプロジェクトの一つです。手のひらの向きでロボットカーの動きを制御するシンプルなコンセプトです。各コンポーネントの役割と機能を理解し、それらを組み合わせて目的の性能を実現するまで分解して説明します。
1. ADXL335(加速度センサー)
加速度センサーの役割は手首の向きを検知すること。重力加速度'g'も含めて加速度を測定するため、ADXL335の任意の軸にかかる'g'の成分を測定することで手首の向きを検知できます(下図参照)。

手の傾きによりX軸および/またはY軸の鉛直方向との角度が変わり、'g'加速度の成分がそれらにかかるため、これを測定して手の向きを判定します。ADXL335は最大3gまで測定可能で、軸ピンをArduinoのアナログピンに接続してインターフェースします。出力電圧は加速度に比例します。
本プロジェクトでは、加速度センサーをArduino Nanoに接続し、手のひらに装着。ADXL335は0〜Vcc(通常3.3V)の電圧を出力し、Arduinoのアナログピンで読み取ります(10ビットADCで0〜1024の値)。異なる向きで各軸のアナログ値が異なり、これを各ロボット動作にマッピングします。
加速度センサー回路図

ADXL335動作確認用テストコード
void setup() {
pinMode(A0, INPUT); // X軸 → A0
pinMode(A1, INPUT); // Y軸 → A1
pinMode(A2, INPUT); // Z軸 → A2
Serial.begin(9600);
}
void loop() {
Serial.print(" X= ");
Serial.println(analogRead(A0));
Serial.print(" Y= ");
Serial.println(analogRead(A1));
Serial.print(" Z= ");
Serial.println(analogRead(A2));
delay(1000);
}
このプログラムを実行して、手のひら/手首の前後左右傾きでどの値が得られるか確認し、最終的なロボット制御に使用します。
2. RF-433 送信機と受信機
RFモジュールの役割は、手首側のArduino Nanoからモーター制御側のArduino Unoへコマンドデータを送信すること。433MHz帯の電波を使用し、振幅変調でデータ送信。前進、後退、右、左のコマンドを送信し、データがない場合は停止。通信距離は約10メートルまで良好です。
送信側回路
送信側はRF送信機とHT12Eエンコーダーで構成。HT12Eが送信機にデータを供給します。エンコーダーには4つのデータピンがあり、それぞれ前進、後退、左、右の動作を表現(HIGHで該当動作、全LOWで停止)。アドレスピン(A0-A7)は送信側と受信側で同一に設定(本プロジェクトでは全てLOW/接地)。データ入力ピンをArduinoデジタルピン(6-9)に接続し、ADXL335の入力に基づいてHIGH出力します。

受信側回路
受信側も同様の構成ですが、データピンをArduinoへの入力として読み取り、モーターを駆動します。接続確認用に、ピン17にLEDを1kΩ抵抗直列で接続する簡易版も可能です。

3. モーターシールド
AdafruitのAFMotorライブラリ(GitHub)を使用すると簡単に制御できます。ライブラリをArduinoライブラリフォルダにコピーしてインクルードします。
AFMotorライブラリ使用例
#include
AF_DCMotor motor(4); // モーターをシールドのM4端子に接続
void setup() {
Serial.begin(9600);
Serial.println("Motor test!");
motor.setSpeed(200);
motor.run(RELEASE);
}
void loop() {
uint8_t i;
Serial.print("tick");
motor.run(FORWARD);
for (i=0; i<255; i++) { motor.setSpeed(i); delay(10); }
for (i=255; i!=0; i--) { motor.setSpeed(i); delay(10); }
Serial.print("tock");
motor.run(BACKWARD);
for (i=0; i<255; i++) { motor.setSpeed(i); delay(10); }
for (i=255; i!=0; i--) { motor.setSpeed(i); delay(10); }
Serial.print("tech");
motor.run(RELEASE);
delay(1000);
}
4. 全てを組み合わせる
モーターシールドはほぼ全デジタルピンを使用するため、Arduino Unoのアナログピンで受信データを読み取ります。最終回路図は以下の通り。

モーターシールドがモーター接続を処理。9V電池をシールド電源入力に接続。注:個人的には9V電池を2〜3個並列接続してシールド電源入力に繋ぎ、4つ全モーター駆動用の十分な電力を確保することを推奨します。同側のモーター2つずつを並列接続し、モーターポイント3と4のみで駆動する構成としています。

最終コード
Arduino Nano側(送信側)
int x_axis = 0;
int y_axis = 0;
int forward = 9;
int backward = 10;
int right = 11;
int left = 12;
void setup() {
pinMode(A0, INPUT); // X軸
pinMode(A3, OUTPUT); // Y軸(注:元コードではA1だがA3になっている)
pinMode(forward, OUTPUT);
pinMode(backward, OUTPUT);
pinMode(right, OUTPUT);
pinMode(left, OUTPUT);
Serial.begin(9600);
}
void loop() {
x_axis = analogRead(A0);
y_axis = analogRead(A3);
Serial.print(" X = ");
Serial.println(x_axis);
Serial.print(" Y = ");
Serial.println(y_axis);
if (y_axis >= 390) {
Serial.println("Forward");
digitalWrite(forward, HIGH);
} else {
if (y_axis <= 310) {
Serial.println("BACK");
digitalWrite(backward, HIGH);
} else {
if (x_axis >= 380) {
Serial.println("RIGHT");
digitalWrite(right, HIGH);
} else {
if (x_axis <= 320) {
Serial.println("LEFT");
digitalWrite(left, HIGH);
}
Serial.println(" ");
}
}
}
delay(200);
if (x_axis > 320 && x_axis < 380 && y_axis > 310 && y_axis < 390) {
digitalWrite(forward, LOW);
digitalWrite(backward, LOW);
digitalWrite(right, LOW);
digitalWrite(left, LOW);
}
}
Arduino Uno側(受信・モーター制御側)
#include
AF_DCMotor motor_right(3);
AF_DCMotor motor_left(4);
int forward=0, backward=0, right=0, left=0;
void setup() {
pinMode(A2, INPUT);
pinMode(A3, INPUT);
pinMode(A4, INPUT);
pinMode(A5, INPUT);
Serial.begin(9600);
motor_right.setSpeed(255);
motor_left.setSpeed(255);
motor_right.run(RELEASE);
motor_left.run(RELEASE);
}
void loop() {
forward = digitalRead(A0);
backward = digitalRead(A1);
right = digitalRead(A2);
left = digitalRead(A3);
if(forward == HIGH) {
motor_right.run(FORWARD);
motor_left.run(FORWARD);
Serial.println("Forward");
}
if(backward == HIGH) {
motor_right.run(BACKWARD);
motor_left.run(BACKWARD);
Serial.println("Reverse");
}
if(right == HIGH) {
motor_right.run(FORWARD);
motor_left.run(RELEASE);
Serial.println("RIGHT");
}
if(left == HIGH) {
motor_right.run(RELEASE);
motor_left.run(FORWARD);
Serial.println("LEFT");
}
if(left == LOW && right == LOW && forward == LOW && backward == LOW) {
motor_right.run(RELEASE);
motor_left.run(RELEASE);
}
delay(100);
}
写真と動画はプロジェクトページでご覧いただけます。
製造プロセス
- スマート貯金箱を作ろう:Arduino Nanoでコインアクセプターを制御
- Arduino電源制御センター:N-FET/P-FET/リレー/RTC搭載キット
- ArduinoでBluetooth経由でLEDを制御 – シンプルDIYガイド
- Arduino UNOで作る完全自律ライントラッカーロボット ─ 入門に最適な自作キット
- Arduino UNOで作るシンプル電卓 - シリアルモニターで四則演算
- DIY Arduino加湿器コントローラー:リレーを用いた安全な高電圧制御
- Arduino Nanoで音声制御ロボットを自作
- Arduino UNOとATtiny85で作る携帯型POV(残像)ディスプレイ
- Arduino UnoとBluetoothでラジコンカーを遠隔操作:ステップバイステップガイド
- Arduinoロボットアーム「LittleArm」をAndroidアプリでBluetooth制御
- Arduino Unoで25kHz 4ピンPWMファンを制御 – 製作・コード・テスト