资讯动态

基于STM32的智能垃圾桶设计:超声波测距与舵机控制的工程实践

发布时间:2026/10/15 6:14:57 来源:尧图企业网站定制
简介嵌入式系统开发中传感器采集与执行器控制的协同设计直接决定设备稳定性。基于STM32的智能垃圾桶项目以超声波测距感知桶内垃圾堆积高度通过硬件定时器PWM驱动舵机开合桶盖是典型的传感器执行器应用。工程实现中需重点处理超声波回波滤波、舵机堵转电流冲击、系统低功耗待机及多电压域供电隔离等问题。该设计不仅适用于课程演示也可扩展至智能家居、办公区等实际场景并通过串口Wi-Fi模块实现容量远程上报。文章从器件选型、代码实现到调试避坑完整呈现一个能连续运行的智能垃圾桶方案。1. 超声波测满就开盖这款“基于 STM32 的智能垃圾桶设计”到底解决什么问题要做“基于 STM32 的智能垃圾桶设计”大多数人第一时间想到的演示逻辑是超声波测距发现桶满了舵机自动掀开盖子喊一声“智能”。但真正把这个题目做成一个能放在宿舍或办公室连续跑一周的装置你会发现难点根本不在测距和开盖而在三个地方超声波会不会误报、舵机堵转会不会把整板拉复位、电池供电能不能扛住开盖瞬间的电流跌落。设备能演示是一回事能用的智能垃圾桶是另一回事。这篇文章不是课程设计说明书而是从我把这个题目做了几个版本之后沉淀下来的实操笔记器件怎么选、PWM 怎么配、超声波数据怎么滤波、低功耗怎么进、供电坑怎么避、调试顺序怎么排。适合正在做电子设计课程项目的学生也适合想把这个题目往物联网方向扩展的开发者。如果你也希望自己的智能垃圾桶不只在答辩时能动而是真能摆在角落连续工作下面的内容应该能帮你少走我走过的弯路。2. 系统拆分与器件选型把智能垃圾桶拆成“感知-控制-执行-供电”四块2.1 感知层超声波测距和人体感应怎么配合“智能垃圾桶”这个名字听起来宽泛落到传感器层面核心感知任务只有两个测量桶内垃圾堆积高度、检测是否有人靠近。前者我用超声波测距模块安装在桶盖内侧朝下通过测量探头到垃圾表面的距离来推算剩余容量后者用人体感应或红外避障模块安装在桶正面检测来人后自动开盖。两个传感器配合才能构成“人来了开盖、垃圾满了提醒”的基本产品逻辑。关于超声波的安装位置常见做法是放在盖子内侧中心但要稍微倾斜一点角度不要正对桶底。如果正对桶底当垃圾袋蓬松且反光时回波会非常杂乱倾斜 5 到 15 度可以让回波打在桶壁或垃圾侧面稳定性明显更好。测距频率也不要拉满每 200ms 触发一次足够连续触发反而会因为余振互相干扰出现距离跳变。人体感应模块的选型要分场景红外对管式的小模块响应快、成本低但只能检测固定距离的遮挡适合桶前有人站着的情况。热释电人体感应模块能检测移动的人体感应范围呈扇形但上电前几十秒会有自检误触发而且对静止站在桶前的人不敏感。我的建议是如果只是课程演示用红外避障模块最简单如果想让体验更接近真实产品用热释电模块并做好延时屏蔽。2.2 控制与执行STM32 主控与舵机怎么选控制核心我选 STM32F103C8T672MHz 主频、64KB Flash、20KB RAM跑超声波测距、舵机控制、OLED 显示加一个简单状态机绰绰有余。很多人问要不要上 F4 系列完全没有必要这个题目最吃资源的反而是你写的软件逻辑不是算力。真正要注意的是引脚分配PWM 输出、超声波 Trig/Echo、OLED I2C、按键和串口调试这些引脚不要互相占用同一路定时器的冲突通道这点第 5 章会专门讲。执行机构是舵机最常见的是 SG90 系列的 180 度舵机扭矩在 1.8kg/cm 左右带动普通塑料垃圾桶盖够用。但如果你用的是带提手的金属盖或者桶盖又厚又重SG90 会在开启过程中堵转。我一般会直接换扭矩更大的 MG90S 或 MG996R代价是堵转电流从几百毫安升到接近 1A供电方案要跟着改。选型时有一个容易被忽略的维度不是角度越大越好开盖 45 度左右就能方便投递角度越大舵机负荷越高堵转概率越大。舵机控制必须走硬件定时器 PWM不能靠 GPIO 延时翻转。原因很简单主循环里还有超声波测距、OLED 刷新、按键扫描任何一个函数耗时超过几毫秒软件模拟的 PWM 就会被切成一段一段舵机表现为抽搐、抖动、力量不足。用定时器输出了 PWMCPU 就完全不用管波形只要改比较寄存器就能平滑改变角度。器件关键参数选型注意点STM32F103C8T672MHz / 64KB Flash / 20KB RAM资源富余重点是引脚别冲突超声波测距模块2cm~4m5V 供电盲区 2cm探头别正对桶底SG90 / MG90S 舵机5V0~180 度堵转电流 0.3~1A金属盖请直接上 MG90SOLED 0.96 寸 SSD1306I2C3.3V/5V 版本都有确认模块是否自带稳压影响供电设计2.3 供电与电平3.3V MCU 和 5V 传感器混接这个项目的器件电压不统一STM32 是 3.3V超声波模块和舵机是 5VOLED 模块有 3.3V 和 5V 两个版本。混接最容易出问题的是超声波模块的 Echo 回波引脚它输出的是 5V 高电平直接灌进 STM32 的 3.3V GPIO 是冒险行为。有些引脚标注“5V 容忍”但你不该去赌每一个引脚都容忍更稳妥的做法是用两个电阻分压把 5V 降到 3.3V 以下再接进去。Trig 引脚方向相反是 STM32 输出 3.3V 驱动模块一般能直接驱动。供电拓扑上常见做法是单节锂电池升压到 5V再用 LDO 降到 3.3V 给 MCU。升压模块要选能持续输出 1A 以上的便宜的小模块在舵机启动时会瞬间拉垮5V 电压掉到 4.5V 以下接着 3.3V 也跟着跌落ST官方上电复位阈值一旦被触发MCU 就重启了。我的习惯是 5V 总线给舵机和超声波模块3.3V 单独给 MCU 和 OLED两边只共地不共用输出回路。如果实在想省一路电源至少在舵机电源端并联一个 470uF 电解电容再串一个低压差 LDO这样开盖瞬间的浪涌不会被 MCU 感知。3. 从裸机到跑通最小工程、主循环与舵机开盖代码3.1 初始化与串口调试GPIO、定时器、串口第一步不是写逻辑而是把每个外设跑起来并且把数据打出来。我用 CubeMX 生成工程引脚分配固定下来TIM2_CH1 输出 PWM 给舵机超声波 Trig 和 Echo 各占一个 GPIOOLED 走 I2CUSART1 接串口调试。这样安排的目的是让超声波测量和舵机 PWM 不共用同一个定时器从根源上避免资源冲突。主循环先用最简单的逻辑跑通“测距-打印-开盖”这个过程不要一上来就上状态机。测到的距离值通过串口打到上位机标定空桶距离和满桶阈值这是后面所有判断的基础。很多人跳过了标定这步直接凭感觉写阈值结果垃圾桶在还剩三分之一时就疯狂开盖。串口调试在这个阶段比 OLED 有用得多因为 OLED 只能显示结果串口能让你看到每一次测距的原始值。int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART1_UART_Init(); MX_TIM2_Init(); // 使能 DWT 计数器用于微秒级延时和超声波回波计时 CoreDebug-DEMCR | CoreDebug_DEMCR_TRCENA_Msk; DWT-CTRL | DWT_CTRL_CYCCNTENA_Msk; DWT-CYCCNT 0; uint16_t boot_dist distance_filt(); printf(boot dist%d cm\r\n, boot_dist); // printf 重定向到串口1 while (1) { if (is_full()) { lid_open_graceful(); HAL_Delay(2000); lid_close_graceful(); } HAL_Delay(200); } }这个主循环刻意做得很简它验证的是“测距、滤波、舵机动作”三段都能工作而不是最终逻辑。要知道distance_filt()和is_full()的具体实现见 3.3 节lid_open_graceful()见 3.2 节。第一次上电时 boot_dist 打印出的值就是你的空桶基准把它记录下来。3.2 用 PWM 控制舵机频率、占空比和缓冲舵机 PWM 的配置是整个项目里最需要较真的参数。SG90 要求 50Hz 的 PWM 信号也就是 20ms 周期。在 72MHz 时钟下我把 TIM2 预分频设为 71计数时钟变成 1MHz一个计数值正好是 1us周期寄存器 ARR 设为 19999这样 PWM 周期就是 20000us也就是 20ms。接下来只要改比较寄存器 CCR单位就是微秒和舵机数据手册里的脉宽单位完全一致。SG90 的 0 度对应脉宽 0.5ms180 度对应 2.5ms这是最常见的一组规格。要注意不是所有舵机都这个范围有些是 1ms 到 2ms装上前先用手头舵机标定一次。舵机转到极限位置后会继续憋力堵转电流急剧上升所以角度上下限不要硬顶到 0 和 180留出一点余量更安全。void lid_set_angle(uint16_t angle) // angle: 0~180 { // 0.5ms~2.5ms 映射到 0~180 度 uint16_t ccr 500 (uint16_t)angle * 2000 / 180; __HAL_TIM_SET_COMPARE(htim2, TIM_CHANNEL_1, ccr); } void lid_transit(uint16_t from, uint16_t to) { // 每次只走 5 度延时 20ms让舵机平稳转过去 if (to from) { for (uint16_t a from; a to; a 5) { lid_set_angle(a); HAL_Delay(20); } } else { for (uint16_t a from; a to; a - 5) { lid_set_angle(a); HAL_Delay(20); } } } void lid_open_graceful(void) { lid_transit(0, 45); // 45 度就够打开口径不必硬顶 90 度 }直接从一个角度跳到另一个角度舵机会甩头瞬间电流也大。分段步进相当于软件软启动每次只挪 5 度舵机电流平稳很多。开盖角度限制在 45 度而不是 90 度是我在连续堵转两次之后改的桶盖开 45 度已经能扔进垃圾90 度反而让舵机处于接近极限的位置一旦盖子边缘卡住垃圾袋堵转风险很高。3.3 满桶判定与防溢出超声波中值滤波和连续阈值超声波测距的原始数据很脏尤其是在垃圾桶这种场景里垃圾表面是塑料袋、纸团、易拉罐反射乱七八糟单次测距经常出现上下 10cm 的跳变。直接用单次距离做满桶判断垃圾桶会在没人碰它的时候自己开盖。常见做法是取连续 5 次测量值的中位数再连续累计 3 次低于阈值才算满桶这样既滤掉了瞬时噪声又避免了垃圾投递瞬间的距离波动。void delay_us(uint32_t us) { uint32_t start DWT-CYCCNT; uint32_t ticks us * (SystemCoreClock / 1000000); while ((DWT-CYCCNT - start) ticks); } uint16_t hcsr04_measure(void) { // 触发超声波Trig 拉高至少 10us HAL_GPIO_WritePin(TRIG_GPIO_Port, TRIG_Pin, GPIO_PIN_SET); delay_us(12); HAL_GPIO_WritePin(TRIG_GPIO_Port, TRIG_Pin, GPIO_PIN_RESET); // 等待 Echo 上升沿超时 30ms 防止死等 uint32_t timeout 0; while (HAL_GPIO_ReadPin(ECHO_GPIO_Port, ECHO_Pin) GPIO_PIN_RESET) { delay_us(1); if (timeout 30000) return 999; } // 用 DWT 记录 Echo 高电平时间不占用定时器 uint32_t start DWT-CYCCNT; timeout 0; while (HAL_GPIO_ReadPin(ECHO_GPIO_Port, ECHO_Pin) GPIO_PIN_SET) { delay_us(1); if (timeout 30000) return 999; } uint32_t elapsed_us (DWT-CYCCNT - start) / (SystemCoreClock / 1000000); return (uint16_t)(elapsed_us / 58); // 58us 对应 1cm 的往返时间 } #define SAMPLE_CNT 5 #define FULL_THRESHOLD_CM 15 uint16_t distance_filt(void) { uint16_t buf[SAMPLE_CNT]; for (int i 0; i SAMPLE_CNT; i) { buf[i] hcsr04_measure(); HAL_Delay(20); } // 冒泡排序取中值干掉最大最小跳变 for (int i 0; i SAMPLE_CNT - 1; i) { for (int j i 1; j SAMPLE_CNT; j) { if (buf[j] buf[i]) { uint16_t t buf[i]; buf[i] buf[j]; buf[j] t; } } } return buf[SAMPLE_CNT / 2]; } uint8_t is_full(void) { static uint8_t full_cnt 0; if (distance_filt() FULL_THRESHOLD_CM) full_cnt; else full_cnt 0; return full_cnt 3; // 连续 3 次低于阈值才判满 }这里有几个参数你要根据实际桶去调FULL_THRESHOLD_CM 是满桶阈值空桶距离 40cm 的桶我一般设 15 到 18连续判满次数设为 3 到 4 比较合适太少不抗干扰太多会导致垃圾已经满了还不反应。注意 HC-SR04 有 2cm 盲区垃圾满到贴住探头时测距值会变成 0 或 999所以满桶判定不能光看小于阈值还要把 0 和 999 当成有效值处理。4. 让垃圾桶更像产品OLED 显示、低功耗待机与按键互锁4.1 OLED 显示容量百分比测距值本身没有直觉意义显示“剩余 72%”比显示“当前距离 28cm”友好得多。百分比计算需要标定两个基准空桶距离和满桶距离。公式很简单percent (当前距离 - 满桶距离) / (空桶距离 - 满桶距离) * 100然后钳位到 0 到 100。空桶距离就是 3.1 节 boot_dist 打印出来的值满桶距离就是你满桶阈值。显示更新的频率要克制。OLED 全屏刷新一次要几十毫秒如果每 200ms 刷一次主循环大部分时间都耗在 I2C 传输上舵机虽然不受影响但按键响应会变迟钝。我一般把显示刷新放到 1 秒一次的定时任务里而且只在百分比和上次显示的差值大于 2% 时才刷新日常放桶时屏幕基本静止只有投垃圾时数字才跳动视觉效果也更稳。uint8_t get_capacity_percent(void) { uint16_t dist distance_filt(); int p (int)(dist - FULL_THRESHOLD_CM) * 100 / (EMPTY_DIST_CM - FULL_THRESHOLD_CM); if (p 0) p 0; if (p 100) p 100; return (uint8_t)p; } void display_capacity(uint8_t percent) { char line[16]; sprintf(line, Cap:%3d%%, percent); OLED_Clear(); OLED_ShowString(0, 0, line, 1); OLED_Refresh(); }注意 sprintf 在单片机里会吃掉不少 Flash如果工程空间紧张可以自己拼字符串先取百分比的百位、十位、个位再写入显示缓冲区。OLED 上电后要发初始化序列如果你的模块是从 5V 供电的确认模块上自带 3.3V 稳压否则 I2C 电平会被拉到 5VSTM32 的引脚不一定扛得住。4.2 低功耗Stop 模式与外部中断唤醒智能垃圾桶如果插着 USB 供电低功耗无所谓但只要用电池功耗就是大问题。传感器、舵机、OLED 都在闲着的时候耗电而垃圾桶一天真正被使用的次数可能只有几十次。常见做法是让系统大部分时间进 Stop 模式只留外部中断待命等人靠近或按键按下时唤醒。进入 Stop 模式的代码很短但有几个容易被忽略的步骤。先挂起 SysTick否则唤醒后 HAL_Delay 的时间基准是乱的进入 Stop 前要把串口和 OLED 停掉既省电又能避免唤醒后外设状态不一致。唤醒后的第一件事不是测距而是重新配置时钟因为 Stop 模式下系统时钟已经停了。void enter_stop_mode(void) { HAL_SuspendTick(); // 暂停系统滴答防止唤醒后延时错乱 OLED_DisplayOff(); HAL_UART_DeInit(huart1); HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); // 唤醒后恢复时钟和串口 SystemClock_Config(); HAL_UART_Init(huart1); OLED_DisplayOn(); HAL_ResumeTick(); // 给外部中断源的稳定留时间避免醒来立刻再睡 HAL_Delay(50); }唤醒源我用的是人体感应模块的输出引脚配置成外部中断上升沿唤醒。这里有个坑热释电人体感应模块上电后会自检 30 到 60 秒期间会输出好几次高电平如果程序一上电就进入 Stop 模式模块自检的高电平会立刻把系统唤醒然后陷入“睡-醒-睡-醒”的死循环。解决方法是上电后先让系统正常运行 60 秒再考虑进 Stop或者用按键作为唯一唤醒源。真正要低功耗光靠 MCU 进 Stop 不够。OLED 在 Stop 模式下如果还通着电它会从电源轨上继续抽流所以要加一个 MOS 管把 OLED 的 VCC 切掉。这个细节做到位整机待机电流能从几十毫安降到一两毫安电池供电才有实际意义。4.3 按键互锁手动开盖优先自动关盖等一拍加了自动开盖后最容易出现的问题是逻辑打架垃圾还没满用户按按键手动开盖扔垃圾此时超声波突然测到一个瞬时短距离判断“满了”系统自动关盖把用户的手或垃圾夹在半空。这种问题靠零散的 if 判断永远修不完正确做法是引入一个简单的状态机把桶盖的行为限制在几个明确状态里。状态一共四五个就够了盖子关闭、自动开盖后等待、手动开盖、关盖延时。每次按键或测距事件进来先看当前在哪个状态再决定要不要响应。手动开盖状态下自动关盖的触发条件被屏蔽自动开盖状态下如果桶还是满的就一直开着等人把垃圾压实或拿走后再关。这个状态机写起来不复杂却把整个项目的行为从“乱七八糟的 if”里解放了出来。typedef enum { LID_CLOSED, LID_AUTO_OPENED, LID_MANUAL_OPENED } lid_state_t; lid_state_t lid_state LID_CLOSED; void lid_state_machine(void) { uint8_t btn HAL_GPIO_ReadPin(BTN_Port, BTN_Pin); switch (lid_state) { case LID_CLOSED: if (btn PRESSED) // 手动开盖优先 { lid_open_graceful(); lid_state LID_MANUAL_OPENED; } else if (is_full()) // 自动满桶检测 { lid_open_graceful(); lid_state LID_AUTO_OPENED; } break; case LID_AUTO_OPENED: HAL_Delay(2500); // 给人留出投递时间 if (!is_full()) // 桶又能装了才关 { lid_close_graceful(); lid_state LID_CLOSED; } break; case LID_MANUAL_OPENED: if (btn RELEASED) { lid_close_graceful(); lid_state LID_CLOSED; } break; } }我在状态机里特意让自动开盖后至少等 2.5 秒再判断是否关闭而不是测到距离恢复就立刻关。原因是垃圾投进去的瞬间超声波会测到一个明显波动如果此时立刻判断并关盖盖子大概率会夹在正在回弹的袋子上。等一拍再判断既给用户时间也给传感器时间这是我调试中觉得很值得的一个延时。5. 调试与避坑超声波回波抖动、舵机堵转、电池电压跌落四条血泪排查记录5.1 空桶误报满桶超声波隔着桶壁测到了地面现象垃圾桶刚通电OLED 显示“容量 0%”盖子自动打开但桶里是空的。串口打印的距离值不是桶深 40cm而是时不时跳到 100 多厘米超过阈值。原因超声波探头正对桶底空桶时回波很强但桶口边缘或桶壁结构产生了多次反射回波绕射到了桶外桌面或地面测距值变成 100cm 以上的杂波。另一个常见原因是从 Stop 模式唤醒后第一次触发模块内部还没稳定测出 0cm也被当成了有效值。解决把探头安装位置从桶盖中心改成偏置并朝桶底方向倾斜 10 度左右让主回波打在桶壁上而不是桶外。软件上增加“上电 500ms 内不测距”的延时唤醒后第一帧测距结果直接丢弃。在 distance_filt 的入口处加一个合理性校验测距值大于桶深 1.5 倍或等于 0、999 时直接返回上一次有效距离。5.2 舵机堵转把整板拉复位现象盖子开到某个角度后卡住紧接着 OLED 黑屏整板重启串口重新打印 boot dist。重启频率和舵机卡住的位置强相关盖子越重越容易触发。原因舵机堵转瞬间电流达到 800mA 到 1A 以上如果舵机电源和 MCU 共用同一路 LDO 或同一路升压输出5V 电压会被拉出很大的跌落3.3V 也跟着掉到 STM32 上电复位阈值以下。我的第一版就是把 5V 升压后同时给舵机和 LDO结果每次堵转都是硬复位。解决舵机电源独立供电至少做到“共地不共源”。5V 总线直接给舵机3.3V 通过低压差 LDO 单独给 MCU并在舵机电源端并联 470uF 电解电容加 100nF 瓷片电容。同时软件层把开盖角度上限从 90 度降到了 45 度配合 5 度步进缓冲堵转电流冲击减小很多。5.3 OLED 刷新时舵机抽搐超声波偶尔测出 0现象OLED 每刷新一次舵机就轻微抖一下超声波测距值在 OLED 刷新后紧接着的一两次测量中明显异常。原因我用软件模拟 I2C 驱动 OLED刷新过程中关闭了全局中断如果此时恰好 Echo 引脚正在输出高电平测距的计时就被打断了。于是出现了两个连锁问题舵机 PWM 虽然由硬件定时器输出但 CPU 关中断时间过长个别周期的比较值更新被延迟舵机就抖超声波计时用的是同一个定时器的输入捕获中断被关后计数混乱测距值自然错乱。解决把超声波回波计时从定时器输入捕获改成 DWT-CYCCNT 计数器DWT 是内核调试单元自带的 32 位计数器不受外设定时器占用影响。OLED 刷新改成硬件 I2C并避免在 Echo 高电平期间进入长临界区。改完以后OLED 正常刷新舵机纹丝不动超声波也不再跟着“抽搐”了。5.4 电池供电时一开盖 OLED 就变暗甚至黑屏现象USB 供电时一切正常换成锂电池升压供电后每次舵机开始转动时 OLED 屏幕亮度明显下降严重的直接黑屏几个毫秒然后又恢复。原因电池本身有内阻升压模块瞬间响应不够快舵机启动瞬间拉低了 5V 总线电压OLED 模块上的 3.3V 稳压器输入电压掉到压差以下输出就跟着塌了。单独看 5V 波形只掉到 4.5V似乎还能接受但 AMS1117 这类常规 LDO 需要 1V 以上的压差输入 4.5V 时输出已经不到 3.3V 了。解决把舵机电源主线从模块的细导线换成粗线缩短到舵机的距离在舵机电源端并联一个大电解电容把瞬时峰值电流先扛住3.3V 改用低压差 LDO。如果还不行就把升压模块的输出调到 5.2V 到 5.5V给 LDO 留出足够的压差余量。这个现象排查了很久最后发现不是哪一处的问题而是线阻、升压响应、LDO 压差三个因素叠加。6. 进阶玩法加个串口 Wi-Fi 模块把余量上报证明你的设计能跑更远本地显示加自动开盖已经是一个完整课设但距离“智能”还差一步数据不能离开垃圾桶。最常见的扩展方式是给 STM32 加一个串口 Wi-Fi 模块把容量百分比通过局域网实时上报这样你坐在工位上就能看到宿舍的垃圾桶是不是该倒了。有人会直接上 NB-IoT 或者 4G 模块对垃圾桶这种低频上报场景来说成本和功耗都浪费一个串口透传模块就足够了。接入方案我一般这样搭STM32 的 USART2 接 Wi-Fi 模块通过 AT 指令让它连接路由器和远端数据接口主循环每 30 秒测一次容量拼成一个自定义协议帧发出去。发送的格式不需要严格 JSON但最好包含设备 ID方便以后多个垃圾桶区分。void report_capacity(uint8_t percent) { char frame[32]; int len sprintf(frame, id1,cap%d\r\n, (int)percent); HAL_UART_Transmit(huart2, (uint8_t *)frame, len, 200); }接入互联网之后你会发现真正的坑不在上报代码而在 AT 指令握手。模块上电后不一定立刻进入透传状态你要发 AT 等它回 OK 再往下走如果你发完指令就死等应答模块没响应时整个系统会卡住。常见做法是给每个 AT 等待加上超时比如用 HAL_UART_Receive 最多等 500ms超时直接重发。很多人在这上面翻车不是模块坏了而是串口接收没有超时机制。如果想把功耗和联网都做好可以用串口 Wi-Fi 模块的“深度睡眠”模式让 STM32 在进 Stop 之前先发一条指令让模块睡觉唤醒后先发唤醒指令再工作。这样一来整机的平均功耗才会真正降下来电池续航能到周级别。我自己的体会是做这个题目最容易陷入的误区是把时间花在花哨的显示界面上最后发现稳定性才是能不能长期开机使用的关键。现在再让我从头做一遍我会先把供电和超声波标定做扎实再考虑 OLED 动画和联网而不是反过来。希望这个项目的拆解和踩坑记录对你有帮助。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑