Arduino外围组件模块非常丰富。我想做一个温度报警器,但我发现电池的供电不能持续几天,所以我辗转反侧了一段时间,最后把待机时间延长到退休后^-^,现在和大家分享过程。 首先要知道电池供电待机时间的计算公式。通常电池都会标明容量为毫安时(mAH)。7号电池容量为1.5V700mAH左右. 18650电池可以轻松实现3.7V3500mAH。假如我们选择1节1865 3500mAH的电池来供Arduino工作,最长能待多久?假设Arduino平均工作电流为30mA,那么3500/30=117小时=4.88天显然离我们的目标17年太远了。如果要实现17年待机目标,电流应控制在本文不考虑电池自放电、电压变化和温度影响。 好了,有了目标,想办法把待机电流控制在23.5uA吧!
1.首选8Mhz主频的Arduino板,因为绝大多数单片机程序都是8M主频跑起来绰绰有余,但是8M功耗相比16M但是可以大大降低,可以用分频代码测试不同工作频率下的功耗。 2.首选2.7V~5.5V 电源板。因为18650电池的电压范围是2.7~4.2V,三节7号电池3V~4.8V,要想把电池的电量使用完,单片机必须能在最低2.7V稳定在电压下工作。 3.主要是简化外围电路USB转TTL电路,5V转3.3VLDEO电路等。 结合以上三点,建议直接使用 开发板,某宝有售。此款板子正是具有TYPE-C接口的pro Mini 8MHz 328P芯片开发板,更重要的是,它专门设计了一个外围电路断开焊点,上传程序后断开焊点LDO和USB电路。如图
4.剩下的就是代码优化,直接上代码,思路就是让Arduino开机进入 SLEEP_MODE_PWR_DOWN 此时,实测电流已成功降至23uA。当然,什么都不做。打开看门狗中断,每秒唤醒一次,执行看门狗计数。醒来后进入loop循环,然后判断循环已经过了多少秒,根据需要执行自己的功能操作。
#include <avr/sleep.h> #include <avr/power.h> #include <avr/wdt.h> #define LED_PIN (13) void OFFACDDC() {//关闭ACD和ADC ACSR |=_BV(ACD); ADCSRA=0; } void ONACDDC() {//开启ACD和ADC ACSR &= ~_BV(ACIE); ACSR &= ~_BV(ACD); ADCSRA |= _BV(ADEN); ADCSRA |= _BV(ADIF); } volatile int f_wdt = 1; ///看门狗计数 ISR(WDT_vect) { ////看门狗唤醒执行函数 f_wdt ; } void enterSleep(void) { //进入睡眠状态 set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_enable(); sleep_mode(); sleep_disable(); power_all_enable(); } void setup() { pinMode(LED_PIN , OUTPUT); digitalWrite(LED_PIN , LOW); OFFACDDC(); /*** 设置看门狗 ***/ MCUSR &= ~(1 << WDRF); /* 清除复位标志. */ WDTCSR |= (1 << WDCE) | (1 << WDE); //* 设置新的看门狗超时间 WDTCSR = 1<<WDP1 | 1<<WDP2;// 看门狗每1秒超时1次,也可以执行一次唤醒函数 ISR WDTCSR |= _BV(WDIE); /* 设置为定期中断,而不是复位 */ } void loop() { if (f_wdt >= 5) { //唤醒后会运行loop是的,此时检查唤醒5次,也就5秒,闪烁一下 ONACDDC();//打开ADC,模拟输入IO口才可以恢复使用 digitalWrite(LED_PIN, HIGH); delay(20); digitalWrite(LED_PIN, LOW); f_wdt = 0; OFFACDDC(); } enterSleep();/继续休眠 }
5.在实际应用中,对于一些简单低功耗的传感器,如LM35,可以直接用数字IO口接其VCC引脚可以在唤醒后使用IO口控制LM35供电,休眠前断开。如果是WIFI如果模块耗电量大,可以外接小功率固态继电器,如211EH,也能满足唤醒电源的要求。另外,功耗降低了,其实可以加5个V小太阳能电池板(串几个二极管,确保电流不倒灌且最强光线下不超过电池最高充电电压),配合可充电电池,实现无限续航。
PS:3节7号电池串联,24节uA在电流下可以工作700/0.024/24/365= 3.3年。