Archiv der Kategorie: Raspberry Pi
RRD Datenbank auf RaspberryPi
In meinem Beitrag über den RaspberryPi mit RFM12B 868 MHz Enpfänger, habe ich bereits das Modul beschrieben, das die Daten empfängt. Der Code für den Arduino mini liegt auf Github.
In diesem Blogpost möchte ich die Datenerfassung mit dem rrdtool beschreiben.
Die empfangenen Daten werden vom Empfängermodul folgendermassen übergeben, hier dargestellt mit dem serialRead Programm aus WiringPi:
pi@raspberrypi ~ $ ./wiringPi/examples/serialRead ���16 3283 2210 4360 271 17391 69 ������16 3283 2210 4350 271 17459 68 ������16 3283 2210 4360 272 17528 69 ������16 3274 2200 4340 273 17597 69
Die seltsamen ersten Zeichen der Zeilen werden vom serialRead Beispielprogramm ausgegeben, wenn 10s lang keine Daten über seriell empfangen werden und sind ein Byte mit dem Wert 0. Vermeiden lässt sich das, wenn statt
// Loop, getting and printing characters for (;;) { putchar (serialGetchar (fd)) ; fflush (stdout) ; }
folgendes gemacht wird
// Loop, getting and printing characters for (;;) { int char1; if ((char1 = serialGetchar(fd)) > 0) { putchar (char1 ); fflush(stdout); } }
Die Ausgabe der Empfangsmoduls ist wie folgt zu interpretieren:
– 16: ID des Senders
– 3283: Batteriespannung des Senders, hier 3283 mV
– 2210: Temperatur, hier 22,1°C
– 4360: Luftfeuchte, hier 43,6%
– 271: Minute seit dem letzten Reset des Senders
– 17391: Sekunden seit dem Reset des Empfängers
– 69: Sekunden seit dem letzten Datenpaket.
Momentan werden nur die Temperatur, die Feuchte und die Batteriespannung weiterverarbeitet.
Für die weitere Verarbeitung setze ich die Installation des RRDPakets und eines Apache Webservers mit PHPvoraus. Die RRD Datenbank für meine Daten habe ich so angelegt:
rrdtool create sensor16.rrd --step 300 \ -> Messwerte alle 300s DS:temp:GAUGE:600:U:U \ -> wenn keine Messwerte nach 600s UNKNOWN, keine Limits :U DS:hum:GAUGE:600:U:U \ DS:batt:GAUGE:600:U:U \ RRA:AVERAGE:0.5:1:8640 \ -> Messwerte für 30 Tage RRA:MIN:0.5:12:8760 \ -> Archiv 1 Wert pro 300*12=1h, 8760h=365 Tage RRA:MAX:0.5:12:8760 \ RRA:AVERAGE:0.5:12:8760 \
Die rechts eingefügten Kommentare sind bei der Eingabe zu löschen. Die seriell empfangenen Daten werden geparsed und per system() Aufruf an RRD übergeben. Das Programm enthält noch viele Kontrollausgaben, die aber nicht weiter stören. Das parsen der Daten ist nicht unbedingt sehr elegant, ist aber historisch gewachsen und funktioniert.
Die Daten sollen grafisch dargestellt werden und während der Laufzeit erzeugt werden. Das ist zwar nicht besonders performant, schützt aber den Flashspeicher des RaspPi vor zu vielen Schreibzyklen, wenn die Grafiken z.B. alle 5 min per cron erzeugt würden. Solche Grafiken werden dynamisch beim Aufruf einer PHP Seite mit RRD erzeugt und zeigen die Daten der letzten 24 Stunden. Zwischen 12:00 und 13:30 wurden keine Daten gespeichert. Die Akkus waren schon ziemlich leer, deshalb sinkt die Batteriespannung des Senders so rapide.
Zusätzlich können auch – ebenfalls dynamisch – Historiendaten (eine Woche, ein Monat) erzeugt werden. Die zugehörigen php Files findet ihr auf Github. Als Einstiegsseite wird tf.php aufgerufen.
Raspberry Pi empfängt auf 868 MHz
Für mein Projekt „Temperatur und Feuchte per Funk“, das die Sendemodule von Nathan Chantrells TinyTX nutzt, war ich auf der Suche nach einem geeigneten Empfänger, der die Daten auf einen Raspberry Pi bringt, wo sie letztendlich gespeichert werden sollen und per Webseite dargestellt werden.
Im ersten Schritt setzte ich die RPi-Shield-Bridge von Watterott ein, quasi ein vollständiger Arduino Clone auf einem Board, dass auf den Pinheader des Raspberry Pi gesteckt werden kann. Das RPi-Shield hat den Vorteil, dass bereits Pegelwandler 5V<-> 3,3V für die Kommunikation zwischen RaspPi und Arduino enthalten sind. Weiterer Vorteil sind die Arduino Shield kompatiblen Buchsenleisten.
Für meinen ersten Testaufbau benutze ich zusätzlich ein Proto-Shield auf dem ein RFM12B mit 868MHz als Empfänger steckt.
Nachdem die Software und Hardware zuverlässig funktionierten, wollte ich eine elegantere Lösung finden. Meine ersten Recherchen führten mich zum Raspberry Pi Base Station Receiver Board des Projektes OpenEnergyMonitor. Dieses Board erfüllte alle meine Anforderungen. Da ich allerdings noch einige Arduino Mini Clones rumliegen hatte, entschied ich, ein eigenes Board zu designen. In Eagle entstand eine doppelseitige Platine, die nur 8 Durchkontaktierungen hat und sich deshalb relativ leicht selbst herstellen lässt. Da nicht alle Anschlüsse des Mini benutzt werden, müssen auch nicht alle Bohrungen gemacht werden.
Für erste Tests wurde aus der WiringPi Library das SerialRead Beispiel benutzt. Zum Arduino Mini ist noch zu bemerken, dass es Versionen mit 5V oder mit 3,3V Versorgungsspannung gibt. Die 5V Versionen laufen bei mir auch mit 3,3V, allerdings läuft dann der ATMega mit 16MHz außerhalb seiner Spec. Wenn das Probleme bereitet, werde ich den Prozessor auf 8MHz internen Takt umfusen.
Einrichtung des Raspberry Pi, um Daten seriell zu empfangen
Im Raspbian Image für den Pi ist die serielle Schnittstelle standardmäßig als serielles Terminal konfiguriert. Das muss zunächst umgestellt werden.
$ sudo nano /boot/cmdline.txt
console=ttyAMA0,115200
und kgdboc=ttyAMA0,115200
löschen
$sudo nano /etc/inittab
Die Zeile auskommentieren oder löschen T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
.
Den Raspberry rebooten.
Die Installation von WiringPi wird hier erklärt.
Die Eagle Files liegen auf Github.