Schlafmodus mit Wecken durch Pin Change Interrupt (PCI)
Das nachfolgende Programmbeispiel zeigt, wie ein schlafender Attiny azyklisch "von außen" mit einem Pin Change Interrupt, ausgelöst durch das Drücken eines Tasters, geweckt wird.
Funktion:
Nach Neuanlauf des Attiny wird dieser in den Schlafmodus gesetzt. Durch Drücken der Taste "LED Ein" wird ein PCI am Pin PB3 ausgelöst, der die LED für 2 Sekunden einschaltet. Anschließend geht der Attiny wieder in den Schlafmodus, wo er bis zum nächsten Tastendruck verharrt.
Infos zum PCI beim Attiny findet man hier!
Verwendete Library:
sleep: Die verwendete Library sleep ist Bestandteil der Arduino-IDE und muss deshalb nicht installiert werden.
Hinweis:
Wer mit Registerprogrammierung und Pin Change Interrupt nicht vertraut ist, sollte sich zum Verständnis des Programms folgende Seiten ansehen: Bitmanipulation und Pin Change Interrupt Attiny
//Sleep Mode mit PCI-Wecken
//Code fuer Attiny
//Author Retian
//Version 1.0
#include <avr/sleep.h>
//Prototypen:
void gotoSleep(void);
#define ledPin 4
volatile bool statusLeuchten = false;
bool statusSleep = true;
void setup() {
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);//Setzen der Register fuer Pin-Change-Interrupt Pin PB3
//Loeschen des Global Interrupt Enable Bits (I) im Status Register (SREG)
SREG &= 0x7F; //entspricht "cli();"
//Setze des Pin Change Interrupt Enable Bit
GIMSK |= (1 << PCIE);
//Setzen des Pin Change Enable Mask Bit 3 (PCINT3) ==> Pin PB3
PCMSK |= (1 << PCINT3);
//Setzen des Global Interrupt Enable Bits (I) im Status Register (SREG)
SREG |= 0x80; //entspricht "sei();"
}
void loop() {
if (statusLeuchten)
{
digitalWrite(ledPin, HIGH);
delay(2000);
digitalWrite(ledPin, LOW);
statusLeuchten = false;
statusSleep = true;
}if (statusSleep)
{
gotoSleep();
statusSleep = false;
}
}
//Attiny in den Schlafmodus setzen
void gotoSleep()
{
byte adcsra;adcsra = ADCSRA; //ADC Control and Status Register A sichern
ADCSRA &= ~_BV(ADEN); //ADC ausschaltenMCUCR |= (1 << SM1) & ~(1 << SM0); //Sleep Modus = Power Down
MCUCR |= _BV(SE); //Sleep Enable setzen
sleep_cpu(); //Schlafe ....
MCUCR &= ~(1 << SE); //Sleep Disable setzen
ADCSRA = adcsra; //ADCSRA-Register rückspeichern
}
//Interrupt Serviceroutine (Pin-Change-Interrupt)
ISR(PCINT0_vect)
{
statusLeuchten = true;
}
Ergebnis:
Der Stromverbrauch des Testaufbaues beträgt ca. 17 mA bei leuchtender LED (ca. 7,5 mA ohne LED). Wie nachfolgende Abbildung 2-1 zeigt, beträgt im Schlafmodus der Stromverbrauch weniger als 0,5 µA !!
Abbildung 2-1: Multimeter mit Anzeige des Stromverbrauchs im Schlafmodus von weniger als 0,5 µA (Messbereichsvorwahl 200 µA)