来源:抖音视频 · 立创商城 · 约 37 秒 · 作品 ID 7697201553719053583
让宿舍实现「关灯自由」的是开关上那颗 5 块钱的 SG90 舵机。它不是普通电机,而是一个自带反馈的小闭环系统:单片机每 20 毫秒发一个脉冲,脉冲有多宽,它就转到哪个角度;转到位后电位器把角度变成电压回传,芯片比较后自动纠偏。
视频只讲了原理(约 37 秒)。下面的接线、代码、安装和安全部分是我按公开资料补的通用做法,已分别标注,不要把补充内容当成视频里说过。
1. 视频回答的几个问题
| 视频里的问题 | 答案(视频的说法) |
|---|---|
| 它凭什么能当「义父」? | 开关上装了一颗 5 块钱的 SG90 舵机,替你下床拨开关 |
| 它里面有什么? | 电机 + 减速齿轮 + 电位器 + 控制芯片 |
| 它怎么知道转到哪该停? | 单片机每 20 ms 发一个脉冲,脉冲宽度决定转到哪儿 |
| 转过去以后怎么不跑偏? | 电位器跟着转,把角度变成电压反馈给芯片,芯片自动纠偏 |
2. 拆开看:四个零件各干一件事
| 零件 | 干什么 | 可以怎么理解 |
|---|---|---|
| 直流电机 | 提供动力 | 只会转,不知道转了多少 |
| 减速齿轮 | 降速、增力 | 转得慢一点,但劲儿大一点 |
| 电位器 | 把角度变成电压 | 相当于一直盯着「现在转到哪了」 |
| 控制芯片 | 比较目标与当前,有误差就转 | 相当于大脑,负责纠偏 |
闭合的一圈是这样的: 单片机给目标脉宽 → 芯片驱动 电机 → 减速齿轮 → 输出轴转动 → 带动 电位器 → 电位器电压回到芯片 → 芯片发现没到就继续转,到了就停。
所以舵机和普通直流电机的根本区别是:你给的不是一个「转/不转」,而是一个「转到多少度」,剩下的它自己闭环完成。视频里说的「自动纠偏」就是这个环在起作用——外力把它掰偏了,它会自己转回来。
3. 关键:脉宽决定角度
此处配图暂缺,参阅原帖。
| 脉宽示例 | 帮助理解 |
|---|---|
| 1.0 ms | 通常偏向一侧,具体角度需实测 |
| 1.5 ms | 通常接近中位,不保证一定是 90° |
| 2.0 ms | 通常偏向另一侧,具体角度需实测 |
视频提到 1.5 ms 为中位;1.0、2.0 ms 只是常见示例,不是每颗舵机的角度或安全端点。不同型号及机构的行程和映射都可能不同。先查手上舵机规格,以中位小幅移动,逐步标定并避开机械限位。参考 M5Stack SG90 资料。
图中使用 20 ms 作为常见周期。舵机主要根据高电平持续时间判断目标位置,允许的刷新周期和信号电平要看具体型号。
4. 接线:三根线,两件事最容易错
| 线色 | 接哪里 | 说明 |
|---|---|---|
| 红 | 外部 5 V 正极 | 示例资料为 4.8–6.0 V;实际以手上型号为准 |
| 棕 / 黑 | GND | 必须和单片机共地 |
| 橙 / 黄 | 单片机 GPIO | 只有这一根是信号线 |
三条最容易出事的:
- 供电容量按手上舵机和负载确认。 舵机启动或受阻时电流会明显上升,不能凭扭矩猜电流;优先查具体规格书或实测。供电能力不足可能导致复位、抖动或发热。
- GND 一定要共地。 电源地和单片机地不连在一起,信号没有回路,表现为不转或乱抖。
- 先确认线序再上电。 不同厂家的配色会变(也有黑-红-白),以你手上那颗的实际标签为准。
5. 怎么用代码打脉宽
Arduino(用 writeMicroseconds 比 write(角度) 更可控):
#include <Servo.h>
Servo s;
void setup() { s.attach(9); } // 信号线接 9 号脚
void loop() {
s.writeMicroseconds(1500); // 1.5 ms → 中位
delay(1000);
s.writeMicroseconds(2000); // 2.0 ms → 拨向一端
delay(1000);
}
Servo.h的默认映射约是 544–2400 µs,所以write(90)出来的不是精确的 1500 µs。要精确就用writeMicroseconds()。
STM32(HAL,示意代码): 需先按实际时钟、引脚复用和定时器配置设置 PSC、GPIO 和 PWM 通道;以下片段不能单独直接运行。
// 目标:周期 20 ms(50 Hz),脉宽用微秒直接写
// TIM 计数时钟 = 1 MHz → 1 个计数 = 1 µs
// PSC = TIM_CLK / 1MHz - 1 例:72 MHz 时 PSC = 71
// ARR = 19999 例:20 ms / 1 µs - 1
// CCR = 脉宽(µs) 例:1500 → 1.5 ms
__HAL_TIM_SET_AUTORELOAD(&htim3, 19999);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 1500); // 1500 µs
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
ESP32(Arduino-ESP32 旧版 LEDC API 示例): 这不是 ESP-IDF 代码,使用前先核对安装的 Arduino 内核版本和实际引脚。
const int ch = 0, pin = 18;
ledcSetup(ch, 50, 16); // 50 Hz,16 位分辨率
ledcAttachPin(pin, ch);
// 通用换算:duty = 脉宽(µs) × 65536 / 20000
ledcWrite(ch, (uint32_t)(1500.0 * 65536 / 20000)); // ≈ 4915 → 1.5 ms
ESP32 的 LEDC API 在不同内核版本里名字不一样(新版是
ledcAttach/ledcWriteChannel),按你装的版本的示例改一下即可。
6. 真装到宿舍开关上:先看机械和安全
视频没有讲安装,这部分是补充的通用注意事项:
- 只在外面拨,不要拆 220 V 开关面板。 面板内部是市电带电部分,拆开操作有触电风险;这个项目应该是在面板外部用舵机推拉翘板,不碰接线。
- 固定要牢。 舵机发力时反作用力会把自身顶开,用支架、扎带或强力双面胶固定,并留出摆臂行程余量,不要让摆臂顶死在机械限位上。
- 别让它长期堵转。 扭矩不够或卡住时会持续大电流,导致发热甚至烧毁;行程两端要留余量。
- 先确认宿舍管理规定。 「宿舍神器」类改造在很多学校属于违规用电/改造,别为了关灯被通报。
7. 出问题怎么排查
| 现象 | 先查什么 |
|---|---|
| 完全不动 | 线序、是否共地、GPIO 是否真的在输出、电源电压够不够 |
| 抖动 / 嗡嗡响 | 脉宽顶到机械限位了(往 1.0–2.0 ms 收)、供电电流不足、信号线受干扰 |
| 角度不准 | 检查实际脉宽并逐颗标定;不同批次的中位和行程会有差异 |
| 一转就复位 / 单片机重启 | 供电被拉垮,舵机改独立电源 |
| 发热、有糊味 | 立即断电;多半是堵转或长时间顶住限位 |
| 齿轮咔咔响 | 已经扫齿,塑料齿轮一旦打滑基本只能换 |
8. 和你手头项目的关系
你的四足机器人也涉及舵机控制,但型号与 SG90 不同;下面是需要结合 MF168 资料确认的通用思路:
- 你的当前方案是 8 个 MF168 舵机。 舵机电源与逻辑供电的分配、电压及电源容量应按 MF168 官方资料和实际测量确定;电源地与信号参考地的连接也应按实际系统设计。这里的 SG90 参数不能套用到 MF168。
- 角度标定要实测。 逐颗记录中位和安全行程;你的方案使用 PCA9685 时,按实际驱动代码配置脉宽,不照搬 Arduino
writeMicroseconds示例。 - 行程留余量。 腿足机构最容易顶到限位,顶死就是持续大电流 + 发热。
- PCA9685 可以统一产生多路 PWM 信号。 它不提供舵机位置反馈,也不保证比单片机定时器更高精度;频率和脉宽仍按实际舵机确定。
以上是我给的通用建议,不是对你现有机器人做的实测结论。
来源与关联索引
- 来源
- 个人知识库
- 原笔记
- 抖音收藏待整理/009-宿舍关灯神器与SG90舵机原理.md
- 资料性质
- 工程笔记。原文的版本、来源与验证边界继续保留。