スマートArduino四足歩行ロボットの製作:ステップバイステップガイド
部品と用品
| Arduino Mega 2560 | 1 |
| SG90 マイクロサーボモーター | 12 |
| SparkFun 超音波センサー HC-SR04 | 1 |
| 5mm LED:赤 | 4 |
| 5mm LED:緑 | 4 |
| LED、青 | 4 |
| メスヘッダー 40ピン 1列 (2.54mm) | 2 |
| カスタムPCB | 1 |
必要な工具と機械
| はんだごて(汎用) |
アプリとオンラインサービス
| Arduino IDE |
このプロジェクトについて
Arduinoベースの四足歩行ロボット!四足とは4本脚のボットで、基本的にクモのような見た目をしています。クモがどう歩くかを学び、Arduinoで再現してみましょう。
必要な部品
- Arduino Mega または Arduino Uno ×1
- 穴あきユニバーサル基板 ×1
- サーボモーター(9g) ×12
- HC-SR04 超音波センサー ×1
- RGB LED ×4
- 段ボール
ステップ2:重心(CG)の維持

歩行時の最重要要素は重心(CG)です。重心がボディの中心にあればバランスよく立てますが、許容範囲を超えてズレるとバランスを崩して転倒します。
すべての脚が45度なら重心は完璧に中心にあります。しかし、いずれかの脚を動かすと重心がその側に移動し、その方向に倒れます。
これを防ぐには、両端の脚を45度より大きい角度に保ち(ボディサイズによる)、3本の脚で三角形を形成してその中に重心を収め、残りの1本を自由に動かせるようにします。
ステップ3:歩行手順

- 初期位置:C脚とD脚を片側に伸ばし、A脚とB脚を内側に引く
- 右前脚(B)を持ち上げ、ロボットの前方遠くに伸ばす
- すべての脚を後方にシフトし、ボディを前進させる
- 左後脚(D)を持ち上げ、ボディの横に前進させる。初期位置の鏡像になる
- 左前脚(A)を持ち上げ、前方遠くに伸ばす
- 再びすべての脚を後方にシフトし、ボディを前進させる
- 右後脚(C)を持ち上げ、ボディに戻す。初期位置に戻る
ステップ4:四足ロボットの設計図
LEGS.pdf BODY.pdfステップ5:ボディの構築


PDFに従ってボディを構築してください。
ステップ6:回路接続

Arduino Megaには15個のPWMピンがあります。12個をサーボ接続に、3個をRGB LEDに、任意の2ピンを超音波センサーに使用して、独自のシールドを作成してください。
ステップ7:サーボの初期化
- プログラムをArduino Megaにアップロードし、画像に従って脚を組み立て開始

#include <Servo.h>
Servo servo[4][3];
const int servo_pin[4][3] = { {10,11,2}, {3,4,5}, {6,7,8}, {9, 12, 13} };
void setup() {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 3; j++) {
servo[i][j].attach(servo_pin[i][j]);
delay(20);
}
}
}
void loop(void) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 3; j++) {
servo[i][j].write(90);
delay(20);
}
}
}
ステップ8:最終ステップ


メインコード(完全版)
/* Includes ----------------------------------------------------------------*/
#include <Servo.h>
#include <FlexiTimer2.h>
#define ledred 46
#define ledblue 44
#define ledgreen 45
/* Servos ----------------------------------------------------------------*/
Servo servo[4][3];
const int servo_pin[4][3] = { {2, 3, 4}, {20, 6, 7}, {8, 9, 17}, {16, 12, 13} };
/* Size of the robot -----------------------------------------------------*/
const float length_a = 55;
const float length_b = 77.5;
const float length_c = 27.5;
const float length_side = 71;
const float z_absolute = -28;
/* Constants for movement ------------------------------------------------*/
const float z_default = -50, z_up = -30, z_boot = z_absolute;
const float x_default = 62, x_offset = 0;
const float y_start = 0, y_step = 40;
const float y_default = x_default;
/* variables for movement ------------------------------------------------*/
volatile float site_now[4][3];
volatile float site_expect[4][3];
float temp_speed[4][3];
float move_speed;
float speed_multiple = 1;
const float spot_turn_speed = 4;
const float leg_move_speed = 8;
const float body_move_speed = 3;
const float stand_seat_speed = 1;
volatile int rest_counter;
const float KEEP = 255;
const float pi = 3.1415926;
/* Constants for turn ----------------------------------------------------*/
const float temp_a = sqrt(pow(2 * x_default + length_side, 2) + pow(y_step, 2));
const float temp_b = 2 * (y_start + y_step) + length_side;
const float temp_c = sqrt(pow(2 * x_default + length_side, 2) + pow(2 * y_start + y_step + length_side, 2));
const float temp_alpha = acos((pow(temp_a, 2) + pow(temp_b, 2) - pow(temp_c, 2)) / 2 / temp_a / temp_b);
const float turn_x1 = (temp_a - length_side) / 2;
const float turn_y1 = y_start + y_step / 2;
const float turn_x0 = turn_x1 - temp_b * cos(temp_alpha);
const float turn_y0 = temp_b * sin(temp_alpha) - turn_y1 - length_side;
/* -------------------------------------------------------------------------*/
void setup() {
pinMode(ledred, OUTPUT);
pinMode(ledblue, OUTPUT);
pinMode(ledgreen, OUTPUT);
Serial.begin(115200);
Serial.println("Robot starts initialization");
set_site(0, x_default - x_offset, y_start + y_step, z_boot);
set_site(1, x_default - x_offset, y_start + y_step, z_boot);
set_site(2, x_default + x_offset, y_start, z_boot);
set_site(3, x_default + x_offset, y_start, z_boot);
for (int i = 0; i < 4; i++)
for (int j = 0; j < 3; j++)
site_now[i][j] = site_expect[i][j];
FlexiTimer2::set(20, servo_service);
FlexiTimer2::start();
Serial.println("Servo service started");
servo_attach();
Serial.println("Servos initialized");
Serial.println("Robot initialization Complete");
}
void servo_attach(void) {
for (int i = 0; i < 4; i++)
for (int j = 0; j < 3; j++) {
servo[i][j].attach(servo_pin[i][j]);
delay(100);
}
}
void servo_detach(void) {
for (int i = 0; i < 4; i++)
for (int j = 0; j < 3; j++) {
servo[i][j].detach();
delay(100);
}
}
void loop() {
analogWrite(ledred, 255); Serial.println("Stand"); stand(); delay(2000);
analogWrite(ledred, 0); analogWrite(ledblue, 255); Serial.println("Step forward"); step_forward(5); delay(2000);
analogWrite(ledblue, 0); analogWrite(ledgreen, 255); Serial.println("Step back"); step_back(5); delay(2000);
analogWrite(ledgreen, 0); analogWrite(ledred, 255); analogWrite(ledblue, 255); Serial.println("Turn left"); turn_left(5); delay(2000);
analogWrite(ledgreen, 255); analogWrite(ledred, 0); analogWrite(ledblue, 255); Serial.println("Turn right"); turn_right(5); delay(2000);
analogWrite(ledgreen, 255); analogWrite(ledred, 255); analogWrite(ledblue, 0); Serial.println("Hand wave"); hand_wave(3); delay(2000);
Serial.println("Hand shake"); hand_shake(3); delay(2000);
int x = 100;
for(int i = 0; i < 5; i++) {
analogWrite(ledgreen, 255); analogWrite(ledred, 255); analogWrite(ledblue, 255); delay(x); // white
analogWrite(ledgreen, 255); analogWrite(ledred, 255); analogWrite(ledblue, 0); delay(x); // yellow
analogWrite(ledgreen, 255); analogWrite(ledred, 0); analogWrite(ledblue, 255); delay(x); // cyan
analogWrite(ledgreen, 0); analogWrite(ledred, 255); analogWrite(ledblue, 255); delay(x); // purple
analogWrite(ledgreen, 0); analogWrite(ledred, 255); analogWrite(ledblue, 0); delay(x); // red
analogWrite(ledgreen, 0); analogWrite(ledred, 0); analogWrite(ledblue, 255); delay(x); // blue
analogWrite(ledgreen, 255); analogWrite(ledred, 0); analogWrite(ledblue, 0); delay(x); // green
}
analogWrite(ledgreen, 0); analogWrite(ledred, 0); analogWrite(ledblue, 0);
delay(1000);
}
/* 各種動作関数(sit, stand, turn_left, turn_right, step_forward, step_back,
hand_wave, hand_shake, head_up, head_down, body_dance)および
サーボ制御の数学モデル(cartesian_to_polar, polar_to_servo)は
元コードの通り実装されています。詳細はGitHub等を参照してください。 */
LEDピンを接続したら完成です!
- プログラムをアップロード
- プログラムで定義されたピンにサーボを接続
追加コード
spider(メインスケッチ)
上記メインコードと同内容
spider_fix.ino(脚の初期位置調整用)
// 脚の初期位置を特定するためのスケッチ
// RegisHsu 2015-09-09
#include <Servo.h>
Servo servo[4][3];
const int servo_pin[4][3] = { {10,11,2}, {3,4,5}, {6,7,8}, {9, 12, 13} };
void setup() {
for (int i = 0; i < 4; i++)
for (int j = 0; j < 3; j++) {
servo[i][j].attach(servo_pin[i][j]);
delay(20);
}
}
void loop(void) {
for (int i = 0; i < 4; i++)
for (int j = 0; j < 3; j++) {
servo[i][j].write(90);
delay(20);
}
}
カスタムパーツとエンクロージャ
回路図
製造プロセス
- 自作LUMAZOID:Arduino音楽ビジュアライザーDIYガイド
- Arduino Nano 33 IoT製 フライトシミュレーター2020用コックピットパネル - LCD&CDI表示
- ArduinoでBluetooth経由でLEDを制御 – シンプルDIYガイド
- Arduino手洗いタイマー:COVID-19対策のシンプルDIYツール
- Arduino RGB LEDカラーミキサー:初心者向けDIYプロジェクト
- Arduino Unoで8×8 LEDマトリックスを制御:ステップバイステップガイド
- DIY ArduinoラジオニクスEMR治療デバイスの構築
- 屋外対応DMX制御RGB LED投光器 – 低コスト・高性能・自作PCB
- DIY LEDルーレットゲーム – Arduino Nanoで作る1人用アーケードゲーム
- Arduino駆動スマート自動駐車場システムの製作
- Arduino超音波距離センサー:HC-SR04で測定システム構築