Feinstaubmessung und übertragung der Daten an Luftdaten.info mittels SDS011 Feinstaubsensor

  • Hi zusammen,

    hier gibts ja schon ein paar Beiträge zum Theme Feinstaubmessung. Hat hier jemand den SDS011 Feinstaubsensor erfolgreich an seinem PI zum laufen bekommen und überträgt jemand seine Daten an eine Plattform wie Luftdaten.info? Falls ja bin ich über eine Anleitung oder Hilfestellung sehr dankbar. Ich bekomme das einfach nicht hin ;(

  • Hallo backi,

    danke für die Nachfrage. Ja, den Sensor habe ich schon seit 1 1/2 Jahren am Raspi im Betrieb. Jedoch nicht stationär, sondern mit GPS und kleinem Display. Gemeinsam mit einer Energieagentur veranstalten wir damit in Berlin Projekttage an Schulen. Die Daten laden wir nicht auf Luftdaten.info hoch, dafür gibt es ja bereits das vorgefertigte Projekt für die stationäre Version samt Firmware auf deren Webseite. Wir wollten das Thema für Schulen "erlebbar" machen und sind auch damit an diesem Wochenende auf der Maker Faire in Berlin vertreten. Für die Schulen bieten wir die Projekttage kostenlos an und bauen derzeit noch weitere Messgeräte, die dann an interessierte Schulen verliehen werden.

    Wenn du dich auf github umschaust, dann findest du schon einige Python Module, mit denen sich der Sensor recht einfach ansteuern lässt.

    Beste Grüße,

    /luetzel

  • Dieser Feinstaubsensor hat eine Serielle Schnittstelle. Meist wird er sogar mit einem USB zu Seriell Adapter geliefert. Damit ist das empfangen der Werte auf einem Raspberry Pi ein Kinderspiel.

    Man muss nur die Baudrate entsprechend einstellen (9600-8N1) und kann dann aus /dev/ttyUSB0 lesen und schreiben.

    Mit lesen bekommt man dann die daten. Jede Sekunde wird ein (binaer) paket empfangen. Die Daten kann man mit einem kleinen Script entschluesseln. Schreiben tut man verschiendene Einstellungen. Ein Python Script namens sds011.py macht das alles. Aber man kann auch X11-Basic oder eine andere Programmiersprache nehmen .

  • Das Datenformat ist übrigens (10 Bytes im Paket):

    AA C0 x1 x2 x3 x4 x5 x6 cc AB


    AA -- der Wert 170

    AB -- der Wert 171

    C0 -- der Wert 192


    Der PM2.5 Wert errechnet sich aus pm25= (x2*256+x1)/10

    Der PM10 Wert errechnet sich aus pm10= (x4*256+x3)/10

    x5 und x6 enthalten eine Sensor-ID.

    cc ist eine Check-Summe. (cc=(x1+x2+x3+x4+x5+x6) AND 255)


    Noch gut zu wissen: Die serielle Schnittstelle geht auch mit 3.3V so dass man den Sensor auch direkt an die GPIOs des Raspis anschlissen kann.

    Edited once, last by wend ().

  • Als einstellmöglichkeiten am Sensor gibt es:


    A) Standby ein und ausschalten (verlaengert die Lebensdauer).

    B) Messperioden einstellen.

    C) USER ID einstellen

    D) Daten-Modus einstellen (Nachfragen oder senden, pull oder push)

    E) Abfrage der Versionsnummer


    Hierfür muss man ein Paket von Bytes senden, und zwar:


    Fur Standby AN:


    AA B4 06 01 01 FF FF 06 AB


    Für Standby aus:


    AA B4 06 01 00 FF FF 05 AB


    Für pull mode:


    AA B4 02 01 FF FF 01 AB


    Für push mode:


    AA B4 02 00 FF FF 00 AB


    Messperiode:


    AA B4 08 01 pp FF FF cc AB


    Device ID:


    AA B4 05 i1 i2 FF FF cc AB


    Get version:


    AA B4 07 FF FF 05 AB


    (Als Antwort wird ein einzelnes Byte != AA empfangen)


    Get Data:


    AA B4 04 FF FF 02 AB

  • ok, danke - das klingt alles prima, nur hab ich von der Programmierung keinen Plan. Ich bin mehr oder weniger nach der Suche nach einem fertigen Skript oder einer Installationsanleitung, mit der ich die Daten auslesen kann und dann an luftdaten.info und/oder opensensemap übertrage.

  • Soweit ich weiss gibt es das nicht. Ein wenig muesstest Du also schon programmieren.


    Zum reinen Auslesen gibt es was fertiges hier:


    https://github.com/ikalchev/py-sds011


    Wenn Du die Daten zu luftdaten.info schicken willst, warum nimmst Du dann nicht den "offiziellen" Bausatz? Die Kosten für die Extra-Hardware ist verglichen mit dem Aufwand am Raspi wirklich peanutzs.

  • Diese Schritte muessen vorher noch auf dem Raspberry pi durchgeführt werden:


    sudo usermod -a -G dialout pi


    Ich starte dann erstmal eine screen session im Terminal:


    screen


    Dann starte ich dort


    xbasic feinstaub.bas


    Die feinstaubauslese sollte dann laufen. Um das Terminal zu verlassen, ohne die Auslese abzubrechen,


    CTRL-A, CTRL-D drücken.


    Jetzt werden die Daten einfach in die files geschrieben.

    z.B.:


    feinstaubdata-17684.dat


    Das kann man sich dann mit einfachen gnuplot scripts plotten:


    gnuplot feinstaub.gnu

  • Jetzt bleibt noch das Problem, die (selbst ausgelesenen) Daten an luftdateninfo zu schicken. Hab ich auch noch nicht geschafft, aber hier ist ggf. ein Weg:


    https://api.luftdaten.info/v1/push-sensor-data/


    Also man macht dahin eine TCP-Verbindung über Port 80 auf und schreibt


    P1, P2, temperature, humidity und pressure mit den entsprechenden Werten da rein.

    Timestamp ist nicht nötig, aber Sensor-ID (X-PIN, X-Sensor) username und passwort.


    Wie man das in X11-Basic macht, hab ich noch nicht rausgefunden....

  • Und hier kommt schon die Lösung:


    Ein X11-Basic Programm, welches die Sensordaten an den Server bei luftdateninfo abliefert.


    Irgendwo muss aber noch eine Passwortabfrage rein, und so geht es auch nicht über https:// es kommt immer BAD Request.

    Vielleicht muss man doch python verwenden und die richtige POST-https library. X11-basic ist da wohl überfordert. Hierfür benötige ich aber selbst hilfe....

  • Hi WE, hast du dir das python skript von corny schon mal angesehen und zum laufen gebracht?

    Ich glaube ich habs geschafft -> Wenn ich das Skript starte erhalte ich die folgende Ausgabe.

    Wars das jetzt? Misst der Sensor jetzt periodisch alle 5 Minuten und übermittelt die Einträge oder muss ich das Skript per cronjob regelmässig selber starten?


    DEBUG:Adafruit_I2C.Device.Bus.1.Address.0X76:Read 0x6E93 from register pair 0x88, 0x89

    DEBUG:Adafruit_I2C.Device.Bus.1.Address.0X76:Read 0x6826 from register pair 0x8A, 0x8B

    DEBUG:Adafruit_I2C.Device.Bus.1.Address.0X76:Read 0x0032 from register pair 0x8C, 0x8D

    DEBUG:Adafruit_I2C.Device.Bus.1.Address.0X76:Read 0x91FE from register pair 0x8E, 0x8F

    DEBUG:Adafruit_I2C.Device.Bus.1.Address.0X76:Read 0xD6A4 from register pair 0x90, 0x91

    DEBUG:Adafruit_I2C.Device.Bus.1.Address.0X76:Read 0x0BD0 from register pair 0x92, 0x93

    DEBUG:Adafruit_I2C.Device.Bus.1.Address.0X76:Read 0x2153 from register pair 0x94, 0x95

    DEBUG:Adafruit_I2C.Device.Bus.1.Address.0X76:Read 0xFFD0 from register pair 0x96, 0x97

    DEBUG:Adafruit_I2C.Device.Bus.1.Address.0X76:Read 0xFFF9 from register pair 0x98, 0x99

    DEBUG:Adafruit_I2C.Device.Bus.1.Address.0X76:Read 0x300C from register pair 0x9A, 0x9B

    DEBUG:Adafruit_I2C.Device.Bus.1.Address.0X76:Read 0xD120 from register pair 0x9C, 0x9D

    DEBUG:Adafruit_I2C.Device.Bus.1.Address.0X76:Read 0x1388 from register pair 0x9E, 0x9F

    DEBUG:Adafruit_I2C.Device.Bus.1.Address.0X76:Read 0x4B from register 0xA1

    DEBUG:Adafruit_I2C.Device.Bus.1.Address.0X76:Read 0x014A from register pair 0xE1, 0xE2

    DEBUG:Adafruit_I2C.Device.Bus.1.Address.0X76:Read 0x00 from register 0xE3

    DEBUG:Adafruit_I2C.Device.Bus.1.Address.0X76:Read 0x1E from register 0xE7

    DEBUG:Adafruit_I2C.Device.Bus.1.Address.0X76:Read 0x19 from register 0xE4

    DEBUG:Adafruit_I2C.Device.Bus.1.Address.0X76:Read 0x25 from register 0xE5

    DEBUG:Adafruit_I2C.Device.Bus.1.Address.0X76:Read 0x03 from register 0xE6

    DEBUG:Adafruit_I2C.Device.Bus.1.Address.0X76:Read 0x25 from register 0xE5

    DEBUG:Adafruit_I2C.Device.Bus.1.Address.0X76:Wrote 0x24 to register 0xF4

    DEBUG:Adafruit_I2C.Device.Bus.1.Address.0X76:Wrote 0x60 to register 0xF5

    DEBUG:Adafruit_I2C.Device.Bus.1.Address.0X76:Wrote 0x04 to register 0xF2

    DEBUG:Adafruit_I2C.Device.Bus.1.Address.0X76:Wrote 0x93 to register 0xF4

    DEBUG:root:Start of constructor

    INFO:root:Communication to device at /dev/ttyUSB0 initiated.

    DEBUG:root:Building checksum for data bytearray(b'\xaa\xc0\x05\x00\x05\x00\xbf\xec').

    DEBUG:root:Checksum calculated is 181.

    DEBUG:root:response() successful run

    DEBUG:root:Data 0 for commandmode CommandMode.Getting constructed.

    DEBUG:root:send() entered with command DutyCycle and data bytearray(b'\x00\x00').

    DEBUG:root:Input parameter proofed

    DEBUG:root:Building checksum for data bytearray(b'\xaa\xb4\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff').

    DEBUG:root:Checksum calculated is 6.

    DEBUG:root:Going to send: bytearray(b'\xaa\xb4\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x06\xab')

    DEBUG:root:Sent and flushed: bytearray(b'\xaa\xb4\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x06\xab')

    Edited 3 times, last by backi ().

  • ich habs mit dem abgewandelten Skriptvon Corny irgendwie zum laufen bekommen. Soweit ich mich erinnere hat die automatische Erkennung der ID des Raspberry nicht geklappt, ich hab mein ID dann einfach manuell in das Skript eingetragen. Im Detail weiß ich es aber auch nicht mehr, was ich verändert habe. Du kannst die Daten auch noch zusätzlich an opensensemap.org hochladen - das geht auch prima, vor allem mit weiteren Sensoren (UV-Index, Helligkeit usw.)