Arduino睡眠模式实战:从原理到应用,打造超低功耗物联网节点
1. 项目缘起为什么我们需要让Arduino“睡觉”如果你玩过Arduino尤其是用电池供电的项目比如户外气象站、无线传感器节点或者一个需要跑上几个月的智能花盆那你肯定遇到过最头疼的问题电池怎么这么快就没电了我最初做的一个土壤湿度监测器用两节五号电池理想中能撑一个季度结果不到两周就歇菜了。拆开一看核心板上的电源指示灯还在那倔强地亮着仿佛在嘲笑我对功耗的一无所知。这就是我们今天要聊的核心Arduino的睡眠模式。它不是一个炫酷的功能而是一个生存技能。对于绝大多数由电池或太阳能等有限能源驱动的嵌入式项目来说让微控制器在“不干活”的时候进入深度睡眠是延长其使用寿命从“天”到“年”的关键跨越。Arduino Uno上那颗经典的ATmega328P芯片在正常全速运行16MHz时电流消耗大概在15-20mA左右。听起来不大但如果你让它24小时不间断工作一块常见的2000mAh的9V电池理论续航也就四五天。而一旦进入最深的睡眠模式它的电流可以降到惊人的0.1μA以下功耗相差了数十万倍。所以“认识与实验Arduino的睡眠模式”这个事本质上是在学习如何给你的项目“节流”让它在该拼命的时候全力输出在该休息的时候彻底“躺平”。这不仅仅是省电更是决定了你的创意能否脱离电源线的束缚真正走向户外、走向长期部署的关键一步。无论你是刚入门的新手还是已经做过几个项目的老玩家只要你的项目有移动或长期无人值守的需求掌握睡眠模式就是你必须点亮的技能树。2. 睡眠模式探秘ATmega328P的几种“睡法”要让Arduino睡觉我们得先了解它的大脑——ATmega328P微控制器提供了哪些“睡眠套餐”。这些模式不是简单的开关而是一系列不同深度的休眠状态深度越深功耗越低但被唤醒的难度和速度也相应变化。Arduino IDE的avr/sleep.h库为我们封装了这些底层硬件功能。2.1 六种睡眠模式详解ATmega328P主要支持六种睡眠模式从浅眠到深眠依次是空闲模式 (Idle Mode)功耗约15mA与运行模式相差不大但CPU和Flash时钟停止。唤醒方式任何中断外部中断、定时器中断、USART、ADC转换完成等。特点这是最浅的睡眠。CPU核心和Flash时钟停止了但系统时钟如定时器、看门狗、ADC仍在运行。它适合需要快速响应、但CPU大部分时间空闲的场景比如等待串口指令。ADC降噪模式 (ADC Noise Reduction Mode)功耗降至约6.5mA。唤醒方式外部中断、看门狗中断、定时器中断、ADC转换完成中断。特点在空闲模式基础上进一步停止了CPU和I/O时钟但保留了ADC的时钟以减少转换时的噪声。顾名思义它适用于需要高精度ADC采样且对功耗有一定要求的间歇性数据采集。掉电模式 (Power-down Mode)功耗可低至0.1μA典型值具体看外设状态。唤醒方式外部中断INT0/INT1的边沿触发、看门狗中断、TWII2C地址匹配中断需提前使能。特点这是最常用、最省电的模式之一。几乎所有时钟都停止了只有异步中断源能唤醒它。你的无线传感器节点、定时唤醒的闹钟基本都靠它。省电模式 (Power-save Mode)功耗与掉电模式类似略高一点。唤醒方式外部中断、看门狗中断、TWI地址匹配中断。关键区别它允许异步定时器2如果使用32.768kHz晶振继续运行。特点它是“掉电模式”的增强版在保持超低功耗的同时还能让Timer2继续工作用于实现精确的长时间定时唤醒比如每小时唤醒一次。如果你的项目需要精准的日历时间这是最佳选择。待机模式 (Standby Mode)功耗约1.5μA。唤醒方式外部中断、看门狗中断。特点主振荡器停止但外部晶体振荡器保持运行。唤醒速度比掉电模式快但功耗也稍高。适用于对唤醒延迟有要求但仍需较低功耗的场景。扩展待机模式 (Extended Standby Mode)功耗与待机模式类似。唤醒方式外部中断、看门狗中断、定时器中断。特点允许异步定时器继续运行是“省电模式”和“待机模式”的折中。对于大多数电池供电项目掉电模式和省电模式是我们的主战场。下面这个表格可以帮你快速决策睡眠模式典型功耗唤醒延迟关键外设是否运行典型应用场景空闲模式~15 mA极快 (几个时钟周期)定时器、看门狗、ADC等等待外部事件需即时响应掉电模式~0.1 μA慢 (需要时钟重启)几乎全部停止电池供电的传感器节点长时间休眠省电模式~0.1 μA慢Timer2 (异步需外接32K晶振)需要精准定时唤醒的长期监测设备ADC降噪~6.5 mA中等ADC高精度、间歇性数据采集注意上述功耗值是芯片内核的理论值。在实际的Arduino Uno板上因为板载的USB转串口芯片如ATmega16U2和电源稳压器LDO存在静态功耗即使MCU进入掉电模式整板电流通常也在5-10mA左右。要实现真正的微安级功耗你需要将MCU从开发板上拆下或使用专门为低功耗设计的板子如Pro Mini并移除电源指示灯LED。2.2 睡眠背后的寄存器SMCR我们通过avr/sleep.h库调用的sleep_mode()等函数底层操作的是一个叫做电源管理及睡眠控制寄存器。这个寄存器很小但权力很大它决定了MCU如何入睡、睡多深。SE睡眠使能位。这是“入睡”的总开关设置为1时执行SLEEP指令后MCU才会进入睡眠。SM2:SM0睡眠模式选择位。这三位二进制数就对应着我们上面提到的六种模式。例如SM[2:0] 0b010代表掉电模式。库函数帮我们封装了这些细节但了解原理有助于你排查一些奇怪的睡眠失效问题。比如如果你在代码中错误地配置了某些中断或者没有正确清除中断标志可能会导致MCU无法进入预期的深度睡眠。3. 实战演练手把手构建一个低功耗温湿度监测节点理论说再多不如动手做一遍。我们来构建一个经典场景一个基于DHT11温湿度传感器和Arduino Uno的监测节点。它每5分钟醒来一次读取数据然后通过串口打印模拟无线发送接着继续沉睡。3.1 硬件连接与功耗考量首先按如下方式连接硬件DHT11的数据引脚接Arduino数字引脚2。Arduino Uno通过USB线连接电脑用于编程和查看串口输出但最终测试功耗时我们会使用外部电源如9V电池或稳压电源。一个至关重要的细节为了测量真实的低功耗电流你需要一个万用表并将其串联在电源正极VIN和板子之间切换到电流档mA或μA档。在Uno板上你可以将跳线帽从VIN插针上取下将万用表表笔连接两端。3.2 核心代码实现与逐行解析我们将使用掉电模式并通过看门狗定时器来定时5分钟唤醒。看门狗定时器是一个独立的时钟源即使在深度睡眠下也能运行是实现长时间定时唤醒的利器。#include avr/sleep.h #include avr/power.h #include avr/wdt.h // 看门狗定时器库 #include DHT.h // 需要安装DHT sensor library #define DHTPIN 2 #define DHTTYPE DHT11 DHT dht(DHTPIN, DHTTYPE); // 看门狗中断服务程序 ISR (WDT_vect) { // 看门狗中断唤醒时这里什么都不用做 // 只需确保中断被触发MCU会从这里继续执行 wdt_disable(); // 重要先禁用看门狗防止它在我们处理数据时再次复位 } void setup() { Serial.begin(9600); dht.begin(); // 最关键的一步在进入睡眠前将所有未使用的引脚设置为输入上拉以最小化功耗 for (int i 0; i 20; i) { // 遍历所有可能的数字引脚 pinMode(i, INPUT_PULLUP); } // 但注意我们使用的DHT引脚2需要保持为输入模式不能上拉因为DHT有自己特定的上拉要求 pinMode(DHTPIN, INPUT); // 设置为输入不启用内部上拉 Serial.println(低功耗温湿度监测节点启动...); } void loop() { // 1. 执行工作任务读取传感器数据 float h dht.readHumidity(); float t dht.readTemperature(); if (isnan(h) || isnan(t)) { Serial.println(读取DHT11失败); } else { Serial.print(湿度: ); Serial.print(h); Serial.print( %\t); Serial.print(温度: ); Serial.print(t); Serial.println( *C); } // 2. 进入睡眠前的准备工作 Serial.println(进入睡眠5分钟后见...); Serial.flush(); // 确保所有串口数据发送完毕 delay(100); // 短暂延时让串口发送完成 // 3. 配置并启动看门狗定时器作为间隔定时器 setup_watchdog(9); // 参数9对应约8秒的定时后面解释 // 4. 配置睡眠模式为掉电模式 set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_enable(); // 使能睡眠功能 // 5. 真正进入睡眠 sleep_mode(); // 程序在此处暂停进入睡眠 // 6. 唤醒后继续执行从看门狗中断返回后会继续执行这里 sleep_disable(); // 首先禁用睡眠模式 // 7. 重新启用可能需要的外设在深度睡眠中某些外设可能被关闭以省电 power_all_enable(); // 启用所有时钟域 } // 配置看门狗定时器中断的函数 void setup_watchdog(int timerPrescaler) { if (timerPrescaler 9) timerPrescaler 9; // 参数范围0-9 byte bb timerPrescaler 7; if (timerPrescaler 7) bb | (1 5); // 设置第5位WDP3 // 清除复位标志配置为中断模式而非复位模式 MCUSR ~(1 WDRF); // 开始配置序列先允许写然后设置预分频值和模式 WDTCSR | (1 WDCE) | (1 WDE); // 设置新的看门狗超时值和中断模式 WDTCSR bb | (1 WDIE); }代码关键点解析引脚配置是省电的灵魂setup()函数中的循环将所有未使用的引脚设置为INPUT_PULLUP。浮空的输入引脚会因感应噪声而产生微小的电流波动将其上拉到VCC或GND可以稳定电平显著降低功耗。这是一个极易被忽略但效果显著的技巧。看门狗定时器作为闹钟我们通常用看门狗防止程序跑飞但这里我们把它改造成了“定时唤醒中断”。setup_watchdog(9)中的参数9对应着看门狗定时器的一个预分频值大约产生8秒的超时周期。我们需要用它来累计5分钟300秒。如何实现5分钟定时代码中只睡了8秒。实际上我们需要在循环中加入一个计数器。例如定义一个全局变量sleepCounter每次看门狗中断唤醒后将其加1当累计到300/8 ≈ 38次时才执行传感器读取和打印任务。否则直接再次进入睡眠。这样可以避免频繁唤醒带来的功耗累积。sleep_mode()的魔力调用这个函数后MCU执行SLEEP指令程序计数器在此暂停。直到一个使能的中断发生MCU被唤醒从中断服务程序ISR返回后程序会紧接着从sleep_mode()之后的那行代码继续执行。中断服务程序ISR要简短在WDT_vect中我们只做了最关键的事——禁用看门狗。中断处理必须快进快出尤其要避免使用delay()或复杂的打印操作。3.3 功耗实测与优化对比将上述代码加入计数器逻辑实现5分钟唤醒上传到Arduino Uno。正常模式功耗注释掉所有睡眠相关的代码让loop()里只有读取传感器和打印然后delay(300000)。用万用表测量整板电流大约在45-50mAMCU约20mA串口芯片约20mA传感器等。睡眠模式功耗未优化引脚使用睡眠代码但去掉setup()中配置未使用引脚为INPUT_PULLUP的循环。测量睡眠时的电流可能在8-12mA左右。这比运行模式低了很多但远高于理论值主要就是浮空引脚和板载LED/LDO的“偷电”。睡眠模式功耗优化后启用引脚上拉配置。测量睡眠电流可以降到5-8mA。这主要是板载稳压器和USB芯片的静态功耗。此时如果你断开USB使用纯净的9V电池通过VIN引脚供电并小心地用电烙铁移除板上的电源指示灯LED睡眠电流有望进一步降至1mA以下甚至达到几百微安级别。这个对比实验清晰地展示了软件优化睡眠模式和硬件优化引脚处理、移除LED对功耗的巨大影响。4. 唤醒机制详解如何优雅地“叫醒”Arduino让Arduino睡着不难难的是如何在正确的时间、用正确的方式把它叫醒。唤醒机制是睡眠模式设计的核心决定了系统的响应性和可靠性。4.1 外部中断唤醒最灵活的“门铃”外部中断唤醒就像给Arduino装了个门铃。当指定的引脚电平发生变化上升沿、下降沿或任意变化时MCU立即被唤醒。// 使用数字引脚2INT0的外部中断唤醒 const int wakeUpPin 2; // 对应INT0 void setup() { pinMode(wakeUpPin, INPUT_PULLUP); // 配置为输入上拉通常连接一个按钮到GND attachInterrupt(digitalPinToInterrupt(wakeUpPin), wakeUp, FALLING); // 当按钮按下引脚变低电平时触发中断 // ... 其他初始化 } void wakeUp() { // 这个函数内容通常为空或者只设置一个标志位 // 例如wakeFlag true; } void loop() { // 进入睡眠 set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_enable(); sleep_mode(); // 唤醒后 sleep_disable(); // 检查是否是按钮唤醒 // if (wakeFlag) { ... } }实操心得防抖动机械按钮在按下时会产生多次电平抖动可能误触发多次中断。一个简单的软件防抖方法是在中断服务程序中delay(50)后再读取引脚状态确认但更好的方法是在硬件上并联一个0.1μF的电容到地。中断引脚有限ATmega328P只有两个外部中断引脚INT0和INT1对应D2和D3。如果需要更多唤醒源可以考虑使用“引脚变化中断”它支持更多的引脚但只能检测电平变化无法区分上升沿或下降沿。4.2 看门狗定时器唤醒最可靠的“闹钟”如前所述看门狗定时器是一个独立的、低功耗的振荡器即使在掉电模式下也能运行。它是实现长时间、周期性唤醒的不二之选。关键参数设置看门狗的超时时间由WDTCSR寄存器的WDP3:WDP0位控制。常见的设置如下表WDP3WDP2WDP1WDP0典型超时时间 (VCC3.3V)典型超时时间 (VCC5.0V)000016 ms16 ms000132 ms32 ms..................01111.0 s1.0 s10002.0 s2.0 s10014.0 s4.0 s10108.0 s8.0 s注意看门狗的超时时间受供电电压和温度影响并非绝对精确。对于需要高精度定时的应用如每小时整点唤醒建议使用外部的实时时钟模块。4.3 其他唤醒源USART串口唤醒在空闲模式下可以通过串口接收到数据来唤醒MCU。这对于需要随时响应上位机指令的设备很有用。模拟比较器中断当模拟比较器的输出状态变化时可以产生中断唤醒。TWII2C地址匹配在掉电或省电模式下如果TWI模块被使能当总线上出现匹配的从机地址时可以唤醒MCU。这在构建I2C传感器网络时非常高效主设备可以随时“呼叫”沉睡的从设备。选择唤醒源的策略定时任务用看门狗周期性的数据采集、心跳包发送。事件触发用外部中断按钮按下、门磁开关触发、振动传感器报警。通信唤醒用串口或I2C设备需要随时响应主机查询。5. 避坑指南睡眠模式实战中常见的“坑”与解决方案在实际项目中让Arduino安稳地睡去并准时醒来总会遇到一些意想不到的问题。下面是我踩过的一些坑和总结的解决方案。5.1 睡眠后无法唤醒或行为异常症状调用sleep_mode()后设备“睡死”按按钮、定时器到点都没反应。排查中断未正确配置或使能这是最常见的原因。确保在sleep_enable()之前你已经用attachInterrupt()或配置了看门狗中断并且全局中断是使能的sei()通常在setup()中默认调用。中断标志未清除某些中断在触发后其标志位需要手动清除。如果不清除MCU可能会在唤醒后立即再次进入中断导致程序逻辑混乱。例如看门狗中断标志是硬件自动清除的但一些外部中断可能需要查询状态寄存器。引脚配置冲突如果你用来唤醒的中断引脚如D2在代码其他地方被意外地写为输出digitalWrite可能会干扰中断触发。确保中断引脚在整个睡眠期间保持为输入模式。5.2 睡眠后功耗仍然居高不下症状测量电流还有几十mA远达不到预期。排查板载外设和指示灯如前所述Arduino Uno板上的电源指示灯ON、串口通信指示灯TX/RX都会消耗电流。对于最终产品考虑使用更精简的开发板如Pro Mini或自制PCB。未使用的模拟引脚浮空的模拟引脚也会漏电。除了数字引脚最好也将未使用的模拟引脚设置为输入上拉pinMode(A0, INPUT_PULLUP)。使能了不必要的外设在进入睡眠前可以使用avr/power.h库关闭不需要的外设时钟。例如power_adc_disable(); // 关闭ADC power_spi_disable(); // 关闭SPI power_timer0_disable(); // 关闭Timer0会影响delay和millis power_timer1_disable(); power_timer2_disable(); power_twi_disable(); // 关闭I2C警告关闭了外设时钟后对应的功能如millis()、delay()、ADC读取、串口将无法使用直到你调用power_xx_enable()重新开启。务必在唤醒后、使用相关功能前重新使能。外部电路漏电检查你连接在Arduino上的传感器、模块。即使它们的VCC断电如果数据引脚直接连接也可能存在微小的漏电流。理想情况下应该用一个MOSFET或三极管通过数字引脚控制这些外围模块的电源在睡眠时彻底断电。5.3 定时唤醒的时间不准症状设定8秒唤醒一次实际可能7.5秒或8.5秒。原因与解决看门狗时钟源精度看门狗使用的是内部128kHz RC振荡器这个振荡器本身精度就不高±10%且受电压和温度影响。这是误差的主要来源。中断响应和代码执行时间从唤醒到再次进入睡眠中间执行的代码如读取传感器标志会占用时间。这段延迟在每次循环中累积导致长期定时漂移。解决方案对于要求不高的应用可以接受这个误差。如果需要高精度有两条路使用外部32.768kHz晶振配合省电模式这是最精准的方法。你需要焊接一个32.768kHz的晶振和两个负载电容到Arduino的XTAL1/XTAL2引脚并使用省电模式让Timer2基于这个精准的时钟工作。使用外部RTC模块如DS3231它自带高精度晶振可以通过I2C设置闹钟并用中断引脚唤醒Arduino。这是工业级的解决方案精度极高且不占用MCU内部资源。5.4 串口通信在睡眠唤醒后乱码或丢失症状睡眠唤醒后通过Serial.print()发送的数据电脑端串口监视器显示乱码或接收不到。原因在深度睡眠模式下系统主时钟停止依赖于系统时钟的串口波特率发生器自然也停了。唤醒后时钟重新启动但串口模块可能没有正确重新初始化或者与主机电脑的波特率已经失步。解决唤醒后重新初始化串口在sleep_disable()之后尝试先执行Serial.end()再执行Serial.begin(9600)。但这会带来短暂的延时。更稳健的方法避免在唤醒后立即进行大量串口通信。可以先发送一个特定的、简单的握手字符如\n等待主机响应后再开始正式数据传输。或者考虑在进入睡眠前就发送完所有数据。根本方法如果项目对功耗要求极致且不需要实时调试最终产品可以完全移除串口通信或者仅通过低速、异步的方式如单线协议传输数据。6. 进阶应用构建一个超低功耗的无线环境监测站掌握了基础我们来设计一个更贴近真实场景的应用一个太阳能供电的户外环境监测站。它集成了温湿度、大气压传感器通过LoRa无线模块每小时上报一次数据。6.1 系统架构与功耗预算核心控制器Arduino Pro Mini (3.3V, 8MHz版本)。选择它是因为它板载元件极少没有USB芯片和指示灯易于实现低功耗。传感器BME280温湿度气压三合一I2C接口。它本身支持低功耗模式可以在测量间隙休眠。无线模块LoRa模块如SX1278。LoRa以其远距离和低功耗著称在发射瞬间电流较大~120mA但发射时间极短几十到几百毫秒平均功耗可以很低。电源小型太阳能板6V, 1W搭配18650锂电池和充电管理模块。目标平均工作电流控制在100μA以下确保在连续阴雨天也能工作数月。6.2 软件设计策略状态机与分时供电代码逻辑不能是简单的读传感器-发数据-睡觉循环。我们需要更精细的控制。// 伪代码逻辑框架 #include LowPower.h // 使用一个优秀的第三方库简化操作 #include Wire.h #include Adafruit_BME280.h #include LoRa.h enum SystemState { SLEEPING, MEASURING, TRANSMITTING }; SystemState currentState SLEEPING; long lastTransmitTime 0; const long transmitInterval 3600000L; // 1小时 void setup() { // 1. 初始化所有引脚为输入上拉省电第一步 initializePinsForLowPower(); // 2. 按需使能外设先不开I2C和LoRa的电源 pinMode(SENSOR_POWER_PIN, OUTPUT); pinMode(LORA_POWER_PIN, OUTPUT); digitalWrite(SENSOR_POWER_PIN, LOW); digitalWrite(LORA_POWER_PIN, LOW); // 3. 初始化看门狗或RTC用于定时唤醒 setupRTC(); } void loop() { switch (currentState) { case SLEEPING: // 使用LowPower库进入掉电模式由RTC闹钟中断唤醒 LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); // 唤醒后检查是否到达发送间隔 if (millis() - lastTransmitTime transmitInterval) { currentState MEASURING; } break; case MEASURING: // 1. 打开传感器电源 digitalWrite(SENSOR_POWER_PIN, HIGH); delay(10); // 等待电源稳定 // 2. 初始化I2C和传感器 Wire.begin(); bme.begin(0x76); // 3. 读取数据 readSensorData(); // 4. 关闭传感器电源 digitalWrite(SENSOR_POWER_PIN, LOW); Wire.end(); // 关闭I2C总线以省电 currentState TRANSMITTING; break; case TRANSMITTING: // 1. 打开LoRa模块电源 digitalWrite(LORA_POWER_PIN, HIGH); delay(50); // 等待模块启动 // 2. 初始化LoRa LoRa.begin(868E6); // 3. 发送数据包 sendLoRaPacket(); // 4. 关闭LoRa模块电源 LoRa.end(); digitalWrite(LORA_POWER_PIN, LOW); // 5. 更新状态和时间 lastTransmitTime millis(); currentState SLEEPING; break; } }这个设计的精髓在于状态机清晰管理设备的不同工作阶段。分时供电传感器和LoRa模块只在需要工作的极短时间内上电其他时候完全断电消除了它们的静态功耗。外设动态管理Wire.begin()/end(),LoRa.begin()/end()在不用时彻底关闭总线或模块。使用第三方库LowPower.h库封装了更便捷的睡眠函数并提供了关闭ADC、BOD掉电检测等选项能进一步降低功耗。6.3 实测与优化结果按照上述设计在测量和发送的短暂窗口期约2秒系统总电流可能达到130mA主要是LoRa发射。但在长达1小时的睡眠期内只有Pro Mini的MCU处于掉电模式加上外围电路的极小漏电流整机平均电流可以轻松做到50μA以下。计算一下工作期2秒消耗130mA睡眠期3598秒消耗0.05mA。 平均电流 (130mA * 2s 0.05mA * 3598s) / 3600s ≈0.12mA。 一块2000mAh的电池理论续航可达2000mAh / 0.12mA ≈ 16666小时接近2年。这就是睡眠模式的威力。7. 工具与库推荐让你的低功耗开发事半功倍LowPower.h库由Rocky Bristol维护这是简化AVR睡眠操作的利器。它提供了类似LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF)的简单接口支持多种睡眠时长和选项比直接操作寄存器友好得多。RTCZero库如果你使用Arduino Zero、MKR系列等基于SAMD21的板子这个库提供了对芯片内部RTC的访问可以用于精确定时唤醒。EnableInterrupt库当你的项目需要多个引脚作为唤醒源时标准的attachInterrupt只支持两个引脚。这个库扩展了中断支持到几乎所有数字引脚使用引脚变化中断非常灵活。万用表/电流表一个能测量微安级电流的万用表是低功耗调试的必备工具。许多廉价万用表在低电流档位精度很差建议选择一款带有良好μA档位的型号。逻辑分析仪或示波器用于调试中断时序、观察唤醒过程中的引脚电平变化对于解决复杂的唤醒同步问题非常有帮助。最后我想分享一个最深刻的体会低功耗设计是一个系统工程它从芯片选型开始贯穿硬件设计电源管理、外围电路、软件架构状态机、中断服务、直到最终的固件优化时钟管理、引脚配置。Arduino的睡眠模式是其中至关重要的一环但它不是银弹。当你为一个户外项目苦苦挣扎于续航时不妨回过头从电源路径上的每一个元件、代码中的每一个循环、每一个delay()去审视那里往往藏着被你忽略的“电老虎”。当你成功地将一个项目的续航从几天延长到几个月甚至几年时那种成就感是任何炫酷的灯光效果都无法比拟的。

相关新闻