Mehrere DHT-Sensoren funktionieren nicht am RasPi-Pico

OP #7417267
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.
#7417288
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.

#7417301
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

OP #7417724
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.

#7418659
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?

#7418677
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.

#7418681
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()‹?

#7418705
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.

#7418737
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! ;-)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren