从人头到机器头:Arduino 驱动的低成本仿生机器人头部 DIY
项目动机
热爱机器人但受限于舵机成本?本项目仅用 3 个舵机($13)、Arduino UNO、LinkIt ONE 板和安卓手机,打造一个能三轴(偏航/俯仰/横滚)跟随人头动作的机器人头。核心思路:利用手机内置姿态传感器(方向/俯仰/横滚)经蓝牙传输控制舵机,极大降低成本。
材料清单
| 组件 | 数量 | 备注 |
|---|---|---|
| Arduino UNO | 1 | 主控舵机 |
| LinkIt ONE | 1 | 蓝牙接收手机数据,经串口转发给 UNO |
| 5V 舵机 | 3 | 对应 Yaw/Pitch/Roll 三轴 |
| 安卓手机 | 1 | 运行 SensoDuino 采集姿态 |
| 稳压电源板 | 1 | 输出 12V/5V/3.3V,舵机供电 |
| 万用 PCB、公针座、铝角材、热熔胶、12V/5V 适配器 | 若干 | 结构与供电 |
为何双板? LinkIt ONE 仅 2 路 PWM 且 3.3V 电平,驱动不了 5V 舵机;UNO 有 6 路 PWM 且 5V 逻辑。若有蓝牙模块(如 HC-05)可省去 LinkIt ONE,单 UNO 即可。
自制舵机扩展板
- 万用板焊接 6 路舵机接口(信号接 UNO D3/5/6/9/10/11,电源/地并联)
- 舵机电源**必须**接外部 5V 稳压板,不可取 USB 供电(电流不足导致抖动、过热、烧毁舵机——实测烧过一个)
- UNO 也建议接外部适配器供电

机械结构设计:三轴串联
- Yaw(偏航·左右转):底座舵机,输出臂水平安装
- Pitch(俯仰·上下点头):第二舵机,通过铝角材 L 型件固定在 Yaw 输出臂上,轴线垂直于 Yaw
- Roll(横滚·侧倾):第三舵机,固定在 Pitch 输出臂末端,轴线与 Pitch 平行
- 所有舵机中位(90°)时轴线共线、头部朝正前方
- 先双面胶临时固定验证运动不干涉,再热熔胶永久固定
- LinkIt ONE TX → UNO RX,共地
- 三舵机信号线分别接 UNO D3(Yaw)、D5(Pitch)、D6(Roll)
- 稳压板 5V 给舵机,12V 给 UNO/LinkIt(或各自适配器)
- 安装 SensoDuino
- 菜单 → Connect Bluetooth → 选择 LinkIt ONE
- 启用 Orientation 传感器,勾选"Send via Bluetooth"
- Performance 设置采样率:测试 250ms,最终 100ms(10Hz)
- 上传中位代码,通电确认三舵机均指向 90°,机械臂共线
- 手持手机测试:面向磁北 180°(Yaw 中位),点头/摇头/侧倾观察跟随
- SensoDuino 调至 100ms 采样,动作流畅度显著提升
- 找圣诞老人玩偶头套在 Roll 舵机臂上,戴帽子固定手机(双面胶)
- 戴帽子,面向 180° 站立,机器人头即跟随你的头部动作
- 蓝牙延迟 + 100ms 采样 → 约 200-300ms 端到端延迟
- 磁力计受环境干扰,Yaw 长时间漂移,需定期重新校准朝向
- LinkIt ONE 已停产,建议改用 ESP32/HC-05 + 单 UNO 方案
- 结构可升级为 3D 打印关节,提升精度与美观度
- 3× 舵机:$13
- Arduino UNO 兼容板:~$5
- LinkIt ONE / HC-05:~$10
- 电源板、PCB、结构件:~$10
- **总计 < $40**,商业同类仿真头通常 $200+

电子连接
手机端:SensoDuino 配置
Orientation 输出格式:>Orientation,1,Yaw,Pitch,Roll>(Yaw: 0-360°,Pitch: -180~+180°,Roll: -90~+90°)
固件代码
LinkIt ONE:蓝牙透传
#include <LBT.h> #include <LBTServer.h>
String inputString = "";
void setup() {
LBTServer.begin((uint8_t*)"Sivam_LIO");
Serial1.begin(9600); // 硬件串口接 UNO RX
}
void loop() {
if (LBTServer.connected()) {
uint8_t buf[64]; int bytesRead;
while ((bytesRead = LBTServer.readBytes(buf, 32)) > 0) {
inputString = "";
for (int j=0; j
Arduino UNO:解析与舵机映射
#include <Servo.h>
Servo leftright, updown, shake;
String inputString = "";
void setup() {
Serial.begin(9600);
leftright.attach(3); updown.attach(5); shake.attach(6);
leftright.write(90); updown.write(90); shake.write(90);
}
void serialEvent() {
while (Serial.available()) {
char c = Serial.read(); if (c != '\n') inputString += c;
}
int s = inputString.indexOf('>');
if (s >= 0) {
int e = inputString.indexOf('>', s+1);
if (e > 0) {
String frame = inputString.substring(s, e);
inputString = inputString.substring(e);
// 解析: >Orientation,1,Yaw,Pitch,Roll>
int c1 = frame.indexOf(','); String sensor = frame.substring(1, c1);
int c2 = frame.indexOf(',', c1+1); String rec = frame.substring(c1+1, c2);
int c3 = frame.indexOf(',', c2+1); String v1 = frame.substring(c2+1, c3);
int c4 = frame.indexOf(',', c3+1); String v2 = frame.substring(c3+1, c4);
String v3 = frame.substring(c4+1);
int S1=v1.toInt(), S2=v2.toInt(), S3=v3.toInt();
// 映射到舵机 0-180°
int rot1 = map(S1, 90, 270, 180, 0); // Yaw: 面向 180° 为中位
int rot2 = map(S2, -90, 90, 0, 180); // Pitch
int rot3 = map(S3, 90, -90, 0, 180); // Roll: 注意符号反向
rot1 = constrain(rot1, 0, 180);
rot2 = constrain(rot2, 0, 180);
rot3 = constrain(rot3, 0, 180);
if (rot1!=0 && rot1!=180) leftright.write(rot1);
if (rot2!=0 && rot2!=180) updown.write(rot2);
if (rot3!=0 && rot3!=180) shake.write(rot3);
delay(15);
}
}
}
舵机中位校准代码
// Servoposition.ino
#include <Servo.h>
Servo leftright, updown, shake;
void setup() {
leftright.attach(3); updown.attach(5); shake.attach(6);
leftright.write(90); updown.write(90); shake.write(90);
}
void loop() {}
调试与定型

已知局限与改进
成本核算
制造工艺
- DIY仿Wall-E树莓派CD盒机器人
- 滚动闹钟机器人:树莓派+Google Calendar智能移动唤醒系统
- RasPiRobot Board V2:将树莓派扩展为强大机器人控制器
- 用 Arduino 打造电动《我的世界》苦力怕机器人
- Archimedes:情感感知 AI 机器猫头鹰
- 在 Windows 10 IoT Core 上构建语音驱动的计算机视觉机器人
- ROS 机器人:树莓派终端控制导航
- 在 Sonbi 机器人上集成 Microsoft Kinect 与树莓派实现实时人体检测
- Simple Pi Robot:用树莓派打造 2WD 自主巡航车
- 真正的资产:零售运营中的人力资本
- 软体机器人通过相机与阴影检测人类触摸——低成本无接触方案
- 人类反射神经助双足机器人保持平衡