Forum: Mikrocontroller und Digitale Elektronik Mehrere DHT-Sensoren funktionieren nicht am RasPi-Pico


von Mike W. (mike93)


Lesenswert?

Hi,

ich will zwei (am besten vier) DHT11 Sensoren an meinem RasPi Pico 
betreiben. Leider klappt das nicht. Benutze ich nur einen Sensor, messe 
ich plausible Temperaturen und Luftfeuchtigkeiten. Sobald ich den Code 
aber auf 2 oder 3 Sensoren erweitere, erhalte ich nur noch 0 für Temp 
und Hum für alle Sensoren. Kann mir jemand erklären, warum das so ist?

Falls es an der Wahl der Sensoren liegt: Kann man mehrere BME280er 
gleichzeitig benutzen?
1
from machine import Pin
2
from time import sleep
3
import dht
4
import sdcard
5
import uos
6
7
## init sensors
8
sensor1 = dht.DHT11(Pin(21, Pin.IN, Pin.PULL_UP))
9
sensor2 = dht.DHT11(Pin(20, Pin.IN, Pin.PULL_UP))
10
#sensor3 = dht.DHT11(Pin(19))
11
#sensor4 = dht.DHT11(Pin(18))
12
13
## init SD-card
14
CS = machine.Pin(9, machine.Pin.OUT)
15
spi = machine.SPI(1,baudrate=1000000,polarity=0,phase=0,bits=8,firstbit=machine.SPI.MSB,sck=machine.Pin(10),mosi=machine.Pin(11),miso=machine.Pin(8))
16
17
sd = sdcard.SDCard(spi,CS)
18
19
vfs = uos.VfsFat(sd)
20
uos.mount(vfs, "/sd")
21
22
## measure loop
23
while True:
24
    ## measureing starts
25
    sensor1.measure
26
    sensor2.measure
27
    #sensor3.measure
28
    #sensor4.measure
29
    ## measured values to variables
30
    # Temp:
31
    temp1 = sensor1.temperature() 
32
    temp2 = sensor2.temperature()
33
    #temp3 = sensor3.temperature()
34
    #temp4 = sensor4.temperature() 
35
    # Hum:
36
    hum1 = sensor1.humidity()
37
    hum2 = sensor2.humidity()
38
    #hum3 = sensor3.humidity()
39
    #hum4 = sensor4.humidity()
40
    # print temps and hums
41
    print("Temperature 1: {} °C    Humidity 1: {}%".format(temp1,hum1))
42
    print("Temperature 2: {} °C    Humidity 2: {}%".format(temp2,hum2))
43
    #print("Temperature 3: {} °C    Humidity 3: {}%".format(temp3,hum3))
44
    #print("Temperature 4: {} °C    Humidity 4: {}%".format(temp4,hum4))
45
    ## open file
46
    file = open("/sd/data.txt", "a")
47
    print("Writing to data on SDcard.txt...")
48
    file.write("Temperature 1: {} °C    Humidity 1: {}%".format(temp1,hum1))
49
    file.write("Temperature 2: {} °C    Humidity 2: {}%".format(temp2,hum2))
50
    #file.write("Temperature 3: {} °C    Humidity 3: {}%".format(temp3,hum3))
51
    #file.write("Temperature 4: {} °C    Humidity 4: {}%".format(temp4,hum4))
52
    file.close()
53
    
54
    print("Done")
55
    print("")
56
    sleep(3) # sleep for 3 sec.

von Michael H. (mha1)


Lesenswert?

Das Problem wird vermutlich in "import dht" liegen. Kann die Library 
überhaupt mit mehreren DHT Sensoren umgehen?

Ich habe auf einem Breadboard parallel zwei DHT21 und zwei BM280 laufen. 
Die endgültige Platine kommt später. Allerdings habe ich es in C selbst 
programmiert. Ich nutze eine eigene Library für die DHT21 (mit Nutzung 
der PIOs). Das ganze läuft unter FreeRTOS SMP.

Ich hatte Anfangs ebenfalls Probleme. Die waren aber eher hausgemacht. 
Das Timing der DHT21, die ich zum Test zur Verfügung hatte war leicht 
unterschiedlich. Mit 3,3V hatte ich bei den DHT21 immer wieder mal 
Bitfehler. Erst mit 5V + Pegelwandlern hatte ich ein stabiles Signal.

von Rainer W. (rawi)


Lesenswert?

Mike W. schrieb:
> Falls es an der Wahl der Sensoren liegt: ...
Es kann auch an deinem Aufbau liegen (Kabellänge). Bei 3V3 ist der DHT11 
etwas pingelig.

> Kann man mehrere BME280er gleichzeitig benutzen?
Ja,  ein bisschen Beschäftigung mit den Grundlagen von I2C (NXP UM10204
I2C-bus specification and user manual) und mit dem Datenblatt des BME280 
(Kap. 6.2 I²C Interface) beantwortet dir deine Frage sofort.

https://www.nxp.com/docs/en/user-guide/UM10204.pdf
https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bme280-ds002.pdf

von J. S. (jojos)


Lesenswert?

Nimm mal die measure Aufrufe raus, die werden in temperature() schon 
implizit aufgerufen. Zu schnell nacheinander aufgerufen liefert measure 
einen Fehler.
Sonst sehe ich im dht Code keinen Grund das es nicht mehrere Instanzen 
erlaubt.

von Norbert (der_norbert)


Lesenswert?

Mike W. schrieb:
> sensor1.measure
> sensor2.measure

In der Vergangenheit hat es sich immer bewährt, wenn man dem Aufruf 
einer Methode ein Pärchen Klammern spendiert. ;-)

von Mike W. (mike93)


Lesenswert?

Norbert schrieb:
> Mike W. schrieb:
>> sensor1.measure
>> sensor2.measure
>
> In der Vergangenheit hat es sich immer bewährt, wenn man dem Aufruf
> einer Methode ein Pärchen Klammern spendiert. ;-)

Jo, das ist der Fehler. Warum sagt denn der Compiler nichts? Danke sehr.

Das ist nun die Ausgabe:
Temperature 1: 17 °C    Humidity 1: 64%
Temperature 2: 20 °C    Humidity 2: 52%

Die Sensoren sind 1 cm von einander entfernt. 3 Grad und 12% Unterschied 
sind schon viel...


Michael H. schrieb:
> Das Problem wird vermutlich in "import dht" liegen. Kann die Library
> überhaupt mit mehreren DHT Sensoren umgehen?
=> Anscheinend geht das doch. Wenn man keine Klammern vergisst :-)


Rainer W. schrieb:
> Mike W. schrieb:
>> Falls es an der Wahl der Sensoren liegt: ...
> Es kann auch an deinem Aufbau liegen (Kabellänge). Bei 3V3 ist der DHT11
> etwas pingelig.
=> Wo wir gerade bei Kabellängen sind: Wie lang können die denn für 
DHT11, DHT22 und BME280 maximal sein? Meine Ziel-Anwendung hätte nämlich 
1 und 2 Meter Kabellänge. Bei HDMI, das meines Wissens auch I2C nutzt, 
sind es max. 15 Meter.

: Bearbeitet durch User
von Norbert (der_norbert)


Lesenswert?

Mike W. schrieb:
> Jo, das ist der Fehler. Warum sagt denn der Compiler nichts? Danke sehr.

Weil's kein Fehler ist. Du fragst lediglich das Objekt ab und bekommst 
die (ungenutzte und verworfene) Information das es sich um eine Funktion 
handelt.
1
#!python
2
def X():
3
    print('Y')
4
5
X
6
<function X at 0x7f998f987310>
7
8
X()
9
Y

: Bearbeitet durch User
von Helmut -. (dc3yc)


Lesenswert?

Mike W. schrieb:
> Die Sensoren sind 1 cm von einander entfernt. 3 Grad und 12% Unterschied
> sind schon viel...

Neee, das ist bei den schrottigen DHT-Sensoren normal!

von Mike W. (mike93)


Lesenswert?

Helmut -. schrieb:
> Mike W. schrieb:
>> Die Sensoren sind 1 cm von einander entfernt. 3 Grad und 12% Unterschied
>> sind schon viel...
>
> Neee, das ist bei den schrottigen DHT-Sensoren normal!

Dann ist gut :-)

Gibt es denn wegen der Kabellänge für die BME280 Hinweise und 
Erfahrugnen?

von Helmut -. (dc3yc)


Lesenswert?

Habe teilweise bei SHT35 (Temperatur und Feuchte) Kabel mit 1m Länge in 
Betrieb. Das geht!

von J. S. (jojos)


Lesenswert?

Mike W. schrieb:
> Jo, das ist der Fehler. Warum sagt denn der Compiler nichts? Danke sehr.

das kann ich noch nicht nachvollziehen. Für den pico gibt es die dht lib 
und da finde ich folgendes:
https://github.com/ikornaselur/pico-dht11/blob/f98c792d66bc5b8c3ee66059a95e67775c43e9dc/dht.py#L51-L59
Also wird da measure() beim Lesen des Properties aufgerufen, der 
explizite wäre damit also nicht nötig.
In der Doku zu MicroPython steht der measure() Aufruf im Beispiel auch 
drin, also gibt es da wohl verschiedene Implementierungen. Woher weiß 
man jetzt welche tatsächlich verwendet wird?

Die anderen Sensoren SHT oder BME sind deutlich besser, die waren nur 
lange nicht lieferbar oder wenn dann sehr teuer. Sieht es damit jetzt 
besser aus?

: Bearbeitet durch User
von Helmut -. (dc3yc)


Lesenswert?

Wenn du Schweizer Qualität bei den SHTs willst, musst du halt dafür 
zahlen. Die Billigdinger, die als SHT angeboten werden, sind 
China-Nachbauten, kommen aber an die Qualität der Originale nicht heran.
Und ob die BME alle von Bosch sind, ist auch eine Frage des Preises.

: Bearbeitet durch User
von Norbert (der_norbert)


Lesenswert?

J. S. schrieb:
> Also wird da measure() beim Lesen des Properties aufgerufen, der
> explizite wäre damit also nicht nötig.

Dort (github Version) ist ›humidity()‹ explizit als Property einer 
Klasse definiert.
Das kann man dann jedoch nicht - so wie Eröffnungspost beschrieben - als 
Methodenaufruf abfragen, da gäbe es 'ne Kelle.

In der von dir gezeigten Klasse wäre
»wert = xxx.humidity«
richtig und »wert = xxx.humidity()«
würde eine Exception werfen.

Des weiteren:
Wenn ›measure()‹ nur implizit aufgerufen werden soll, warum heist das 
olle Ding dann nicht zumindest ›_measure()‹?

: Bearbeitet durch User
von J. S. (jojos)


Lesenswert?

Danke, ja, verstehe. Das MicroPython hat mittlerweile eine ganze Menge 
Treiber (als C-Code) integriert, der dht gehört dazu und die Aufrufe 
sehen anders aus als in externen py-only lib aus.
Python ist nicht meine Muttersprache, aber interessant finde ich es 
schon.
Ist _measure() dann automatisch was in C++ private wäre? Gibt es sowas 
wie private in python Klassen?

der Vollständigkeit halber, dann dürfte es dieser Quellcode sein:
https://github.com/micropython/micropython-lib/blob/7128d423c2e7c0309ac17a1e6ba873b909b24fcc/micropython/drivers/sensor/dht/dht.py#L24-L36
Und darin wird eine Funktion in C aufgerufen die das bitbanging macht.

: Bearbeitet durch User
von Norbert (der_norbert)


Lesenswert?

J. S. schrieb:
> Ist _measure() dann automatisch was in C++ private wäre? Gibt es sowas
> wie private in python Klassen?
1
#!/usr/bin/python3
2
# -*- coding: UTF-8 -*-
3
# vim:fileencoding=UTF-8:ts=4
4
5
class Q:
6
7
    def __init__(self):
8
        self.a = 111
9
10
    def m(self):
11
        return self.a
12
13
    def _m(self):
14
        return self.a
15
16
    def __m(self):
17
        return self.a
18
19
    @property
20
    def p(self):
21
        return self.a
22
23
    @property
24
    def _p(self):
25
        return self.a
26
27
    @property
28
    def __p(self):
29
        return self.a
30
31
32
q = Q()
33
print("A:", q.m)
34
print("B:", q._m)
35
try:
36
    print("C:", q.__m)
37
except Exception as e:
38
    print("CE:", e, e.__class__)
39
40
print("D:", q.m())
41
print("E:", q._m())
42
try:
43
    print("F:", q.__m())
44
except Exception as e:
45
    print("FE:", e, e.__class__)
46
47
48
print("G:", q.p)
49
print("H:", q._p)
50
try:
51
    print("I:", q.__p)
52
except Exception as e:
53
    print("IE:", e, e.__class__)
54
55
try:
56
    print("J:", q.p())
57
except Exception as e:
58
    print("JE:", e, e.__class__)
59
60
try:
61
    print("K:", q._p())
62
except Exception as e:
63
    print("KE:", e, e.__class__)
64
65
try:
66
    print("L:", q.__p())
67
except Exception as e:
68
    print("LE:", e, e.__class__)
Resultat:
1
A: <bound method Q.m of <__main__.Q object at 0x7f01f5ec1fd0>>
2
B: <bound method Q._m of <__main__.Q object at 0x7f01f5ec1fd0>>
3
CE: 'Q' object has no attribute '__m' <class 'AttributeError'>
4
D: 111
5
E: 111
6
FE: 'Q' object has no attribute '__m' <class 'AttributeError'>
7
G: 111
8
H: 111
9
IE: 'Q' object has no attribute '__p' <class 'AttributeError'>
10
JE: 'int' object is not callable <class 'TypeError'>
11
KE: 'int' object is not callable <class 'TypeError'>
12
LE: 'Q' object has no attribute '__p' <class 'AttributeError'>
Ohne Unterstrich: Prima, benutze es.
Mit einem Unterstrich: Benutze es auf eigene Gefahr. Kann sich ändern.
Mit zwei Unterstrichen: Good luck! ;-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.