AchWo.de

Sie sind hier: Startseite > Computer > OneWire Sensoren am RaspberryPi

OneWire Sensoren am RaspberryPi

Der RaspberryPi bietet sich nicht nur als Bastelrechner für allerlei Spielereien an. Man kann ihn durchaus auch für dauerhafte Projekte verwenden.

So auch hier. Im digitalen Zeitalter sind mittlerweile auch einfache Temperatursensoren angekommen. Wo man "früher" noch mit NTC, PTC und Messschaltungen sowie A/D-Wandlern hantierten musste, gibt es heute chicke Sensoren, die das ganze Messgedöns schon auf einem winzigen Chip vereint haben, dazu noch fertig abgeglichen und direkt einsatzbereit.

DS18S20 - 1-Wire Digital Thermometer (hier von Pollin)

Wie bei der analoge Variante werden nur 2 Anschlüsse benötigt. Aber warum heißen denn die Dinger "OneWire"? Nun, gespart wird heute überall und so hat man einfach die "Masse" - also den gemeinsamen "Rückleiter" in der Bezeichnung weggelassen. Deshalb wird auch der I2C-Bus als "Zweidrahtbus" bezeichnet, obwohl er streng genommen 3 Adern hat.

Was ist nun OneWire?

OneWire ist ein serielles Protokoll, bzw. eine Schnittstelle, mit dem man Daten über nur eine aktive Leitung schicken und empfangen kann.Bei einfachen Sensoren erfolgt sogar die Stromversorgung über diese eine Leitung - der Rückleiter wird ja durch die Masseleitung dargestellt. Das hat gegenüber der Analogtechnik mehrere Vorteile:

  1. Der Leitungswiderstand hat keinen Einfluss auf die Messgenauigkeit
  2. Störungen führen nicht zu falschen Messergebnissen (sollte das digitale Signal nicht stimmen und die Prüfsumme fehlerhaft sein, wird es einfach verworfen oder ein Fehler angezeigt).
  3. Es können sehr viele Sensoren parallel an eine einzige Leitung angeschlossen werden. Durch die Adressierung und eindeutige Seriennummern der Sensoren ist eine korrekte Zuordnung gegeben.
  4. Auf der Controller-Seite reicht ein einfacher serieller Eingang / Ausgang, der sich als Offener Kollektor mit Software ansteuern lässt. Eine besondere Hardware oder ein spezielles Interface ist nicht nötig. Daher lässt sich ein beliebiger GPIO-Pin des RaspberryPi oder eines Arduino verwenden.
  5. Der Betriebsspannungsbereich liegt bei diesen Sensoren zwischen 2,8 und 5,5 Volt und deckt damit die üblichen 3,3V und 5V Logikpegel ab.

Zur genaueren Funktionsweise dieser Sensoren suche man sich ein Datenblatt, z. B. hier: https://www.pollin.de/productdownloads/D180014D.PDF

Hoppla: Hatten wir oben nicht von "einer" Leitung plus Masse gesprochen? Wieso haben die Dinger denn 3 Anschlüsse?
Man kann diese Sensoren auch mit einer getrennten Stromversorgung betreiben. Das bietet sich zum Beispiel an, wenn man extreme Temperaturen (z. B. im Gefrierschrank oder im Heißwasserspeicher) messen will und daher der interne Kondensator für "parasite power" dann u. U. nicht mehr ausreicht. Auch kann man dann die Abfrageintervalle kürzer setzen und den Pull-Up Widerstand vergrößern, sowie mehr Sensoren parallel schalten, als dies ohne den dritten Anschluss möglich wäre.

Zur Schaltung

 Bild folgt noch :-)

Software

 Um den DS18S20 mit dem RaspberryPi auslesen zu können, reicht es aus, einfach nach den Sensordaten im Ordner /sys/devices/w1_bus_master1/ nachzusehen:

pi@rpi:~ $ ls -lah /sys/devices/w1_bus_master1/
insgesamt 0
drwxr-xr-x  8 root root    0 Jul 10 16:05 .
drwxr-xr-x 11 root root    0 Feb 14  2019 ..
drwxr-xr-x  4 root root    0 Jul 10 16:05 10-00080172262d
drwxr-xr-x  4 root root    0 Jul 10 16:06 10-000801727e63
drwxr-xr-x  4 root root    0 Jul 10 16:06 10-000801728a49
drwxr-xr-x  4 root root    0 Jul 10 16:06 10-000801d42828
drwxr-xr-x  4 root root    0 Jul 10 16:06 10-000801d447e5
...

Hier findet man dann für jeden Sensor ein eigenes Unterverzeichnis.

Liest man die jeweilige w1_slave Datei per cat-Befehl aus, bekommt man direkt die Temperatur angezeigt:

pi@rpi:~ $ cat /sys/bus/w1/devices/10-00080172262d/w1_slave
2a 00 4b 46 ff ff 0d 10 d1 : crc=d1 YES
2a 00 4b 46 ff ff 0d 10 d1 t=20937

Hier  sind das 20,937 ºC - man muss sich vor der drittletzten Stelle noch ein Komma einbauen.

Und auch negative Temperaturen werden korrekt dargestellt:

pi@rpi:~ $ cat /sys/bus/w1/devices/10-000801d447e5/w1_slave
d0 ff 4b 46 ff ff 0a 10 32 : crc=32 YES
d0 ff 4b 46 ff ff 0a 10 32 t=-23875

Hier der schon oben im Text erwähnte Gefrierschrank, mit -23,875 ºC

In der ersten Zeile steht noch die CRC-Prüfung - hier sollte man beachten, dass ein YES am Ende steht, sonst stimmt etwas mit dem Auslesen nicht.

Script für Check_MK

Hier nun ein Script, das einen Sensor ausliest, die CRC prüft und den Wert an Check_MK weitergibt. Falls die CRC nicht stimmt, wird das Auslesen bis zu 5 mal wiederholt.

#!/bin/bash

# Auslesen des Sensors DS1820 im Keller_02

sensorname="Temperatur im Solarspeicher 1"
onewiredir=/sys/bus/w1/devices/

# Device-ID - Seriennummer des Sensors
deviceid=10-000801728a49

# Warn und Crit-Wert
hwarntemp=85
lwarntemp=50
hcrittemp=90
lcrittemp=45

# Startwerte
status=3
temp=0
iteration=5

# Los gehts

# Pruefe ob Verzeichins existiert
if [ -d $onewiredir$deviceid ]; then

    i=0
    # Prüfe CRC, wenn fehlerhaft prüfe weitere $iteration mal
    while [ $i -lt $iteration ]; do

    # Lese Daten aus, berechne CRC und Temperaturrohwert
    rawdata=`cat $onewiredir$deviceid/w1_slave`
    crc=${rawdata:36:3}
    tempint=`echo $rawdata | tail -n1 | sed 's/.*t=//'`

        if [ "$crc" = "YES" ]; then
        i=$iteration
        else
    i=$[$i+1]
    sleep 1
    fi

    done

        # Wenn nach Prüfung CRC immer noch fehlerhaft, Fehler ausgeben
        if  [ "$crc" = "NO " ]; then
        status=3
        echo -n UNKNOWN - Sensor CRC fehlerhaft

        else

        # Berechne Temperatur aus dem Rohwert
        temp=`echo "scale=2; $tempint/1000" | bc -l`
        tempraw=$(($tempint /1000))

            # Prüfe ob kritischer Wert erreicht
            if [ "$tempraw" -gt $hcrittemp ] || [ "$tempraw" -lt $lcrittemp ] ; then
            status=2
            echo -n CRITICAL - $sensorname = $temp C
            else

                # Prüfe ob Warnwert erreicht
                if [ "$tempraw" -gt $hwarntemp ] || [ "$tempraw" -lt $lwarntemp ] ; then
                             status=1
                            echo -n WARNING - $sensorname = $temp C
                            else
                status=0
                echo -n OK - $sensorname = $temp C
                fi
            fi
        fi
else

# Wenn Verzeichnis nicht vorhanden, bzw Sensor nicht erkannt wurde
echo -n UNKNOWN - Sensor wurde nicht erkannt
temp=0

fi

# Ausgabe der Servicedaten
echo " |Temp=$temp;$lwarntemp:$hwarntemp;$lcrittemp:$hcrittemp;0;100"

# Übergabe Exitwert
exit $status

nach oben