Probleme mit DHT22 Sensor

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Drezael
User
Beiträge: 11
Registriert: Dienstag 4. März 2014, 06:35

Hallo,

ich habe folgendes Problem:
Ich möchte einen DHT22 Sensor http://www.exp-tech.de/Sensoren/AM2302- ... 084a6e9e01

via Python auslesen. Soweit klappt alles ganz gut. Nur das nach ein paar mal auslesen der Sensor anscheinend einen "None" Wert zurück gibt und mich das ganze aus meinem Script schmeißt.

Den Sensor spreche ich zum Testen über folgendes Script an:

Code: Alles auswählen

#!/usr/bin/env python
import dhtreader
import os
from time import sleep
type = 22
pin = 4
while True:
        os.system("clear")
        dhtreader.init()
        t, h = dhtreader.read(type, pin)
        if t == None:
                print ("Es konnte kein Wert ermittelt werden")
                sleep(3)
                continue
        else:
                temp = ("{0}".format(t))
                temparatur = round(float(temp), 1)
                print temparatur
                sleep(3)
        continue
Nach ein paar erfolgreichen Ausgaben kommt dann plötzlich:

Traceback (most recent call last):
File "test.py", line 10, in <module>
t, h = dhtreader.read(type, pin)
TypeError: 'NoneType' object is not iterable

Ich hoffe Ihr könnt mir helfen so das das Script wenn es den Wert "None" vom Sensor bekommt nicht abbricht sondern die Schleife wieder von vorne startet.

Vielen Dank schon mal im vorraus für eure Hilfe.
BlackJack

@Drezael: Du musst den Rückgabewert testen und nicht bedingungslos auf die beiden Namen `t` und `h` entpacken. Denn wie man sieht funktioniert das entpacken von `None` auf zwei Namen nicht. Was sollte da auch passieren‽

Sonstige Anmerkungen: Einrückungstiefe ist per Konvention vier Leerzeichen pro Ebene. Siehe auch den Style Guide for Python Code.

`type` ist der Name einer eingebauten Funktion, den sollte man nicht an etwas anderes binden. Der Wert könnte sowieso etwas präziser benannt werden.

Zum starten von externen Programmen sollte das `subprocess`-Modul verwendet werden, welches eingeführt wurde um diverse andere Arten zu ersetzen, inklusive `os.system()`. Wobei der Aufruf von ``clear`` nicht schön ist. Das löscht dem Benutzer den Inhalt vom Terminal, was eventuell nicht erwünscht ist.

Soll der Sensor tatsächlich vor jedem Auslesen aufs Neue initialisiert werden? Ich denke mal das gehört vor die Schleife.

Abkürzungen sollte man bei Namen vermeiden, solange sie nicht allgemein bekannt sind. `t` und `h` sind zu nichtssagend. Bei `t` kann man aus dem Programmkontext noch erkennen wie der Wert eigentlich benannt sein sollte, während man bei `h` nur raten kann, sofern man nicht den Sensor und die API von dem `dhtreader`-Modul kennt.

Die Klammern bei der Ausgabe wenn kein Wert ermittelt werden konnte, gehören dort nicht hin.

Beide ``continue``-Anweisungen sind überflüssig, weil der Programmfluss dort sowieso schon am Ende der Schleife angekommen ist, also auch ohne das jeweilige ``continue`` als nächster Schritt die Schleife von vorne beginnt.

In beiden Bedingungszweigen wird am Ende drei Sekunden geschlafen. Der Funktionsaufruf kann also *einmal* nach der Schleife stehen.

Was da mit `t` gemacht wird, ist ziemlicher Unsinn. Das ist ein ganzzahliger Wert, den erst in eine Zeichenkette und die dann in eine Gleitkommazahl zu wandeln macht keinen Sinn. Einen Wert ohne Nachkommastellen auf eine Stelle nach dem Komma zu runden ist ebenfalls sinnfrei. Und `temparatur` ist falsch geschrieben.

Ich komme dann bei so etwas heraus (ungetestet):

Code: Alles auswählen

#!/usr/bin/env python
from subprocess import call
from time import sleep
import dhtreader


def main():
    dht_sensor_type = 22
    dht_sensor_pin = 4
    dhtreader.init()
    while True:
        call('clear')
        sensor_values = dhtreader.read(dht_sensor_type, dht_sensor_pin)
        if sensor_values:
            temperature, _humidity = sensor_values
            print temperature
        else:
            print 'Es konnte kein Wert ermittelt werden.'
        sleep(3)


if __name__ == '__main__':
    main()
Drezael
User
Beiträge: 11
Registriert: Dienstag 4. März 2014, 06:35

Hallo,

erst mal vielen Dank für dein schnelle und gut erläuternde Erklärung. Da ich in Sachen Python noch ein ziemliche Anfänger bin hilft mir das sehr weiter.
Was du zu t und h sagt da habe ich mich wie genau bei dem Rest des Scripts bis auf ein paar kleine Änderungen ans Orginalscript gehalten.
https://github.com/adafruit/Adafruit-Ra ... ver_Python

Was das runden des Wertes angeht so hab ich das deshalb gemacht da beim puren Auslesen des Sensors mir zb. ein Wert von 23,526214252 zurück gegeben wird mit dem ich im weiteren leider so nichts anfangen kann.
BlackJack

@Drezael: Das Modul gibt *zwei* *ganzzahlige* Werte in einem Tupel zurück. Die Temperatur ist also 23 Grad, ohne Nachkommastellen. Die andere Zahl ist für die Feuchtigkeit die der Sensor misst.

Edit: Ups, da habe ich mich verlesen, es sind tatsächlich zwei Gleitkommawerte. Deine Behandlung des Wertes wird dadurch aber nicht wirklich sinnvoller, denn eine Gleitkommazahl in eine Zeichenkette zu wandeln, nur um diese danach wieder in eine Gleitkommazahl zu wandeln ist genau so sinnfrei. Und statt den Wert zu runden, solltest man besser die Ausgabe entsprechend formatieren, denn beim Runden auf eine Nachkommastelle muss der Wert nicht zwangsläufig aus eine dezimale Nachkommastelle gerundet werden, da die interne Darstellung zur Basis 2 nicht alle Brüche in Dezimaldarstellung verlustfrei abbilden kann.

Die Ausgabezeile müsste dann wie folgt angepasst werden:

Code: Alles auswählen

            print '{0:.1f}'.format(temperature)
Antworten