Webインターフェースで6自由度Arduinoロボットアームをリモート制御
部品と材料
| Arduino UNO | 1 | |
| PHPoC WiFi Shield for Arduino | 1 | |
| 6自由度アームロボット | 1 |
このプロジェクトについて
初心者の方は以下のチュートリアルを先に読むことを推奨します:
- Arduino - モーター
- Arduino - サーボモーター
- Arduino - WiFi
1. デモンストレーション
2. ユーザーインターフェース


ロボットアームには6つのモーター(サーボ)があります:
- ゾーンA: モーター2, 3, 4を制御(3つの手首関節)
- ゾーンB: モーター1を制御(ベース回転)
- ゾーンC: モーター5を制御(グリッパー回転)
- ゾーンD: モーター6を制御(グリッパー開閉)
3. システムアーキテクチャ

4. 動作フロー
クライアント側(Web UI - JavaScript + HTML + CSS)
ユーザーがタッチ/スワイプ(またはマウス操作)すると座標(x, y)を取得。処理フローは以下の通り:

ゾーンAの場合、モーター2, 3, 4の角度を求めるため幾何計算が必要です(詳細は後述)。
サーバー側(Arduinoコード)
クライアントから角度セットを受信すると、6つのモーターが現在角度から目標角度へ同時に到達するよう滑らかに動作します。単一モーターの制御を考えると:目標角度まで小さなステップで動かし、短い待機を繰り返します。

6モーターを同期させるには、全モーターで同じstepNum(ステップ数)を使い、各モーターのstep(ステップ角度)を変えます。stepNumは最大値を採用。
Arduino全体の動作フロー:

5. 幾何計算(逆運動学)
ロボットアームの計算を以下の幾何問題に帰着させます:
既知
- 点Cは固定
- 点Dはユーザー入力(既知)
- 線分CB, BA, ADの長さ(b, a, d)は既知
- 各アームセグメントの長さ
求めるもの: 角度C, B, A
解法:
- 角度BとAは等しいと仮定
- 補助点と線分を追加
計算過程:
- 点C, Dが既知 → CDの長さ(c)と角度δを計算可能
- 三角形ABEより AE = BE、∠E = π - 2α
- 余弦定理を三角形CDEに適用
- 式変形して2次方程式を解き、αを求める。β = π - α
- さらに余弦定理でγを求める
簡略化:
a, b, c, dが既知なので2次方程式を解いてαを計算。β = π - α。さらに三角形BDCとBDAの余弦定理からγを算出。
最終的にモーター2, 3, 4の目標角度は:(δ+γ), β, βとなります。
6. ソースコード
ソースコードは2ファイル:
- RobotArmWeb.ino: Arduinoコード
- Remote_arm.php: Webアプリコード(PHPoC WiFi ShieldまたはPHPoC Shieldにアップロード)
画像ファイル flywheel.png もPHPoC Shieldにアップロード必要。

関数リファレンス
- Arduino - Servo Library
- Servo.attach() / write() / writeMicroseconds() / read() / attached() / detach()
- Serial.begin() / println()
コード
RobotArmWeb (Arduino)
Arduino側のコードです。
#include <Phpoc.h>
#include <Servo.h>
int angle_init[] = {90, 101, 165, 153, 90, 120}; // 実機での直立時角度
// Web側での直立角度: {0, 90, 130, 180, 0, 0}
int angle_offset[] = {0, 11, -15, -27, 0, 137}; // 実機とWebのオフセット
int cur_angles[] = {90, 101, 165, 153, 90, 120}; // 現在角度
int dest_angles[] = {0, 0, 0, 0, 0, 0}; // 目標角度
int angle_max[] = {180, 180, 160, 120, 180, 137};
int angle_min[] = { 0, 0, 0, 20, 0, 75};
int direction[] = {1, 1, 1, 1, 1, -1};
int angleSteps[] = {3, 2, 2, 2, 4, 4}; // 各モーターのステップ角度
Servo servo1, servo2, servo3, servo4, servo5, servo6;
Servo servo[6] = {servo1, servo2, servo3, servo4, servo5, servo6};
PhpocServer server(80);
PhpocClient client;
int stepNum = 0;
void setup() {
Serial.begin(9600);
Phpoc.begin(PF_LOG_SPI | PF_LOG_NET);
server.beginWebSocket("remote_arm");
servo1.attach(2);
servo2.attach(3);
servo3.attach(4);
servo4.attach(5);
servo5.attach(6);
servo6.attach(7);
for(int i = 0; i < 6; i++) servo[i].write(angle_init[i]);
}
void loop() {
PhpocClient client = server.available();
if(client) {
String angleStr = client.readLine();
if(angleStr) {
Serial.println(angleStr);
int commaPos1 = -1, commaPos2;
for(int i = 0; i < 5; i++) {
commaPos2 = angleStr.indexOf(',', commaPos1 + 1);
int angle = angleStr.substring(commaPos1 + 1, commaPos2).toInt();
dest_angles[i] = angle * direction[i] + angle_offset[i];
commaPos1 = commaPos2;
}
int angle5 = angleStr.substring(commaPos1 + 1).toInt();
dest_angles[5] = angle5 * direction[5] + angle_offset[5];
stepNum = 0;
// ステップ数計算(最大ステップ数を採用して同期)
for(int i = 0; i < 6; i++) {
int dif = abs(cur_angles[i] - dest_angles[i]);
int step = dif / angleSteps[i];
if(stepNum < step) stepNum = step;
}
}
}
// ステップごとにモーターを動かす
if(stepNum > 0) {
for(int i = 0; i < 6; i++) {
int angleStepMove = (dest_angles[i] - cur_angles[i]) / stepNum;
cur_angles[i] += angleStepMove;
if(cur_angles[i] > angle_max[i]) cur_angles[i] = angle_max[i];
else if(cur_angles[i] < angle_min[i]) cur_angles[i] = angle_min[i];
servo[i].write(cur_angles[i]);
}
stepNum--;
delay(20);
}
}
remote_arm.php (PHP)
Webアプリケーションコードです。
<!DOCTYPE html>
<html>
<head>
<title>Arduino - Arm Robot - Web</title>
<meta name="viewport" content="width=device-width, initial-scale=0.9">
<style>
body { text-align: center; }
canvas { background-color: #FFFFFF; }
</style>
<script>
// ... JavaScriptコード(幾何計算、WebSocket通信、Canvas描画など)
// 完全なコードは元記事またはGitHubを参照
</script>
</head>
<body>
<h2>Arduino - Control Arm Robot via Web</h2>
<canvas id="servo"></canvas>
<p>WebSocket : <span id="ws_state">null</span><br></p>
<button id="wc_conn" type="button" onclick="wc_onclick();">Connect</button>
</body>
</html>
回路図
6つのモーターには外部電源が必要です。

製造プロセス
- シンプルPiロボット - Raspberry Piで2WD自律ローバーを構築
- Arduino電源制御センター:N-FET/P-FET/リレー/RTC搭載キット
- IoTで遠隔操作する自作ロボットアーム:Arduino MKR1000とSimulink、ThingSpeak活用
- ArduinoとHC-SR04で作るサーボ駆動障害物回避ロボット
- Arduino UNOで作る完全自律ライントラッカーロボット ─ 入門に最適な自作キット
- DIY Arduino加湿器コントローラー:リレーを用いた安全な高電圧制御
- Arduino UNO + WiFiシールドで温度をWebリアルタイム表示 — シリアル出力だけでグラフ化
- LittleArm 2C: 3Dプリント製Arduinoロボットアーム – STEM教育向け耐久設計
- 自律型ホームアシスタントロボット「O'nine」の構築 – ROS、Alexa、ロボットアーム完全ガイド
- Intel Curie搭載Arduino 101によるモーションアクティブ照明システム
- Arduino向けスマート屋内ナビゲーションロボットキット