Arduino 低功耗优化
来自Jack's Lab
(版本间的差异)
(→深入 ATMEGA 328) |
(→328 Note) |
||
(未显示1个用户的23个中间版本) | |||
第9行: | 第9行: | ||
328P有6种节电设置,分别是: | 328P有6种节电设置,分别是: | ||
− | * 空闲模式 | + | * 空闲模式 (SLEEP_MODE_IDLE) |
− | * ADC 噪声抑制模式 | + | * ADC 噪声抑制模式 (SLEEP_MODE_ADC) |
− | * 掉电模式 | + | * 掉电模式 (SLEEP_MODE_PWR_DOWN) |
− | * 省电模式 | + | * 省电模式 (SLEEP_MODE_PWR_SAVE) |
* Standby 模式 | * Standby 模式 | ||
* 扩展Standby 模式 | * 扩展Standby 模式 | ||
第18行: | 第18行: | ||
[[文件:Atmega328p-power-mode.png]] | [[文件:Atmega328p-power-mode.png]] | ||
+ | |||
+ | |||
+ | 其中,关掉内部部件最多的掉电模式,328P 的耗电约为 1uA | ||
第31行: | 第34行: | ||
WDT_vect 为 watchdog 中断向量入口 | WDT_vect 为 watchdog 中断向量入口 | ||
+ | |||
+ | <br><br> | ||
+ | |||
+ | == ATtiny13 == | ||
+ | |||
+ | * 空闲模式 (SLEEP_MODE_IDLE) | ||
+ | * ADC 噪声抑制模式 (SLEEP_MODE_ADC) | ||
+ | * 掉电模式 (SLEEP_MODE_PWR_DOWN) | ||
+ | * 省电模式 (SLEEP_MODE_PWR_SAVE) | ||
<br><br> | <br><br> | ||
第100行: | 第112行: | ||
</source> | </source> | ||
<br><br> | <br><br> | ||
+ | |||
+ | == 328 Note == | ||
+ | |||
+ | * NO LOW_POWER:闲时 10.5 mA,发射 19.5mA、40mA、85mA | ||
+ | * LOW_POWER: 睡眠 1.7mA,发射 50mA、87mA | ||
+ | |||
+ | |||
+ | '''2019/05/30 23:55:54:''' | ||
+ | |||
+ | * LOW_POWER: 睡眠 1.7mA,power_off_dev() 后,睡眠电流居然猛增到 54mA 左右。。。夜深明日再战。。。 | ||
+ | |||
+ | |||
+ | '''2019/05/31 11:40''' | ||
+ | |||
+ | * 增加 SPI.end(); digitalWrite(SPI_CS, LOW),睡眠电流降到 115uA 左右。必须两个都有,只有其中一个,睡眠电流都在 34mA 左右 | ||
+ | * powerDown(SLEEP_FOREVER, ...) 电流在 111uA 左右 | ||
+ | |||
+ | |||
+ | * 增加 Wire.end(); 电流还是在 115uA 左右。再增加 SDA (A4), SCL (A5) ---> LOW,电流还是在 115uA 左右。 | ||
+ | |||
+ | |||
+ | * 使用另外一片 Quark,power_switch 换成 SI2301,移除 AP2112,直接 Vbat (3.3V) 供电,移除 SX1278,同样的代码(移除 LoRa 相关),睡眠电流为 4.3uA 左右,即: Atmega328p + SI2301 的消耗在 4.3uA 左右。。。 | ||
+ | ** 固件没动,焊上一片 SX1278,睡眠电流一样 | ||
+ | ** 固件和另一片一样,则睡眠电流也变为 109 uA 左右。因此貌似关 SX1278 的电源并不能显著降低睡眠电流,难道应该就用其的 power down 模式?! | ||
+ | ** 改为 sx1272.OFF() (其实就是 SPI.end()),不设 setSleepMode(),电流 2mA;再 digitalWrite(SPI_CS=10, LOW),电流变为 65uA | ||
+ | ** OFF() 前 reset() 一下,不设 setSleepMode(),digitalWrite(SPI_CS=10, LOW),还是 65uA | ||
+ | ** 设 setSleepMode(),OFF() ,digitalWrite(SPI_CS=10, LOW),还是 65uA | ||
+ | ** 设 setSleepMode(),no OFF() ,no digitalWrite(SPI_CS=10, LOW),电流变为 750uA | ||
+ | ** 设 setSleepMode(),no OFF() ,SPI.end(), digitalWrite(SPI_CS=10, LOW),58uA | ||
+ | ** 将 RST 拉低,4.4uA !泪流满面。。。 '''2019/05/31 16:16''' | ||
+ | |||
+ | |||
+ | |||
+ | <br> | ||
+ | |||
+ | == Reference == | ||
+ | |||
+ | * https://github.com/rocketscream/Low-Power/blob/master/LowPower.cpp | ||
+ | * http://www.home-automation-community.com/arduino-low-power-how-to-run-atmega328p-for-a-year-on-coin-cell-battery/ | ||
+ | * https://andreasrohner.at/posts/Electronics/How-to-modify-an-Arduino-Pro-Mini-clone-for-low-power-consumption/ | ||
+ | |||
<br><br> | <br><br> | ||
<br><br> | <br><br> |
2019年5月31日 (五) 16:16的最后版本
目录 |
[编辑] 1 概述
常用的 Atmega328p 最小系统下 16MHz 运行功耗大约是10mA,一块手机1200mAh的电池大约可不间断运行 1200/10/24 = 5天,这个还是在没有任何外围器件的情况下,算上外围设备如温度传感器等,连续运行的时间更短
[编辑] 2 深入 ATMEGA 328
328P有6种节电设置,分别是:
- 空闲模式 (SLEEP_MODE_IDLE)
- ADC 噪声抑制模式 (SLEEP_MODE_ADC)
- 掉电模式 (SLEEP_MODE_PWR_DOWN)
- 省电模式 (SLEEP_MODE_PWR_SAVE)
- Standby 模式
- 扩展Standby 模式
其中,关掉内部部件最多的掉电模式,328P 的耗电约为 1uA
另外:Watchdog 触发中断,不仅只有重启的功能,亦可配置为执行中断函数:
ISR(WDT_vect) { // interrupt function }
WDT_vect 为 watchdog 中断向量入口
[编辑] 3 ATtiny13
- 空闲模式 (SLEEP_MODE_IDLE)
- ADC 噪声抑制模式 (SLEEP_MODE_ADC)
- 掉电模式 (SLEEP_MODE_PWR_DOWN)
- 省电模式 (SLEEP_MODE_PWR_SAVE)
[编辑] 4 代码
#include <avr/sleep.h> #include <avr/wdt.h> volatile byte data=0; void setup() { pinMode(13,OUTPUT); setup_watchdog(9); ACSR |=_BV(ACD);//OFF ACD ADCSRA=0;//OFF ADC Sleep_avr();//Sleep_Mode } void loop() { if(data>=7){ data=0; //------------------------------- digitalWrite(13,HIGH); delay(100); digitalWrite(13,LOW); //-------------------------------- sleep_avr(); } else { sleep_avr(); //Continue Sleep } } // 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms // 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec void setup_watchdog(int ii) { byte bb; if (ii > 9 ) ii=9; bb=ii & 7; if (ii > 7) bb|= (1<<5); bb|= (1<<WDCE); MCUSR &= ~(1<<WDRF); // start timed sequence WDTCSR |= (1<<WDCE) | (1<<WDE); // set new watchdog timeout value WDTCSR = bb; WDTCSR |= _BV(WDIE); } //WDT interrupt ISR(WDT_vect) { ++data; // wdt_reset(); } void sleep_avr(){ set_sleep_mode(SLEEP_MODE_PWR_DOWN ); // sleep mode is set here sleep_enable(); sleep_mode(); // System sleeps here }
[编辑] 5 328 Note
- NO LOW_POWER:闲时 10.5 mA,发射 19.5mA、40mA、85mA
- LOW_POWER: 睡眠 1.7mA,发射 50mA、87mA
2019/05/30 23:55:54:
- LOW_POWER: 睡眠 1.7mA,power_off_dev() 后,睡眠电流居然猛增到 54mA 左右。。。夜深明日再战。。。
2019/05/31 11:40
- 增加 SPI.end(); digitalWrite(SPI_CS, LOW),睡眠电流降到 115uA 左右。必须两个都有,只有其中一个,睡眠电流都在 34mA 左右
- powerDown(SLEEP_FOREVER, ...) 电流在 111uA 左右
- 增加 Wire.end(); 电流还是在 115uA 左右。再增加 SDA (A4), SCL (A5) ---> LOW,电流还是在 115uA 左右。
- 使用另外一片 Quark,power_switch 换成 SI2301,移除 AP2112,直接 Vbat (3.3V) 供电,移除 SX1278,同样的代码(移除 LoRa 相关),睡眠电流为 4.3uA 左右,即: Atmega328p + SI2301 的消耗在 4.3uA 左右。。。
- 固件没动,焊上一片 SX1278,睡眠电流一样
- 固件和另一片一样,则睡眠电流也变为 109 uA 左右。因此貌似关 SX1278 的电源并不能显著降低睡眠电流,难道应该就用其的 power down 模式?!
- 改为 sx1272.OFF() (其实就是 SPI.end()),不设 setSleepMode(),电流 2mA;再 digitalWrite(SPI_CS=10, LOW),电流变为 65uA
- OFF() 前 reset() 一下,不设 setSleepMode(),digitalWrite(SPI_CS=10, LOW),还是 65uA
- 设 setSleepMode(),OFF() ,digitalWrite(SPI_CS=10, LOW),还是 65uA
- 设 setSleepMode(),no OFF() ,no digitalWrite(SPI_CS=10, LOW),电流变为 750uA
- 设 setSleepMode(),no OFF() ,SPI.end(), digitalWrite(SPI_CS=10, LOW),58uA
- 将 RST 拉低,4.4uA !泪流满面。。。 2019/05/31 16:16
[编辑] 6 Reference
- https://github.com/rocketscream/Low-Power/blob/master/LowPower.cpp
- http://www.home-automation-community.com/arduino-low-power-how-to-run-atmega328p-for-a-year-on-coin-cell-battery/
- https://andreasrohner.at/posts/Electronics/How-to-modify-an-Arduino-Pro-Mini-clone-for-low-power-consumption/