Daca vom construi un montaj cu Arduino alimentat de la baterii sau acumulatori si vrem sa marim autonomia acestuia atunci una dintre optiunile de a economisi energie electrica este prin punerea microcontrolerului in modul sleep.
Pentru a putea face acest lucru vom folosi pinul digital 2 la care vom atasa o intrerupere. Cu ajutorul acestei intreruperi putem scoate procesorul din starea sleep in orice moment dorim pentru ca acesta sa isi reia activitatea.
Pentru a genera o intrerupere putem folosi un comutator, un senzor sau chiar un ceas RTC.
Pentru a putea pune procesorul in modul sleep va trebui sa includem libraria sleep.h. Apoi vom defini pinul digital 2 pentru a-l folosi cu o intrerupere. Codul este cel de mai jos:
#include <avr/sleep.h>
#define powerOn 2 //pinul folosit pentru iesirea din sleep mode
In functia setup() va trebui sa declaram pinul digital 2 ca si intrare:
pinMode(powerOn, INPUT_PULLUP);
Pentru a initializa modul sleep in functia loop() va trebui sa o facem prin urmatoarea functie creata de noi:
GoingSleep();
Functia GoingSleep() contine urmatoarele linii de cod:
void GoingSleep() {
sleep_enable();
attachInterrupt(digitalPinToInterrupt(powerOn), wakeUp, LOW);
//aici rulam anumite instructiuni dorite inainte de a intra procesorul in modul sleep
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
delay(1000);
sleep_cpu();
//aici putem pune codul care se va executa imediat dupa ce procesorul va iesi din modul sleep
delay(1500);
}
In functia de mai sus observam ca apare o intrerupere si acea intrerupere apeleaza o noua functie numita wakeUp. Aceasta functie face ca procesorul sa iasa din modul sleep si sa-si continue rularea. Codul acestei functii este cel de mai jos:
void wakeUp() {
sleep_disable();
detachInterrupt(digitalPinToInterrupt(powerOn));
}
Un exemplu practic este urmatorul: vom folosi un display LCD conectat pe magistrala I2C pentru a afisa anumite informatii, dupa cateva secunde microcontrolerul intra in modul sleep iar la apasarea unui buton conectat intre pinul digital 2 si masa montajului acesta isi va relua activitatea. Sketchul folosit in acest exemplu este cel de mai jos:
#include <avr/sleep.h>
#define powerOn 2 //pinul folosit pentru iesirea din sleep mode
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
byte grafic[] = {
0x1F,
0x1F,
0x1F,
0x1F,
0x1F,
0x1F,
0x1F,
0x1F
};
void setup() {
lcd.createChar(0, grafic);
pinMode(powerOn, INPUT_PULLUP);
lcd.begin();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Arduino si ");
lcd.setCursor(0, 1);
lcd.print("sleep mode");
delay(3000);
}
void loop() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("In acest moment");
lcd.setCursor(0, 1);
lcd.print("arduino ruleaza...");
delay(5000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Sleep mode...");
for (int i=0; i<16; i++) {
lcd.setCursor(i, 1);
lcd.write(byte(0));
delay(300);
}
delay(1500);
GoingSleep(); //aceasta functie pune microcontrolerul in mod sleep
}
void GoingSleep() {
sleep_enable();
attachInterrupt(digitalPinToInterrupt(powerOn), wakeUp, LOW);
lcd.noBacklight();
lcd.clear();
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
delay(1000);
sleep_cpu();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Acum m-am trezit");
delay(1500);
}
void wakeUp() {
sleep_disable();
detachInterrupt(digitalPinToInterrupt(powerOn));
}