你们宿舍谁关灯?——SG90 舵机是怎么工作的

让宿舍实现「关灯自由」的是开关上那颗 5 块钱的 SG90 舵机。它不是普通电机,而是一个自带反馈的小闭环系统:单片机每 20 毫秒发一个脉冲,脉冲有多宽,它就转到哪个角度;转到位后电位器把角度变成电压回传,芯片比较后自动纠偏。

原笔记引用的 1 张配图目前未提供;此页保留文字与来源,涉及图示的段落需对照原文阅读。

版本与验证范围

收藏整理,原作者与来源见正文;不作为 Lan 的原创项目或实测结论。

来源:抖音视频 · 立创商城 · 约 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 只有这一根是信号线

三条最容易出事的:

  1. 供电容量按手上舵机和负载确认。 舵机启动或受阻时电流会明显上升,不能凭扭矩猜电流;优先查具体规格书或实测。供电能力不足可能导致复位、抖动或发热。
  2. GND 一定要共地。 电源地和单片机地不连在一起,信号没有回路,表现为不转或乱抖。
  3. 先确认线序再上电。 不同厂家的配色会变(也有黑-红-白),以你手上那颗的实际标签为准。

5. 怎么用代码打脉宽

Arduino(用 writeMicroseconds 比 write(角度) 更可控):

cpp
#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 通道;以下片段不能单独直接运行。

c
// 目标:周期 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 内核版本和实际引脚。

cpp
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
资料性质
工程笔记。原文的版本、来源与验证边界继续保留。
返回文章目录

想去哪里?

22 个入口

首页作品作品展厅全部项目文章总览文件夹标签资料归档关于认识 Lan探索路线工具与工作台最近在做InkFeed · 4.2 英寸电子纸信息终端VIBRATION · 柔性振动检测与采集链路TRACE · 航向保持与灰度循迹小车STRIDE · 八自由度四足机器人SCOPE · 固件日志浏览器温度为什么被 AI 改了?FIFO 有半帧,就一定是故障吗?直线守航向,弧线再看黑线。

Tab 选择入口 · Enter 打开 · Esc 关闭