SDS011 Feinstaubsensor

Der Sensor hat einen Lüfter und ein USB-UART Adapter, mit dem man am Computer gleich die Daten auslesen kann. Probieren wir das doch mal und stecken ihn gleich an den Raspberry Pi 3 an. Dann mit 'dmsg' den richtigen USB-Port rauskriegen.

dmesg
[1712437.854230] usb 1-1.2: reset full-speed USB device number 4 using dwc_otg
[1712438.284188] usb 1-1.3: new full-speed USB device number 9 using dwc_otg
[1712438.417219] usb 1-1.3: New USB device found, idVendor=1a86, idProduct=7523, bcdDevice= 2.64
[1712438.417231] usb 1-1.3: New USB device strings: Mfr=0, Product=2, SerialNumber=0
[1712438.417236] usb 1-1.3: Product: USB Serial
[1712438.417959] ch341 1-1.3:1.0: ch341-uart converter detected
[1712438.419645] usb 1-1.3: ch341-uart converter now attached to ttyUSB1

Weiter dann, wie auf dieser Seite beschrieben.

Ich musste noch serial installieren, und auf die Datei, nicht den www-Ordner den Clown gemacht.

sudo python3 -m pip install pyserial

Ach verflixt… geht natürlich nicht. man muss es in python2 machen, sonst kommen Fehlermeldungen der Art: TypeError: unicode strings are not supported, please encode to bytes

Damit es in python3 geht, muss man das, was man an die serielle Schnittstelle schickt, erst in ein Byte-Array wandeln. Dann kann man natürlich nicht wie bei Springs mit + concatenieren. Abfragen auf einzelne Zeichen müssen dann natürlich auch wieder entweder als Byte abgefragt werden, oder als Zahl. Hier mal die Änderungen zwischen den beiden Dateien.

<     #print(prefix + ' '.join(x.encode('hex') for x in d))
<     print(prefix + ' '.join(hex(x) for x in d))
    
<     ret = bytearray()
<     ret.append(0xaa)
<     ret.append(0xb4)
<     ret.append(cmd)
<     for x in data:
<         ret.append(x)
<     ret.append(0xff)
<     ret.append(0xff)
<     ret.append(checksum)
<     ret.append(0xab)
<     #ret = "\xaa\xb4" + chr(cmd) + ''.join(chr(x) for x in data) + "\xff\xff" + chr(checksum) + "\xab"
61,62c52
<     #checksum = sum(ord(v) for v in d[2:8])%256
<     checksum = sum(v for v in d[2:8])%256
68,69c58
<     #checksum = sum(ord(v) for v in d[2:8])%256
<     checksum = sum(v for v in d[2:8])%256
74c63
<     while byte != b"\xaa":
<     #while byte != "\xaa":
91c80
<     if d[1] == 0xc0:
>     #if d[1] == "\xc0":

PROBLEM: Schlafen legen des Sensors funktioniert - aber nicht das aufwachen. es wird der korrekte - lange - string gesendet. nach dem wachwerden 'liest' er noch 3 Daten, ohne dass der Ventilator angeht, das war es dann aber. auch im internet nichts gefunden.

LÖSUNG: Oh mann, ein paar ser.reset_input_buffer(); der.reset_output_buffer; und ein paar time.sleep(2); nach den Befehlen eingebaut und jetzt geht es - welche die richtigen sind, will ich jetzt gar nicht wissen.

Auch die Ausgabe an MQTT hat nicht funktioniert. Es kam wieder das Problem mit bytes:

TypeError: a bytes-like object is required, not 'str'
TypeError: a bytes-like object is required, not 'dict'

Und wieder eine Korrektur:

    child = subprocess.Popen(cmd, shell=False, bufsize=0, stdin=subprocess.PIPE)
    data=json.dumps(jsonrow)
    child.communicate(data.encode())

    #with subprocess.Popen(cmd, shell=False, bufsize=0, stdin=subprocess.PIPE).stdin as f:
    #    json.dump(jsonrow, f.decode())

Das Umwandeln der Roh-Werte in AQI macht er mit JavaScript auf dieser Seite.

Weiter geht es dann mit dem ESP32. mehr Infos dazu hier: https://sensor.community/de/sensors/airrohr/

Stand April 2021