Arduino (ATmega) mit Bewegungsmelder aufwecken

Vor kurzem hatte ich die Idee, eine Schaltung mit einem ATmega aufzubauen, die immer nur dann etwas macht, wenn jemand in der Nähe ist. Da die Schaltung mit Batterie betrieben werden sollte und eine möglichst lange Laufzeit aufweisen sollte, sollte der ATmega solange schlafen liegen, bis jemand in die Nähe kommt.
Ideen mit IR-Sensor oder Ultraschall Sensor wurden schnell wieder verworfen, das diese selbst zuviel Strom brauchen. Mechanische Schalter wollte ich auch nicht einsetzen und Induktionsspulen erschienen mir zu kompliziert und zu unempfindlich. Die Lösung brachte ein Pyroelektrischer Bewegungssensor. Bei eBay (Suchbgriff: PIR Motion Sensor) sind solche Sensoren für wenig Geld erhältlich. Vor allem der Standby Stromverbrauch von ca. 60uA (Datenblatt) fand ich fast schon nicht zu glauben. Aber schlauer ist man erst, wenn man es ausprobiert. Und heute war es dann soweit. Als erstes habe ich den Stromverbrauch gemessen, im Ruhemodus waren das ca. 70uA, die im aktiven Modus (Ausgang HIGH) dann auf ca. 170uA ansteigen.

CIMG4287bea

Für den ersten Aufbau musste ein Versuchsaufbau auf dem Steckbrett ausreichen. Der Arduino ist für Experimente im Sleep-Modus ungeeignet, da zwar der ATmega schlafen geht, aber andere Bauteile, wie der USB Wandler, der Spannungswandler und die LEDs weiterhin Strom verbrauchen.

Der PIR Sensor wird wie der ATmega mit 5V betrieben und gibt einen HIGH Pegel ab, wenn er Bewegung erkennt. Am ATmega hängt neben der Reset Beschaltung und dem Quarz nebst Kondensatoren ein LCD Display. Die Programmierung erfolgte über einen mySmartUSB light ISP.

Da der PIR-Sensor einen HIGH Pegel abgibt, der ATmega aber mit einem LOW Pegel geweckt werden will, wurde der Pegel mit einem BS170 invertiert. Zum Aufwecken wurde der INT0 am Eingang D2 genutzt, der mit einem externen Pullup auf HIGH gezogen wird. Die Programmierung erfolgte unter der Arduino IDE. Das LCD wird über D8 mit Strom versorgt und wird im Schlafmodus ebenfalls deaktiviert. Im LCD wird während der Aktivphase die Laufzeit in Sekunden und die Anzahl der Aufweckvorgänge angezeigt. Der Stromverbrauch liegt im Sleep-Modus bei ca. 450uA und im Aktiv-Modus bei 18mA.

#include <avr/sleep.h>
 #include <LiquidCrystal.h>
 #define LCD_POW 8
 #define INT2 2
 int toggle=0;
 // initialize the library with the numbers of the interface pins
 LiquidCrystal lcd(12, 11, 5, 4, 3, 6);
void wakeUpNow(){        // here the interrupt is handled after wakeup
 detachInterrupt(0);
 toggle = toggle++;
 }
void setup() {
 pinMode(INT2, INPUT);
 pinMode(LCD_POW, OUTPUT);
 digitalWrite(LCD_POW, HIGH);  // switch on power fpr LCD
 delay(100);  // wait for power to stabilize
 // set up the LCD's number of columns and rows:
 lcd.begin(16, 2);
 // Print a message to the LCD.
 lcd.print("hello, world!");
 }
void sleepNow(){
 pinMode(LCD_POW,INPUT);       // Ausgänge für Schlafen vorbereiten
 pinMode(12,INPUT);       // Ausgänge für Schlafen vorbereiten
 pinMode(11,INPUT);       // Ausgänge für Schlafen vorbereiten
 pinMode(5,INPUT);       // Ausgänge für Schlafen vorbereiten
 pinMode(4,INPUT);       // Ausgänge für Schlafen vorbereiten
 pinMode(3,INPUT);       // Ausgänge für Schlafen vorbereiten
 pinMode(6,INPUT);       // Ausgänge für Schlafen vorbereiten
 set_sleep_mode(SLEEP_MODE_PWR_DOWN);
 sleep_enable();
 attachInterrupt(0,wakeUpNow, LOW);
 sleep_mode();
 // wakes up here
 sleep_disable();
 detachInterrupt(0);
 pinMode(12,OUTPUT);       // Ausgänge für Schlafen vorbereiten
 pinMode(11,OUTPUT);       // Ausgänge für Schlafen vorbereiten
 pinMode(5,OUTPUT);       // Ausgänge für Schlafen vorbereiten
 pinMode(4,OUTPUT);       // Ausgänge für Schlafen vorbereiten
 pinMode(3,OUTPUT);       // Ausgänge für Schlafen vorbereiten
 pinMode(6,OUTPUT);       // Ausgänge für Schlafen vorbereiten
 pinMode(LCD_POW, OUTPUT);
 digitalWrite(LCD_POW, HIGH);  // switch on power fpr LCD
 delay(100);  // wait for power to stabilize
 lcd.begin(16, 2);
 }
void loop() {
 // set the cursor to column 0, line 1
 // (note: line 1 is the second row, since counting begins with 0):
 lcd.setCursor(0, 1);
 // print the number of seconds since reset:
 lcd.print(millis()/1000);
 lcd.print(" ");
 lcd.print(toggle);
 if (digitalRead(INT2)) sleepNow(); // only if HIGH again
}

DSC01892

Veröffentlicht am 9. Juni 2013 in Arduino und mit , , getaggt. Setze ein Lesezeichen auf den Permalink. 2 Kommentare.

  1. Hallo glaskugelsehen,

    da ich keine Kontaktmöglichkeit gefunden habe und dieser Blog schon etwas älter ist, nutze ich jetzt mal die Kommentarfunktion und hoffe dass es dich erreicht. Ich bin komplett „Nicht-Arduino oder Microcontroller Wissend“ aber ich habe ein Projekt im Kopf.

    Für die Remote Überwachung von Automaten an öffentlichen Aufstellplätzen habe bräuchte ich eine Eierlegende Wollmichsau :-) Ich bin auf diesen Artikel mit dem Schlafmodus gestossen und denke das ist genau ein Teil des Projektes, welches ich im Kopf habe.
    Das ganze soll eine Überwachungsmöglichkeit werden mit Bild, Ton, SMS Benachrichtigung ect.
    Ich habe dazu bereits alle Anforderungen in einer Zeichnung aber ich schätze bis ich das dazu benötigte Wissen habe, brauche ich es nicht mehr, weil ich dann wahrscheinlich lieber Bingo in Gesellschaft spiele.

    Gruß, Daniel

Hinterlasse einen Kommentar