ESP32四足蜘蛛机器人搭建:8舵机蓝牙遥控,3小时完工

2026-10-26 19:42:54 137阅读

轮式小车太简单了,四条腿才是真正的入门功课。一只四足机器人得同时管好三件事:三条腿撑住地面、一条腿抬起来迈步、身体重心在支撑腿围成的三角形里来回挪。任何一件没算对,它就在你面前趴下。

这篇教程用一块 ESP32、八个 MG90S 舵机、一块 3D 打印的蜘蛛架子,搭一台手机蓝牙遥控的四足机器人。物料成本大概 43 美元,不含打印件和电池,动手三小时能走起来。核心思路很简单:每条腿一个髋关节加一个膝关节,所有动作都走同一套平滑插值,再加一个校准模式让你在软件里修直一条歪腿,不用拧螺丝。代码是完整可烧的,不是示意片段。

ESP32 四足蜘蛛机器人成品俯视图,红色六边形主控板居中,四条黄紫色 3D 打印腿向外展开,蓝色微型舵机装在关节处,深灰背景

成品俯拍:四条腿是 3D 打印件,红色六边形主控板压在机身中间,蓝色微型舵机分别装在髋和膝两个关节上,橙红两色是走线的杜邦线。

材料清单

先把手上的东西点一遍,缺一样都装不完整。

ESP32 开发板一块,38 针、CP2102 串口芯片、USB-C 口。这里有个硬要求:必须是原版 ESP32。S3 和 C3 没有经典蓝牙 SPP,代码里那句 BluetoothSerial 直接编译不过。

MG90S 金属齿轮微型舵机八个,髋四个、膝四个。金属齿轮是必须的,塑料齿轮的 SG90 撑不住四足落地那一下冲击,走两圈就扫齿。

XL4015 降压模块一个,5A 输出,专门给舵机供电。这是整套里最容易被省掉、也最不能省的一件。

两节 18650 电池盒一个,串起来 7.4 到 8.4 伏。

电解电容一颗,470 到 1000 微法,跨接在舵机电源轨上。

杜邦线若干、M2 螺丝一包、3D 打印的蜘蛛框架一套(身体一块、髋四块、腿四条),外加一台安卓手机,装一个蓝牙串口终端 App。

有一条必须记住:八个舵机同时动的瞬间电流有好几安培,绝对不能从 ESP32 的 5V 或者 3V3 引脚取电。板上那颗稳压芯片额定几百毫安,一冲就掉压,表现就是走到一半突然重启。遇到这种症状,九成九是电源问题,不是代码问题。

第一步:先把电搞定

装腿之前先单独把电源调好,这一步花五分钟,能省掉后面两小时的莫名其妙。

电池盒的输出接 XL4015 输入端,输出端先不接任何负载,万用表搭在输出上,拧那颗电位器,把电压调到 5.5 伏。为什么不是 5 伏:MG90S 标称工作电压 4.8 到 6 伏,取中间偏上,扭矩够、发热也不至于太夸张。而且降压模块带载之后输出会往下掉一点,空载调 5.5,接上八个舵机大概落在 5.3 左右,还在安全区。

XL4015 降压电源模块实物,蓝色电路板上带大电感、可调电位器和接线端子,斜角拍摄

XL4015 降压模块实物,蓝色板子上一颗大电感和一颗可调电位器。输入端接两节 18650 的 7.4 到 8.4 伏,输出调到 5.5 伏再喂给八个舵机。

电压确认之后接线:XL4015 输出正极接八个舵机的红线,全部并联;输出负极接八个舵机的棕线,同时接 ESP32 的 GND。电容正负极跨在舵机电源轨上,尽量靠近舵机那一端。

电容这颗东西很多人省,但它干的活很实在:舵机启动那一瞬间要从电源抽一大口电流,线材有电阻,抽的瞬间整条轨的电压会被拉低。电容像个就近的小水库,先顶一下,让电压别塌。470 微法够用,1000 微法更稳,注意耐压选 16 伏以上。

还有一条:舵机的地和 ESP32 的地必须接在一起。信号是靠电压差传的,两边地不共,信号电平就没有共同参考点,舵机会乱抖。这是新手最常见的坑之一。

第二步:引脚怎么分

舵机信号线是橙色的,八根分别接到 ESP32 的八个 GPIO。腿的编号定成这样:0 号左前、1 号右前、2 号左后、3 号右后。

髋关节四个接 GPIO 13、16、18、25。膝关节四个接 GPIO 27、17、19、26。

这组引脚不是随手挑的,它避开了 ESP32 的 strapping pins,也就是 GPIO 0、2、5、12、15 这五个。这几个脚在上电那一刻会被芯片采样,用来决定从哪个分区启动、跑什么时钟。如果你把舵机信号挂在这上面,上电瞬间舵机内部把线拉高或者拉低,芯片就采样到错误电平,直接进不了 boot,板子看起来像坏了。

舵机控制板布线示意图,标注 3V3、GND、IO 走线以及 220、100uF、470uF、SB560、D2、D5 等元件位号

舵机控制板的布线与元件位图,标了 3V3、GND、IO 的走线走向,还有 220、100uF、470uF、SB560 这些元件位号。自己打板的话照着这张对位。

另外 34 到 39 这几个脚是只输不能输出的,也别拿来驱动舵机。剩下的脚里,避开 strapping、避开只输入、避开串口占用的 1 和 3,可用范围就很清楚了。

第三步:烧固件

先装 Arduino IDE,从库管理器装上 ESP32Servo 库,板子选 ESP32 Dev Module。顺序很重要:在装腿之前就把程序烧进去。因为烧完程序舵机会立刻归中到 90 度,如果腿已经装上了,它会突然一拧,可能把打印件别断。

#include "BluetoothSerial.h"      // 经典蓝牙SPP,只有原版ESP32支持
#include "ESP32Servo.h"

BluetoothSerial bt;
// 腿编号:0左前 1右前 2左后 3右后
const int HIP_PIN[4]  = {13, 16, 18, 25};
const int KNEE_PIN[4] = {27, 17, 19, 26};
int hipDir[4]  = {1, -1, 1, -1};
int kneeDir[4] = {1, -1, 1, -1};
int hipTrim[4]  = {0, 0, 0, 0};
int kneeTrim[4] = {0, 0, 0, 0};
const int SWING = 25, LIFT = 35, STAND = 0;

Servo hip[4], knee[4];
int hipPos[4], kneePos[4];

void writeLeg(int i) {
  hip[i].write(90 + hipDir[i] * hipPos[i] + hipTrim[i]);
  knee[i].write(90 + kneeDir[i] * kneePos[i] + kneeTrim[i]);
}

void glide(const int h[4], const int k[4], int ms) {
  int h0[4], k0[4];
  memcpy(h0, hipPos, sizeof h0);
  memcpy(k0, kneePos, sizeof k0);
  for (int s = 1; s <= 20; s++) {
    for (int i = 0; i < 4; i++) {
      hipPos[i]  = h0[i] + (h[i] - h0[i]) * s / 20;
      kneePos[i] = k0[i] + (k[i] - k0[i]) * s / 20;
      writeLeg(i);
    }
    delay(ms / 20);
  }
}

void stepLeg(int i, int hipTarget) {
  int h[4], k[4];
  memcpy(h, hipPos, sizeof h);
  memcpy(k, kneePos, sizeof k);
  k[i] = LIFT; glide(h, k, 120);
  h[i] = hipTarget; glide(h, k, 120);
  k[i] = STAND; glide(h, k, 120);
}

void stand() {
  int h[4] = {0, 0, 0, 0};
  int k[4] = {STAND, STAND, STAND, STAND};
  glide(h, k, 300);
}

void walk(int dir) {
  const int order[4] = {0, 3, 1, 2};
  for (int n = 0; n < 4; n++) stepLeg(order[n], dir * SWING);
  int h[4] = {0, 0, 0, 0}, k[4];
  memcpy(k, kneePos, sizeof k);
  glide(h, k, 400);
}

void turn(int dir) {
  for (int i = 0; i < 4; i++) stepLeg(i, dir * hipDir[i] * SWING);
  int h[4] = {0, 0, 0, 0}, k[4];
  memcpy(k, kneePos, sizeof k);
  glide(h, k, 400);
}

void wave() {
  int h[4], k[4];
  memcpy(h, hipPos, sizeof h);
  memcpy(k, kneePos, sizeof k);
  k[0] = 70; glide(h, k, 300);
  for (int n = 0; n < 3; n++) {
    h[0] = 30; glide(h, k, 250);
    h[0] = -30; glide(h, k, 250);
  }
  stand();
}

void setup() {
  Serial.begin(115200);
  for (int i = 0; i < 4; i++) {
    hip[i].setPeriodHertz(50);
    hip[i].attach(HIP_PIN[i], 500, 2400);
    knee[i].setPeriodHertz(50);
    knee[i].attach(KNEE_PIN[i], 500, 2400);
    hipPos[i] = 0; kneePos[i] = STAND; writeLeg(i);
  }
  bt.begin("ShillehTek-Spider");
}

void loop() {
  static char mode = 'S';
  char c = 0;
  if (bt.available()) c = toupper(bt.read());
  else if (Serial.available()) c = toupper(Serial.read());
  if (c && strchr("FBLRWCS", c)) mode = c;
  switch (mode) {
    case 'F': walk(1); break;
    case 'B': walk(-1); break;
    case 'L': turn(1); break;
    case 'R': turn(-1); break;
    case 'W': wave(); mode = 0; break;
    case 'S': stand(); mode = 0; break;
    case 'C': for (int i = 0; i < 4; i++) { hip[i].write(90); knee[i].write(90); } mode = 0; break;
    default: delay(20);
  }
}

烧完八个舵机会归中到 90 度并保持住。代码里两个头文件用的是引号不是尖括号,这一点别改。

代码结构值得说一下,因为它决定了后面怎么改。核心是三个函数:writeLeg 负责把内部角度换算成舵机实际角度并写出去;glide 负责在两个姿态之间插值,它把一次移动切成 20 小步,每步之间 delay(ms/20),所以任何动作都是滑过去的,不是瞬移;stepLeg 是抬腿、摆髋、落脚三个动作的组合,每段 120 毫秒。

walk 函数里的 order 数组是 0、3、1、2,这是爬行步态(crawl gait)的抬腿顺序:左前、右后、右前、左后。这个顺序保证任何时刻都只有一条腿离地,另外三条构成一个稳定的三角形,身体重心始终落在这个三角形里面。所以它慢,但它几乎不会摔。

第四步:校准中位

这一步决定它走不走得直,是整个教程里最需要耐心的地方。

先往串口发一个 C 命令,八个舵机全部归到精确 90 度。然后装舵机摇臂和腿,目标是让每条髋关节朝对角线方向水平伸出、每条腿水平。

麻烦在于舵机花键只能每 15 度一档,摇臂几乎不可能刚好落在完美的中位上,总会偏个三五度。硬拧会把齿咬坏。正确做法是用代码里的 hipTrim 和 kneeTrim 数组补偿:改几度、重新烧录、发一个 S 看站姿,反复调到四脚均匀着地、身体平行桌面为止。

八个 trim 值调完,这套参数就是你这台机器人的身份证,记下来存好。以后换电池、换腿都不用重调。

第五步:手机连上

手机蓝牙搜索 ShillehTek-Spider,配对之后打开串口终端 App,安卓上推荐 Serial Bluetooth Terminal。连上就能发单字符命令:F 前进、B 后退、L 左转、R 右转、S 站定、W 挥手、C 全部归中。

App 里可以把这几个字符设成快捷按钮,做成一个遥控面板,按下去就走。

按 F 的时候你会看到它一步一步挪:抬左前腿、摆出去、落下,然后右后腿,然后右前,然后左后。四步一轮,身体跟着微微前后晃。这就是最朴素也最可靠的四足行走,不需要任何动态平衡算法,纯靠静态稳定。

第六步:调参

第一次跑基本不会完美,几个常见症状对应几个参数。

某条腿迈步时往后踢而不是往前,说明那个髋舵机装反了,把 hipDir 数组里对应位置的正负号翻一下就行。脚往桌面下扎而不是抬起来,同理翻 kneeDir 的对应项。

走起来脚拖地,把 LIFT 从 35 调到 40 或者 45,抬得高一点。但别调太高,抬得越高落地冲击越大,舵机越吃力。

步伐太大导致身体左右晃,把 SWING 从 25 降到 20。反过来想走快点就往上加,但加到 35 以上支撑三角形会变小,稳定性明显下降。

这些参数可以一边跑串口一边改,改完重烧,不用拆机。这也是为什么要把校准和调参全放在软件里,机械上不留调节余地。

它为什么能站住

很多人第一次看四足行走会觉得玄,其实原理不复杂。四足在任意时刻只要有三条腿着地,这三个着地点就构成一个三角形。只要身体重心在水平面上的投影落在这个三角形内部,它就是静态稳定的,不动也不会倒。

爬行步态就是把这件事做到极致:永远只抬一条腿,支撑三角形永远存在,只是形状在变。代价是慢,四个舵机轮流工作,速度上不去。

真正难的是再往上走一步。小跑步态要同时抬对角两条腿,那时候支撑只剩一条对角线,重心必须靠身体的动量和加速度维持,这就进入动态平衡的范畴,得算零力矩点、得做姿态反馈、得上 IMU。那已经是另一个量级的项目了。

所以这个教程的价值不在于那几十行步态代码,而在于让你真正理解抬腿、落地、身体位移这三件事怎么咬合。glide 和 stepLeg 这两个函数吃透了,后面想做小跑、对角步态、加视觉跟踪,都是在同一个框架上叠东西。

还能往哪加

基础版能走能转能挥手,剩下的空间很大。

想避障,前面装一个 HC-SR04 超声波,在 walk 里加一句距离判断,15 厘米内自动转弯。

想解放 GPIO 同时拿到更稳的 PWM,把舵机迁到 PCA9685 驱动板上,I2C 两根线控十六路,ESP32 的脚就空出来接传感器了。

想摆脱安卓手机,把蓝牙串口换掉,让 ESP32 自己开一个网页,手机浏览器直接连,iPhone 也能用。

想加摄像头做视觉跟随,那就要换主控了,ESP32 的算力跑不动实时目标检测,得往上走到能跑轻量模型的板子。

从一堆零件到一台会走路的四足,中间其实就隔着电源、引脚、插值这三件事。把这三件做对,剩下的都是加法。


作者:固件烧录仔
链接:https://www.aiddithome.com/p/7d3a5b6b4c7.html
本作版权归作者所有,未经允许请勿转载。若存在违规行为,您可以点击 “举报”。


登录 后发表评论
4条评论
电烙铁爱好者
1楼 · 2026-10-26 19:58:44

这个蠕步步态的思路很清晰——每次抬一条腿另外三条撑地。我之前做的四足用Trot对角步态,调试起来麻烦得多。入门还是蠕步靠谱。

胶佬憨憨
2楼 · 2026-10-26 19:58:44

XL4015调5.5V给舵机供电这个建议太实用了。我之前用USB直接带6个舵机,动不动就重启,折腾了两天才找到原因。

阿强焊点总飞
3楼 · 2026-10-26 19:58:44

请问这个3D打印的蜘蛛框架STL文件在哪里?ShillehTek的页面好像只提到了零件链接,没看到框架文件。

阿伟不emo
4楼 · 2026-10-26 19:58:43

代码里的glide()函数写得挺讲究的,20步插值比直接跳变顺滑多了。不过我试了一下用S3板子,蓝牙SPP确实不行,只能换回原版ESP32。