Вопрос как?
Что уже сделано. Вот схема.
Голая Atmega328P-PU вообще без обвязки. Для тестирования контроллер шлет в UART информацию что он делает. Так ка эксперименты были связаны с понижением напряжения питания пришлось сделать оптическую развязку с переходником USB2UART. На схеме она для выхода TX контроллера, но была и для RX (на потребление как оказалось не влияет).
Теперь собственно про минимизацию потребления. Что сделано:
1. Напряжение питания снижено до 2.7В. Меньше не стал, т.к. датчики которые потом будут работать с контроллером меньше не могут.
2. Частота снижена до 1 Мгц. Контроллер тактируется от внутреннего генератора 8 МГц с делителем на 8. Fuse выставлены следующие:
Код: Выделить всё
a328p_1MHz.bootloader.tool=avrdude
a328p_1MHz.bootloader.low_fuses=0x62
a328p_1MHz.bootloader.high_fuses=0xde
a328p_1MHz.bootloader.extended_fuses=0xFF
4. Режим сна SLEEP_MODE_PWR_DOWN просыпаемся по watchdog
5. Перед тем как заснуть выключаем все устройства power_all_disable(); когда просыпаемся включаем только таймер 1 и UART
Код: Выделить всё
power_usart0_enable();
power_timer0_enable();
Код: Выделить всё
for (byte i = 0; i <= A5; i++)
{
pinMode (i, OUTPUT); // changed as per below
digitalWrite (i, LOW); // ditto
}
Что еще можно сделать?
Вот полный код скетча:
Код: Выделить всё
#include "Test3.h"
#include <avr/io.h>
#include <avr/interrupt.h> // работа с прерываниями
#include <avr/sleep.h>
#include <avr/wdt.h>
#include <avr/power.h>
volatile byte watchdogCounter = 0;
void setup_watchdog(byte sleep_time)
{
cli();
wdt_enable(sleep_time);
MCUSR &= ~_BV(WDRF);
WDTCSR |= _BV(WDCE) & ~_BV(WDE);
WDTCSR |= _BV(WDIE);
sei();
}
void arduino_sleep()
{
cli();
power_all_disable();
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sei();
sleep_mode();
}
void savePower( ) {
power_all_disable();
for (byte i = 0; i <= A5; i++)
{
pinMode (i, OUTPUT); // changed as per below
digitalWrite (i, LOW); // ditto
}
DIDR1 |= _BV(AIN1D) | _BV(AIN0D);
MCUCR = bit (BODS) | bit (BODSE);
MCUCR = bit (BODS);
}
void setup()
{
Serial.begin(9600);
Serial.println("Wait 5 sec..");
delay(5000); // Задержка, чтобы было время перепрошить устройство в случае bootloop
savePower();
setup_watchdog(WDTO_8S);
}
ISR (WDT_vect)
{
WDTCSR |= _BV(WDIE);
watchdogCounter++;
}
void doSomething() {
Serial.print("Hello world!!! Uptime : ");
Serial.print(millis());
Serial.print(" _ ");
for( int i=0; i<100; i++ ) {
Serial.print(".");
delay(50);
}
Serial.println("");
}
void loop()
{
power_usart0_enable();
power_timer0_enable();
delay(5);
doSomething();
Serial.println("Go to sleep....");
delay(100);
while (watchdogCounter < 2) //wait for watchdog counter reached the limit, WDTO_8S * 4 = 32sec.
{
arduino_sleep();
}
Serial.println("Wake up....");
watchdogCounter = 0; //reset counter
}



