Smarter Briefkasten per LoRa
Ansätze für smarte Briefkästen gibt es im Web viele. Hier ist ein Weiterer der besonders energiesparend ist und gleichzeitig bei Bedarf größere Distanzen überbrückt. Schliesslich kann die Briefkastenanlage im Mehrfamilienhaus oder einem entsprechend großen Anwesen weiter von der Smart Home Basis weg sein.
Anforderungen
- Batteriebetrieben, Laufzeit >= 1 Jahr
- Reichweite über mehrere Stockwerke hinweg
- Robuste Sensorik zur Erkennung von Briefeinwurf und -entnahme
Ich habe mich aufgrund der Anforderungen für die Nutzung von LoRa (nicht LoRaWAN) entschlossen, da das nächste LoRaWAN Gateway von The Things Network recht weit entfernt ist bzw. ich alternativ ein recht teueres Gateway kaufen müsste. Statt dessen nutze ich LoRa (ohne WAN) um die Pakete direkt an ein anderes LoRa-Modul zu senden, welches an meinen Raspberry Pi meiner Smart Home Basis angeschlossen ist (siehe LoRa Basis am OpenHAB).
Bauteile
- 2 Reedkontakte 2x14mm “normally open” (5 Stück bei Ebay für z.B. 2,39€)
- 2 kleine Neodym-Magente
- 1 LoRa Funk Modul RFM95W 868 MHz
- 1 Arduino Pro Mini
- 1 Kleingehäuse, Batteriehalter, Litze, etc.
Aufbau der Hardware
Die Reedkontakte werden an die beiden externen Interrupts des Arduino Pro Mini (Pin 2, 3) angeschlossen. Sie können den Arduino damit sogar aus dem Stromsparmodus SLEEP_MODE_PWR_DOWN
aufwecken. Das LoRa Modul wird ebenfalls an den Arduino Pro Mini angeschlossen (NSS -> 10, MOSI -> 11, MISO -> 12, SCK -> 13, RESET -> 9).
Aufbau der Software
Es kommt das Arduino Modul LoRa zum Einsatz, welches wie folgt initialisiert wird:
#include <LoRa.h>
const int lora_sf = 7;
const int dio0_pin = -1;
const long lora_freq = 868.3E6;
const int rst_pin = 9;
const int cs_pin = 10;
void setup() {
LoRa.setPins(cs_pin, rst_pin, dio0_pin);
LoRa.begin(lora_freq)
LoRa.setSpreadingFactor(lora_sf);
LoRa.enableCrc();
}
Wenn der Arduino nichts zu tun hat (dürfte die meiste Zeit so sein) schickt man ihn wie folgt in den Tiefschlaf:
#include <avr/sleep.h>
#include <avr/power.h>
void enterSleep(void) {
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
Serial.println("Enter sleep...");
delay(100);
LoRa.sleep();
sleep_enable();
sleep_mode();
// mcu sleeps here
sleep_disable();
delay(100);
Serial.println("Wakeup.");
}
Dass er aus dem Tiefschlaf wieder aufweckt, dafür sorgen folgende Zeilen:
const int isr1_pin = 2;
const int isr2_pin = 3;
void isr1() { // handler 1 }
void isr1() { // handler 2 }
pinMode(isr1_pin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(isr1_pin), isr1, RISING);
pinMode(isr2_pin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(isr2_pin), isr2, RISING);
Bei entsprechender Aktivität kann über LoRa ein entsprechendes Paket abgesetzt werden und - falls gewünscht - auch direkt auf ein ACK gewartet werden:
// send
LoRa.beginPacket();
byte payload[] = {0x01, 0x02, 0x03};
LoRa.write(payload, 3);
LoRa.endPacket();
// receive
packetSize = LoRa.parsePacket();
if (packetSize) {
while (LoRa.available()) {
int c = LoRa.read();
package[pos++] = c;
}
Akkulaufzeit
Im Stromsparmodus ergibt sich durch die beiden Reedkontakte, da sie sich die meiste Zeit im geschlossenen Zustand befinden, und den an Pin 2 und 3 aktivierten Pull-Up-Widerstand ein Stromfluss von ca. 0,5mA. Vernachlässigt man die LoRa-Transmissionen und den kurzzeitigen Betrieb des Microcontrollers ausserhalb des Stromsparmodus ergibt sich eine theoretische Batterielebensdauer von 200 Tagen (2xAA, 2400mAh).
Am Labornetzteil läuft die Schaltung zwischen 2,1 und 3,3 Volt stabil. Die Laufzeit in der Praxis sollte daher passabel ausfallen. Zum Zeitpunkt des Schreibens dieses Artikels wird noch der erste Batteriesatz verwendet.
Bilder
Der offene LoRa-Node, die Antenne (82mm lang) passt grade entlang der längsten Seite des Gehäuses
Verbesserungsmöglichkeiten
Statt des Arduino Pro Mini einen ATtiny84 verwenden, wie in diesem Heise-Projekt um die Batterielaufzeit zu erhöhen.