背景与问题

在现代机器人技术和自动化控制系统中,舵机的应用非常广泛。尤其是在机械臂和多自由度机器人的控制中,舵机的精确控制对于完成复杂的动作至关重要。然而,在实际应用中,舵机数量往往受限于控制系统的物理输入输出接口(I/O口)数量。例如,如果我们需要控制多个舵机(如16个舵机),传统控制方式中的I/O接口往往不够用,导致控制系统的扩展性差,布线复杂,增加了系统的成本和安装难度。

为了解决这一问题,本文介绍了一种基于ESP32微控制器的无线级联舵机控制系统,该系统通过无线通信解决了舵机接口数量不足的困境,提供了更高的灵活性和可扩展性。

创作动机与技术挑战

在传统的舵机控制系统中,舵机的数量通常受限于硬件I/O口的数量。如果需要控制多个舵机,通常需要使用多个微控制器或复杂的信号分配电路。然而,这种方式在实际应用中存在以下几个问题:

  1. I/O口限制:每个舵机控制都需要一个物理I/O口,传统控制器的I/O口数量有限,难以满足多个舵机的控制需求。

  2. 布线复杂:多个舵机需要大量的布线,这不仅增加了安装难度,还可能影响信号的稳定性和可靠性。

  3. 扩展性差:一旦舵机数量增加,传统的控制系统往往很难快速扩展,且成本较高。

为了克服这些问题,本文设计了一种基于ESP32的无线级联舵机控制系统,通过无线通信扩展舵机数量,实现更加灵活的控制方式。

系统设计与原理

1. 核心硬件设计

先放效果图

正面

背面

有需要用到3D封装的可以私信我哦

MCU选型

本设计的核心是基于ESP32微控制器,它内置Wi-Fi功能,支持无线网络通信。通过Wi-Fi,ESP32能够与其他设备进行无线通信,发送和接收控制命令。每个舵机控制模块包含ESP32模块、PWM信号生成电路、供电模块以及与主控制系统通信的模块。

​​​​电源输入​​​

在电源输入方面,按照不同的舵机需求接入对应的电源,适应多电压不同的需求,但是最大电压不能超过12v,因为1117的最大输入电压是12V。

防反接

为了方便我们调试使用ss54设计了防反接功能,当你接反输入电源时候也不会烧毁后级电路。(防止不经意间电源接错了)

电流倒灌

当我们调试自己的功能代码时,考虑到输入电源不同会烧毁我们电脑的usb口所以使用一个ss54防止电路倒灌问题。

TYPEC自动下载电路

这个自动下载电路现在很常见这里不过多介绍

  • 内置时钟:CH340C 相比 CH340G 最大的优势是内置了时钟振荡器,因此不需要外接晶振电路,大大简化了外围电路,减小了 PCB 面积。
  • 串口连接
    • ESP_TXD <-- CH340_RXD (电脑接收数据)
    • ESP_RXD --> CH340_TXD (电脑发送数据)
  • 利用 CH340C 的 DTRRTS 引脚,通过两个 S8050 NPN 三极管 来自动切换 ESP8266 的启动模式。
  • 电路解析
    • Q3 (ESP_EN 控制):由 RTS 引脚控制。
      • 正常运行:RTS 为高电平,三极管导通,ESP_EN 被拉低,模块复位运行。
      • 下载触发:RTS 为低电平,三极管截止,ESP_EN 由上拉电阻(隐含)维持高电平,模块复位。
    • Q2 (ESP_IO0 控制):由 DTR 引脚控制。
      • 正常运行:DTR 为高电平,三极管导通,ESP_IO0 被拉低?不,这里是为了拉高。实际上电路设计是利用电平翻转,当需要进入下载模式时,DTR 输出低电平,三极管截止,配合电阻网络使得 ESP_IO0 变为低电平
    • 自动化流程
      1. 点击 “下载” 时,电脑软件将 DTR = 低,RTS = 高 → 此时 IO0 = 低,模块进入 烧录模式
      2. 下载完成后,电平翻转 → IO0 = 高,模块自动复位并运行新程序。
  • 电阻 R15/R16:用于上拉 / 下拉,确保三极管截止时引脚处于稳定的高电平状态,防止程序跑飞。

LED指示灯

这里的led是查看开发版是否正常,其中6号引脚的这个可以在功能代码里写状态灯。

OLED

这里预留了oled可以吧对应的信息显示在oled上面。

下载模式

当TYPEC自动下载电路出现问题时候也已通过物理按钮进入下载模式:

操作步骤

  1. 先按住 flash1 按键(此时 GPIO0 被接地,进入下载模式)。
  2. 不要松开 flash1,短暂按一下 reset1 按键(进行复位)。
  3. 松开 reset1 按键。
  4. 最后松开 flash1 按键。

这里还预留了一路用户按钮,方便用户使用

舵机多路控制芯片

1. 芯片核心功能:多路 PWM 信号生成

  • 扩展 IO 能力:ESP8266 自带的硬件 PWM 通道很少,直接控制多路舵机容易冲突或占用大量 CPU 资源。PCA9685 提供了 独立的 16 路 PWM 输出,且每路都有 12 位(4096 级)的精度,完全满足舵机和 LED 调光需求。
  • 硬件独立控制:所有 PWM 信号由芯片内部硬件生成,ESP32 只需通过 I2C 发送指令,释放了单片机的 CPU 占用,使其可以并行处理其他任务(如传感器数据采集)。

这里贴上代码方便小伙伴复刻

#include <Arduino.h>
#include <Wire.h>
#include "Adafruit_PWMServoDriver.h"
#include <WiFi.h>
#include <WebServer.h>

// Wi-Fi 配置
const char* ssid = "ChinaNet-mrVn";
const char* password = "tnt5am23";

// 舵机和按钮配置
#define LED_PIN 6
#define BUTTON_PIN 5
WebServer server(80);

// 舵机驱动配置
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
#define SERVOMIN  150
#define SERVOMAX  600
#define SERVO_FREQ 50

// 将角度转换为脉冲宽度
uint16_t angleToPulse(int angle) {
  return map(angle, 0, 180, SERVOMIN, SERVOMAX);
}

// 处理舵机控制的请求
void handleServoControl() {
  if (server.hasArg("servo") && server.hasArg("angle")) {
    int servoID = server.arg("servo").toInt();
    int angle = server.arg("angle").toInt();
    
    if (servoID >= 0 && servoID < 16) {
      pwm.setPWM(servoID, 0, angleToPulse(angle));  // 控制指定舵机
      server.send(200, "text/plain", "舵机 " + String(servoID) + " 移动到 " + String(angle) + " 度.");
    } else {
      server.send(400, "text/plain", "无效的舵机编号.");
    }
  } else {
    server.send(400, "text/plain", "缺少参数.");
  }
}

// 控制舵机的HTML页面
String htmlPage() {
  String html = "<html><head><meta charset='UTF-8'><style>";
  
  // 页面样式
  html += "body { font-family: Arial, sans-serif; background-color: #f4f4f9; margin: 0; padding: 20px; text-align: center;}";
  html += "h2 { color: #333; font-size: 24px; margin-bottom: 20px; }";
  html += "h3 { font-size: 18px; color: #444; margin: 15px 0; }";
  html += "input[type='range'] { width: 80%; height: 20px; border-radius: 10px; background: #ddd; outline: none; transition: background 0.3s;}";
  html += "input[type='range']:hover { background: #ccc; }";
  html += "span { font-size: 18px; color: #333; font-weight: bold; display: block; margin-top: 10px;}";
  html += ".servo-container { margin-bottom: 30px; padding: 20px; background: #fff; border-radius: 10px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);}";
  html += ".container { display: flex; flex-wrap: wrap; justify-content: center;}";
  html += ".servo-container { flex: 1 1 250px; margin: 10px; }";
  html += "</style></head><body>";
  
  html += "<h2>控制你的机器人手臂</h2><div class='container'>";
  
  // 为每个舵机生成控制滑块
  for (int i = 0; i < 16; i++) {
    html += "<div class='servo-container'>";
    html += "<h3>舵机 " + String(i) + "</h3>";
    html += "<input type='range' id='servo" + String(i) + "' min='0' max='180' value='90' onchange='updateServo(" + String(i) + ")'>";
    html += "<span id='servo" + String(i) + "_value'>90</span>";
    html += "</div>";
  }

  html += "</div><script>";
  
  // JavaScript 用来处理滑块变化并与服务器通信
  html += "function updateServo(servoID) {";
  html += "  var angle = document.getElementById('servo' + servoID).value;";
  html += "  document.getElementById('servo' + servoID + '_value').innerText = angle;";
  html += "  var xhr = new XMLHttpRequest();";
  html += "  xhr.open('GET', '/control?servo=' + servoID + '&angle=' + angle, true);";
  html += "  xhr.send();";
  html += "}";
  
  html += "</script></body></html>";
  return html;
}

// 处理主页请求
void handleRoot() {
  server.send(200, "text/html", htmlPage());
}

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  WiFi.setHostname("Kelen-Robot-Arm");
  Serial.print("设备的 IP 地址: ");
  Serial.println(WiFi.softAPIP());
  
  // I2C 舵机驱动配置
  Wire.begin(19, 20);
  pwm.begin();
  pwm.setOscillatorFrequency(27000000);
  pwm.setPWMFreq(SERVO_FREQ);
  
  // LED 配置
  pinMode(LED_PIN, OUTPUT);
  
  // 按钮配置
  pinMode(BUTTON_PIN, INPUT_PULLUP);  // 内部上拉电阻启用
  
  // 配置路由
  server.on("/", HTTP_GET, handleRoot);
  server.on("/control", HTTP_GET, handleServoControl);
  
  // 启动 HTTP 服务器
  server.begin();
  
  // 将所有舵机初始化到90度
  for (int i = 0; i < 16; i++) {
    pwm.setPWM(i, 0, angleToPulse(90));
  }
}

void loop() {
  server.handleClient();
}

预留MCU多余接口备用

2. 无线级联控制

系统通过Wi-Fi网络实现了无线级联控制。每个舵机控制模块通过无线网络与主控制系统连接,主控制系统可以通过网页或API接口控制每个舵机的角度和状态。通过这种方式,舵机控制不再受到物理I/O口数量的限制,用户可以根据需要扩展舵机数量。

3. 控制命令的发送与接收

控制系统的设计采用HTTP协议或WebSocket协议进行通信。用户可以通过简单的网页界面调整舵机的角度,而系统则通过HTTP请求将控制命令传输给对应的舵机控制模块,舵机模块接收到命令后,生成相应的PWM信号来控制舵机的动作。

4. 系统扩展性与灵活性

每个舵机控制模块可以独立运行并与主控制系统通过Wi-Fi进行通信,最多支持16个舵机的控制。用户可以根据需要调整系统配置,增加或减少舵机控制模块,满足不同规模的应用需求。由于采用无线通信,用户可以简化布线,降低安装和维护的复杂度。

设计优势

  1. 无线扩展性:本设计通过Wi-Fi无线通信实现舵机的控制,突破了传统控制方式中物理接口数量的限制,舵机数量可以根据需要自由扩展。

  2. 简化布线:由于采用了无线控制方式,用户可以减少布线,避免了传统控制方式中大量复杂的电缆连接,提高了系统的可维护性和稳定性。

  3. 高灵活性与可扩展性:每个舵机控制模块可以独立工作,并通过Wi-Fi与主控制系统连接,支持16个舵机的无线控制。系统可以根据实际需要进行灵活调整,满足各种规模的机器人控制需求。

  4. 多舵机同步控制:该系统能够同时控制多个舵机,支持大规模机械臂或多自由度机器人的精确控制,具有广泛的应用前景。

解决的核心问题

本设计的核心创新点在于它通过无线级联的方式解决了舵机接口不足的问题。传统控制方式受限于物理I/O口数量,而无线通信技术使得每个舵机可以通过Wi-Fi进行独立控制,无需占用过多的物理接口,从而大大提高了控制系统的灵活性和扩展性。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐