Projekt PomodoPi – Der Feuchtigkeitssensor: Eingemachtes aus dem Datengarten

Hallo zusammen! Wie beim letzten Mal angedroht, gibt es heute eine größere Ladung Nerdkram, nämlich die technischen Details, die hinter dem Bodenfeuchtigkeitssensor stecken. Zuerst schauen wir uns die Verdrahtung an. Dieses Bild kennen Sie schon aus dem letzten Artikel, aber werfen Sie noch einmal einen Blick auf das offene Ende des Anschlusskabels:

vh400

Der Sensor wird mit Gleichstrom versorgt, Plus und Minus, Sie kennen das. Die Elektrickser nennen Minus auch gern mal „Masse“, um sich von derselben abzuheben. Plus ist der Draht mit der roten Isolierung, Minus alias Masse ist nicht der Draht mit der schwarzen Isolierung – was mir prompt auffällt, nachdem ich alles verkabelt habe und nichts funktioniert. Also, wenn gar nichts mehr hilft: Handbuch lesen. Darin steht: der nicht isolierte Draht gehört an Masse und der schwarze ist Output. Output bedeutet: dieser Draht führt umso mehr Spannung, je höher die Feuchtigkeit ist, die der Sensor misst.

Am Raspberry Pi können wir eine Versorungsspannung von 3,3 oder 5 Volt abgreifen, für den Feuchtigkeitssensor reichen 3,3 Volt. Also schnell mal ausprobieren, Plus und Minus am Raspberry anschließen, Output mit einem Multimeter messen: der knochentrockene Sensor liefert 0 Volt, wie erwartet. Sensor in Blumenerde: 0,9 Volt. Sensor ins Arbeitszimmeraquarium: 2,8 Volt. Ich hatte eigentlich erwartet, dass bei völligem Untertauchen unter Wasser die kompletten 3,3 Volt am Outputdraht anliegen, aber egal – wir rechnen das später in der Software eh in Prozentwerte um, da können wir das anpassen.

Wertewandel

Es wäre schön, wenn wir die drei Drähte einfach an den Raspberry anschließen und die Spannung auslesen könnten. Eine steigende oder fallende Spannung ist aber ein analoger Messwert, und damit können digital arbeitende Systeme wie Computer nix anfangen. Wir brauchen einen Analog-zu-Digital-Verwandler! Völlig unzufällig habe ich einen rumliegen. Er ist klein, schwarz, vielbeinig und sehr zutraulich:

mcp3008

Sein Name ist MCP3008, und er ist für unseren Zweck schon ein bisschen überdimensioniert, denn er kann 8 analoge Messwerte simultan ins Digitalische übersetzen. Auf dem Bild sehen Sie, dass er auf der Oberseite eine kleine Delle hat. Das Beinchen, das dieser Delle am nächsten ist, heißt Pin 1. Von dort werden die Pins gegen den Uhrzeigersinn durchgezählt. An den Pins 1 bis 8 legt man die analogen Eingangsspannungen an, die übrigen Pins dienen zum Anschluss der Versorgungsspannung und der Kommunikation mit dem Raspberry Pi. Schematisch sieht das so aus (draufklicken zum Vergrößern):

vegetronix_Schaltplan

 

Auf dieser Schemazeichnung sind die Pins nicht mit ihren Nummern, sondern mit ihrer Funktion bezeichnet. Pin 1 heißt hier CH0 (Channel 0). Der Outputdraht unsers Feuchtigkeitssensors wird genau dort angeschlossen. Die Pins 2 bis 8 alias Channel 1 bis 7 benutzen wir nicht. Um Störungen zu vermeiden, verbinden wir sie allesamt mit Minus (unter Bastlern verwenden Sie bitte die Formulierung „auf Masse ziehen“, das gibt mehr Street Cred). Auf der rechten Seite sehen Sie schematisch die Anschlüsse des Raspberry Pi. Es sind vierzig an der Zahl, auf dem Raspberry Pi sind sie in zwei Reihen zu je 20 Pins angeordnet, und zwar so (wieder klicken zum Vergrößern):

rasp_b_pinout

 

Auch hier sind die Pins wieder mit Nummern und zusätzlich einer Bezeichnung versehen. Jetzt kann’s losgehen, verbinden Sie

  • MCP3008 Pin 1 (CH0) mit dem Output-Draht des Feuchtigkeitssensors
  • MCP3008 Pin 2 – 8 (CH1 – CH7), Pin 9 (AGND) und Pin 14 (DGND) und den nicht isolierten Draht des Feuchtigkeitssensors mit Masse (Pin 6 am Raspberry) – GND steht für Ground = Minus = Masse
  • Pin 15 (VRef), Pin 16 (VDD) und den rot isolierten Draht des Feuchtigkeitssensors mit 3,3 Volt (Pin 1 des Raspberry)
  • Pin 10 (CS) mit Pin 26 (CE) des Raspberry
  • Pin 11 (Din) mit Pin 19 (MOSI) des Raspberry
  • Pin 12 (Dout) mit Pin 21 (MISO) des Raspberry
  • Pin 13 (CLK) mit Pin 23 (SCLK) des Raspberry.

Das Verkabeln können Sie am besten auf einem Breadboard üben. Das ist ein Steckbrett, auf das Sie elektronische Komponenten aufstecken können, um sie dann mit Drahtbrücken (jumper wires) zu verbinden. So testen Sie Schaltungen, ohne gleich zum Lötkolben greifen zu müssen:

breadboard

Etymologische Abschweifung: Die Dinger heißen übrigens Breadboard, weil man früher tatsächlich Frühstücksbrettchen aus Holz für diesen Zweck verwendet hat. Wiederverwendbare Steckbrettchen aus Kunsstoff gibt es seit den 1970er Jahren.

Wenn alles funktioniert, löten Sie die Schaltung auf eine kleine Experimentierplatine auf. Hier ist meine Version – Profis können das  wesentlich eleganter verdrahten, aber es funktioniert:

mcp3008-board

Damit sind wir mit der Hardwarebastelei fertig. Jetzt müssen wir dem Raspberry aber noch beibiegen, wie er an die Messwerte kommt, die ihm der Analog-Digital-Wandler MCP3008 jetzt zur Verfügung stellt.

Öffentlicher Datennahverkehr

An dieser Stelle müssen wir kurz über Bussysteme sprechen. Bussysteme sind sehr praktisch, besonders wenn die Fahrpläne eingehalten werden. In Computern arbeiten gleich mehrere Bussysteme. Das sind eine Art Datenstraßen mit mehreren Datenverkehrsteilnehmern und einer Steuerzentrale. Die Steuerzentrale ist der Computer (Master), die Verkehrsteilnehmer sind angeschlossene Komponenten (Slaves oder Clients). Der Master kann die Slaves anhand einer eindeutigen Nummer (ID) identifizieren und von ihnen verlangen, dass sie ihre Daten bei der Zentrale abliefern. Auch der Raspberry Pi hat, so klein er auch ist, mehrere Bussysteme. Um die Daten des Feuchtigkeitssensors abzufragen, nutzen wir eines, das SPI heißt (Serial Peripheral Interface). Um das SPI-Bussystem zu aktivieren, führen Sie auf dem Raspberry das Kommando

sudo raspi-config

aus. Es erscheint ein Textmenü, in dem Sie Advanced Options auswählen, und im folgenden Untermenü SPI. Bestätigen Sie die Sicherheitsabfrage mit Yes und verlassen Sie raspi-config. Jetzt starten Sie den Raspberry einmal neu (mit dem Kommando „sudo reboot“). Nach dem Neustart ist das SPI-Bussystem an Bord und wir sind startklar.

Der Worte sind genug gewechselt, lasst Daten sprechen

Mit einem erfreulich kurzen Programm in der Sprache Python weisen wir den MCP3008 an, uns über den SPI-Bus die Daten zu geben, die der an CH0 angeschlossene Sensor liefert:

#!/usr/bin/python
# coding=utf-8

import spidev
import time

spi = spidev.SpiDev()
spi.open(0,1)
antwort = spi.xfer([1,128,0])

if 0 <= antwort[1] <=3:
wert = ((antwort[1] * 256) +antwort[2]) * 0.00322
fprozent = ((wert / 2.82) * 100)
#Substratfeuchte in Prozent ausgeben
print fprozent

else:

pass

Der Messewert in Volt steht in der Variable wert. Da ich empirisch ermittelt habe (durch Eintauchen ins Aquarium), dass der Sensor bei maximaler Umgebungsfeuchtigkeit 2,82 Volt liefert, rechne ich die Voltzahl in Prozent um. Dieser Wert steht in der Variable fprozent und wird ausgegeben:

49.2134751773

Die Anzahl der Nachkommastellen täuscht eine wesentlich höhere Genauigkeit vor, als der Sensor tatsächlich erreicht, deshalb werde ich sie komplett abschneiden und nur mit dem ganzzahligen Vorkommawert weitermachen. Danach wird der Wert in eine simple Textdatei geschrieben und auf einen Internet-Server kopiert, denn ich möchte die Daten natürlich im WWW sehen können. Das erledigt dieses Programm (diesmal nicht in Python, sondern in Bash geschrieben):

#!/bin/bash

WDIR=/usr/local/shellscripts/moisturesensor
ETCDIR=$WDIR/etc/
OUTDIR=$WDIR/output

MOISTPROZENT=$($WDIR/moist_einmal.py|cut -f1 -d\.);
logger „$MOISTPROZENT Prozent Substratfeuchte“
echo $MOISTPROZENT > $ETCDIR/moisture-vh400-1.text

#Wert an Webserver kuehnast.com uebertragen, die weitere Verarbeitung
#findet dort statt

rsync -avz -e ssh $ETCDIR/moisture-vh400-1.text kuehnast.com:/usr/local/shellscripts/moisturesensor/etc/

Dieses Programm ruft das Sensor-Abfrageprogramm moist_einmal.py auf und merkt sich von dessen Ausgabe alles, was vor dem Punkt steht (cut -f1 -d\.), in der Variable MOISTPROZENT. Deren Inhalt wird in die Datei moisture-vh400-1.text geschrieben, und die wird auf den Webserver kopiert, in ein Verzeichnis namens /usr/local/shellscripts/moisturesensor/etc/.

Jetzt das ganze in bunt, bitte.

Auf dem Webserver angekommen, wollen wir aus den Sensordaten (die übrigens alle 60 Sekunden eintrudeln – ich habe definitiv den bestüberwachten Gummibaum Deutschlands) anschauliche Grafiken erstellen. Damit man Verlaufsgrafiken machen kann, muss man die Messwerte über einen längeren Zeitraum sammeln, am besten in einer kleinen Datenbank. Ich nehme für diesen Zweck eine sogenannte Round-Robin-Datenbank (RRD). Das sind Datenbanken mit einer festen Größe (sagen wir, groß genug für die Daten eines Jahres – was älter als ein Jahr ist, fliegt automagisch aus der Datenbank raus). Dabei sind die jüngsten Daten minutengenau verfügbar, etwas ältere Daten werden auf den 5-Minuten-Durchschnitt gemittelt, noch ältere auf einen Stundenmittelwert und so weiter. Die benötigte Software heißt RRDTool und ist bei Linux serienmäßig an Bord, sowohl auf dem Raspberry als auch auf dem Webserver. Das folgende Skript wird nur einmal benötigt: es legt die Round-Robin-Datenbank mit dem Namen moisture.rrd an, die die Messwerte des Feuchtigkeitssensors aufnehmen soll:

#!/bin/bash

WDIR=/usr/local/shellscripts/moisturesensor
ETCDIR=$WDIR/etc/
OUTDIR=$WDIR/output

rrdtool create $ETCDIR/moisture.rrd –step 60 \
DS:data1:GAUGE:120:0:100 \
DS:data2:GAUGE:120:0:100 \
RRA:AVERAGE:0.5:1:2160 \
RRA:AVERAGE:0.5:5:2016 \
RRA:AVERAGE:0.5:15:2880 \
RRA:AVERAGE:0.5:60:8760 \
RRA:MAX:0.5:1:2160 \
RRA:MAX:0.5:5:2016 \
RRA:MAX:0.5:15:2880 \
RRA:MAX:0.5:60:8760

Jetzt benötigen wir noch ein kleines Programm, das einmal pro Minute den Messwert aus der Datei moisture-vh400-1.text liest, ihn an die RRD verfüttert und die Verlaufsgrafik erzeugt. So sieht es aus:

#!/bin/bash

WDIR=/usr/local/shellscripts/moisturesensor
ETCDIR=$WDIR/etc/
OUTDIR=$WDIR/output

MOISTPROZ=$(cat $ETCDIR/moisture-vh400-1.text);
echo „$MOISTPROZ Prozent Substratfeuchte“

rrdtool update $ETCDIR/moisture.rrd N:$MOISTPROZ:U

for i in -4h -12h -24h -7d -30d -90d -180d -360d; do

rrdtool graph $OUTDIR/moisture$i.gif –border=0 -c GRID#ffffff00 -c BACK#ffffff –lazy –slope-mode –start $i –title „Bodenfeuchtigkeit ($i)“ –vertical-label „Prozent“ -w 400 -h 140 \
DEF:data1=$ETCDIR/moisture.rrd:data1:AVERAGE \
DEF:data2=$ETCDIR/moisture.rrd:data2:AVERAGE \
CDEF:shading2=data1,0.98,* AREA:shading2#0000F9:“Bodenfeuchtigkeit (aktuell $MOISTPROZ Prozent)\n“ \
CDEF:shading10=data1,0.90,* AREA:shading10#0F0FF9 \
CDEF:shading15=data1,0.85,* AREA:shading15#1818F9 \
CDEF:shading20=data1,0.80,* AREA:shading20#2D2DF9 \
CDEF:shading25=data1,0.75,* AREA:shading25#3C3CF9 \
CDEF:shading30=data1,0.70,* AREA:shading30#4B4BF9 \
CDEF:shading35=data1,0.65,* AREA:shading35#5A5AF9 \
CDEF:shading40=data1,0.60,* AREA:shading40#6969F9 \
CDEF:shading45=data1,0.55,* AREA:shading45#7878F9 \
CDEF:shading50=data1,0.50,* AREA:shading50#8787F9 \
CDEF:shading55=data1,0.45,* AREA:shading55#9696F9 \
CDEF:shading60=data1,0.40,* AREA:shading60#A5A5F9 \
CDEF:shading65=data1,0.35,* AREA:shading65#B4B4F9 \
CDEF:shading70=data1,0.30,* AREA:shading70#C3C3F9 \
CDEF:shading75=data1,0.25,* AREA:shading75#D2D2F9 \
CDEF:shading80=data1,0.20,* AREA:shading80#E1E1F9 \
CDEF:shading85=data1,0.15,* AREA:shading85#E1E1F9

done

rsync -av $OUTDIR/*.gif /www/kuehnast/pomodopi

Das Skript generiert Bilder für mehrere Übersichtszeiträume: für 4 Stunden, 24 Stunden, 7 Tage, 30 Tage und so weiter bis zu einer Jahresübersicht. Einen Graph über die letzten 7 Tage kennen Sie schon aus dem letzten Artikel:

moisture-7d-2

Sie finden meine aktuellen Grafiken (zumindest vorläufig) unter http://kuehnast.com/pomodopi/. Das ist allerdings im Moment keine richtige Webseite, sondern nur die nackte Liste der Verlaufsgrafiken – der Bau einer kleinen Webseite für das PomodoPi-Projekt steht noch auf der To-do-Liste.

Bis zum Nächsten Mal!

trenner_bohne