DHT11 Sensor: could not convert string to float

L I V E Stammtisch ab 20:30 Uhr im Chat
  • Hallo zusammen,

    ich bin nun seit einiger Zeit auch in der Welt des raspberry unterwegs und konnte bereits mit Hilfe verschiedener Tutorials einige Projekte verwirklichen. Habe mich auch an Python getraut, doch jetzt habe ich ein Problem, bei dem ich nicht weiter komme.

    Ich habe ein kleines Programm geschrieben, welches einen DHT11 Sensor ausließt und je nach Temperatur bzw. Luftfeuchtigkeit verschiedene Aktionen ausführt. Das Programm hat bis jetzt auch gut funktioniert. Jetzt sieht es so aus, als ob der DHT11 Sensor defekt ist.

    Zum auslesen nutze ich den Code von Adafruit und weise den Variablen "temp" und "humi" die Werte des Sensors zu. Das sieht wie folgt aus:

    Code
    # Sensor auslese
    def sensor():
    	global temp
    	global humi
    	output = subprocess.check_output(["/home/pi/Adafruit_Python_DHT/examples/AdafruitDHT.py", "11", "4"]);
    	print output
    	temp = float(output.split(" ")[2])
    	humi = float(output.split(" ")[7])
    	print temp
    	print humi

    Jetzt sieht es so aus, als ob der DHT11 Sensor defekt ist. Denn versuche ich die Werte abzurufen erhalte ich:

    Code
    Failed to get reading. Try again!

    Starte ich jetzt mein Programm erhalte ich als Fehlermeldung:

    Code
    ValueError: could not convert string to float

    Hier wird dann das Programm beendet.
    Klar, es werden ja keine Messwerte mehr ausgegeben, sonder eine Fehlermeldung.
    Wie kann ich denn dafür sorgen, dass das Programm trotzdem weiter läuft.
    Hätte ganz gerne eine Ausnahmeregelung, welche vorsieht Ersatzwerte zu nutzen.

    Pseudocode

    if "ValueError" then use temp = 20 and humi = 50

    Ich müsste irgendwie prüfen, ob "output" die Messwerte enthält oder die Fehlermeldung.

    Hoffe ich konnte mein Problem ausreichend gut erklären.

  • Der einfachste Weg ist den fehler abzufangen

    Code
    try:
        float(element)
    except ValueError:
        print "Keine float Zahl"

    oder du prüfst den String vorher ob es eine Floatzahl ist

    Code
    import re
    if re.match("^\d+?\.\d+?$", element) is None:
        print "Keine float Zahl"
  • Danke für die Antwort.

    Habe jetzt noch ein wenig gegoogelt und nach deinem Beispiel folgendes ergänzt.

    Code
    try:
            float(output)
            return True
    except ValueError:
            return False

    Das funktioniert erstmal.
    Verstehe ich das denn richtig, dass nach "return False" sensor() abgebrochen wird oder sorgt "except ValueError:" bereits für einen Abbruch?

  • Mit "except ValueError" wird nur die Value Error Exception gefangen. Erst mit return False wird die Methode verlassen und False zurückgegeben. :)

    Gibt es eigentlich einen besonderen Grund, dass Du das DHT Modul von Adafruit über subprocess aufrufst und nicht normal importierst und so auf die Biblothek zugreifst? Dann würdest Du Dir das ganze String gefrickel und die damit verbundenen Nachteile sparen.. :s

    Einmal editiert, zuletzt von Chris1705 (9. April 2015 um 23:11)

    • Offizieller Beitrag

    Darf ich mal fragen warum du ein python programm in einem python Programm ausrufst? vor allem da Adafruit ja ein Modul für die Teile bereitstellt (von dem du das Example aufrufst)
    so sieht das aus wenn man den ganzen "unnützen" kram aus dem example rausschmeisst

    Code
    #deine Funktion wird ersetzt durch das
    import Adafruit_DHT
    humidity, temperature = Adafruit_DHT.read_retry(sensor, pin)
    #das ist der none check
    if humidity is not None and temperature is not None:
    	print 'Temp={0:0.1f}*C  Humidity={1:0.1f}%'.format(temperature, humidity)
    else:
    	print 'Failed to get reading. Try again!'

    Der Unterschied zwischen Genie und Wahnsinn definiert sich im Erfolg.

    Einmal editiert, zuletzt von dbv (9. April 2015 um 23:17)

  • Wie dbv und Chris1705 schon erwähnten ist es ziemlich strange wieso du in einem Python Script ein anderes Python Script ausführst.

    Das was framp gepostet hast lässt sich aber leider auch nicht ohne weiteres verwenden, da der TE eine Funktion ausführt und 'output' nicht außerhalb der Funktion verfügbar ist.
    An dieser Stelle sollte man aber auch erwähnen das 'global' nicht verwendet werden sollte.

    Das von dbv gepostete Beispiel ist vielleicht etwas zu heavy zu verstehen für Anfänger, also gerade die Formatierungen..
    Auch fehlt mir in dem Beitrag der Hinweiß das Adafruit_DHT für Python installiert sein muss also innerhalb eins von Python augerufenen PATH sein muss, denn sonst kann er es nicht importieren.
    Da er aber das example Script, wo dbv die Zeilen her hat, direkt ausführt, gehe ich jetzt mal davon aus das der TE nicht weiß wie er das installiert.
    Also:

    Code
    cd /home/pi/Adafruit_Python_DHT/
    
    
    sudo python setup.py install

    dbv erwähnt leider ebenfalls nicht das 'sensor' und 'pin' gesetzt werden müssten. Deshalb hier noch mal ein Anwendungsbeispiel:

    [code=php]
    #!/usr/bin/python

    import Adafruit_DHT

    GPIOpin = 4
    SensorType = 11 #DHT11 = 11 , DHT22 = 22

    def sensor(type, pin):
    humidity, temperature = Adafruit_DHT.read_retry(type, pin)
    print 'Temp: {} *C' . format(temperature)
    print 'Humidity: {} %' . format(humidity)

    try:
    sensor(SensorType, GPIOpin)
    except Exception, error:
    print error
    [/php]


    Aber wie immer gibt es etliche Möglichkeiten.

  • Das sind ja mal ein paar Vorschläge.

    Klar darfst du fragen warum ich ein python Programm in einem python Programm ausführe. Die Antwort ist recht einfach. Ich wusste nicht, dass man das Modul importieren kann und habe angenommen man braucht immer den gesamten code aus examples. Da ich aber insbesondere den ersten Abschnitt nicht verstehe, wollte ich mir so die Messwerte holen und weiß immer wo das Programm dafür liegt. Habe ja auch nur per git clone den Adafruit Ordner heruntergeladen und kann mich jetzt nicht daran erinnern etwas für Python installiert zu haben.

    Habe noch vor der Antwort von meigrafd das Beispiel von dbv getestet. Das sieht jetzt so aus mit import Adafruit_DHT.

    Code
    # Sensor auslese
    def sensor():
        global temp
        global humi
        humi, temp = Adafruit_DHT.read_retry(11, 4)
        if humi is not None and temp is not None:
                 print 'temp={0:0.1f}*C  humi={1:0.1f}%'.format(temp, humi)
        else:
                 print 'Failed to get reading. Try again!'

    So läuft das Programm auch. Bekomme nur im Moment keine Werte ausgegeben, da der DHT11 nicht funktioniert.

    Warum sollte man denn global nicht verwenden? Da ich "temp" und "humi" noch außerhalb von sensor() benutze, hatte ich sonst das Problem, dass beim ausführen immer gemeckert wurde.

  • Warum sollte man denn global nicht verwenden? Da ich "temp" und "humi" noch außerhalb von sensor() benutze, hatte ich sonst das Problem, dass beim ausführen immer gemeckert wurde.

    Weil ... Darum :D

    Dann machste das so:
    [code=php]
    #!/usr/bin/python

    import Adafruit_DHT

    GPIOpin = 4
    SensorType = 11 #DHT11 = 11 , DHT22 = 22

    def sensor(type, pin):
    hum, temp = Adafruit_DHT.read_retry(type, pin)
    return hum, temp

    try:
    humidity, temperature = sensor(SensorType, GPIOpin)
    print 'Temp: {} *C' . format(temperature)
    print 'Humidity: {} %' . format(humidity)
    except Exception, error:
    print error
    [/php]

  • Aha OK. :D

    Dann funktioniert es ja jetzt erstmal.
    Werde mal gucken was ich mit den Vorschlägen noch mache.
    Denke das Thema hat sich dann erstmal erledigt und danke für die Hilfe.

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!