Arduino 低功耗优化

来自Jack's Lab
跳转到: 导航, 搜索

目录

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 模式


Atmega328p-power-mode.png


其中,关掉内部部件最多的掉电模式,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



















个人工具
名字空间

变换
操作
导航
工具箱