Difference between revisions of "DustSensor"

From RevSpace
Jump to: navigation, search
(Software)
 
(77 intermediate revisions by the same user not shown)
Line 3: Line 3:
 
   |Picture=Pms7003.jpg
 
   |Picture=Pms7003.jpg
 
   |Omschrijving=Experiments with a dust sensor
 
   |Omschrijving=Experiments with a dust sensor
   |Status= Initializing
+
   |Status=Completed
 
   |Contact=bertrik
 
   |Contact=bertrik
 
   }}
 
   }}
  
 
== Introduction ==
 
== Introduction ==
I ordered a dust sensor module to perform measurements of airborne dust.
+
To get an idea of the levels of fine dust around my house, I ordered a dust sensor module to play around with.
 
In particular, I ordered this one, the [http://www.plantower.com/en/content/?110.html Plantower PMS 7003],
 
In particular, I ordered this one, the [http://www.plantower.com/en/content/?110.html Plantower PMS 7003],
 
[https://nl.aliexpress.com/item/dit_is_m/32639894148.html AliExpress link].
 
[https://nl.aliexpress.com/item/dit_is_m/32639894148.html AliExpress link].
It's being advertised as an advanced generation of dust sensor (7th generation), while still reasonably priced.
+
It's being advertised as an advanced generation of dust sensor (7th generation), while still reasonably priced (E15,-).
It uses lasers to perform the measurement and I think it contains a small fan to move the air around.
+
It uses a laser to perform the measurement and it contains a small fan to move the air around.
  
== Hardware ==
+
In parallel with the fine dust level measurement, my device also measures basic meteo data using a BME280 module: temperature, relative humidity and air pressure.
Data sheets can be found:
+
* [https://www.pdf-archive.com/2017/04/12/plantower-pms-7003-sensor-data-sheet/plantower-pms-7003-sensor-data-sheet.pdf here (english)] and
+
* [http://aqicn.org/air/view/sensor/spec/pms7003.pdf here (chinese)]
+
  
The module takes 5V to run and communicates using 3.3V levels.
+
I recommend to also get the cable converter board. The pitch of the connector on the sensor module is slightly non-standard: 2 x 5 pins with a spacing of 0.05 inch (instead of the common 0.1 inch spacing).  
  
It makes an estimate of the number of particles per size category, total 6 categories.
+
The data produced by this sensor is sent as JSON to a MQTT server.
It also gives an estimate of the total mass of the particles.  
+
From there it is picked up by two protocol converters:
 +
1) the Telegraf plugin to insert it into my own influx db and
 +
2) a [https://github.com/bertrik/samenmetenbridge custom written Java application] to forward it to the RIVM samenmeten website
  
I plan to connect this thing up using an ESP8266.
+
=== Future work ===
  
== Software ==
+
Next steps:
The software archive can be found at [https://github.com/bertrik/pms7003_esp github], code has been written but not tested yet.
+
* investigate whether it is possible to power the dust sensor off a solar panel (backup battery during the night), this would completely eliminate any wiring to the sensor
Probably doesn't work, pin assignment on the ESP8266 still has to be decided.
+
* improve the casing such that the temperature reading is not influenced as much by direct solar irradiance
 +
* build a luftdaten.info sensor and put it up at RevSpace
  
Libraries used:
+
== Results ==
* SoftwareSerial
+
Below is a graph of the dust levels around new years eve 2017/2018, separated by particle size
* WiFiClient
+
[[File:dust_2017_2018.png|center]]
* WiFiManager
+
* PubSubClient
+
  
This dust sensor outputs its data as a 32-byte serial data stream at 9600 bps.
+
You can clearly see a peak just after midnight.
  
I plan to run the sensor in 'passive' mode. This means it's not doing a measurement unless the software explicitly tells it do one measurement.
+
See also the map of these two experiments:
 +
* [http://samenmeten.rivm.nl/dataportaal/ Samenmeten dataportaal]
 +
* [http://meetnetdata.rivm.nl/vuurwerk/ Vuurwerk-experiment 2017/2018]
  
=== Protocol outgoing data ===
+
== Hardware ==
The protocol for measurement data from the module is that data is sent in frames.
+
[[File:dustsensor_window.jpg|thumb|right]]
Each frame starts with specific begin marker bytes, then a length byte, then the actual data, and finally a checksum.
+
 
I think it is a good match to use a simple finite state machine to parse the stream and get synchronized to the frames.
+
PMS7003 data sheets can be found:
 +
* [https://www.pdf-archive.com/2017/04/12/plantower-pms-7003-sensor-data-sheet/plantower-pms-7003-sensor-data-sheet.pdf here (english)] and
 +
* [http://aqicn.org/air/view/sensor/spec/pms7003.pdf here (chinese)]
 +
 
 +
The PMS7003 takes 5V to run and communicates using 3.3V levels.
 +
I connect it using a NodeMCU.
 +
 
 +
The module gives an estimate of the total mass of the particles (microgram/m3) in 3 categories: PM1.0, PM2.5 and PM10, both for "standard particle" (CF-1) and "standard atmosphere".
 +
It also makes an estimate of the raw number of particles per size category, total 6 categories: 0.3-0.5-1.0-2.5-5.0-10 micrometer.
 +
I don't know how it actually works on the inside and is able to make a distinction between particles of different size.
  
 
{| class="wikitable"
 
{| class="wikitable"
|+Protocol
+
|+Connections
 
|-
 
|-
!Value
+
!NodeMCU
!Meaning
+
!PMS7003/BME280
 
!Remark
 
!Remark
 
|-
 
|-
|0x42 0x4D
+
|D3
|Begin marker
+
|PMS7003-RST
|ASCII for characters 'B' and 'M'
+
|Pulled-up to 3.3V on NodeMCU side, may not be actually needed
 
|-
 
|-
|0x00 0x1C
+
|D4
|Length
+
|PMS7003-SET
|Length of following data
+
|Pulled-up to 3.3V on NodeMCU side, may not be actually needed
 
|-
 
|-
|XX YY
+
|D5
|PM1.0 concentration (ug/m3)
+
|BME280-SCL
|CF=1, standard particles
+
|I2C-SCL
 
|-
 
|-
|XX YY
+
|D6
|PM2.5 concentration (ug/m3)
+
|BME280-SDA
|CF=1, standard particles
+
|I2C-SDA,  
 
|-
 
|-
|XX YY
+
|D7
|PM10 concentration (ug/m3)
+
|PMS7003-TX
|CF=1, standard particles
+
|NodeMCU receive, PMS7003 transmit
 
|-
 
|-
|XX YY
+
|D8
|PM1.0 concentration (ug/m3)
+
|PMS7003-RX
|in atmospheric environment
+
|NodeMCU transmit, PMS7003 receive
 
|-
 
|-
|XX YY
+
|GND
|PM2.5 concentration (ug/m3)
+
|PMS7003-GND / BME280-GND
|in atmospheric environment
+
|GND ground reference
 
|-
 
|-
|XX YY
+
|VU
|PM10 concentration (ug/m3)
+
|PMS7003-VCC
|in atmospheric environment
+
|USB voltage (5V)
|-
+
|XX YY
+
|Number of particles >0.3 um
+
|in 0.1 liter air
+
|-
+
|XX YY
+
|Number of particles >0.5 um
+
|in 0.1 liter air
+
|-
+
|XX YY
+
|Number of particles >1.0 um
+
|in 0.1 liter air
+
|-
+
|XX YY
+
|Number of particles >2.5 um
+
|in 0.1 liter air
+
|-
+
|XX YY
+
|Number of particles >5.0 um
+
|in 0.1 liter air
+
|-
+
|XX YY
+
|Number of particles >10 um
+
|in 0.1 liter air
+
|-
+
|VV
+
|Version number
+
|?
+
|-
+
|EE
+
|Error code
+
|?
+
|-
+
|C1 C2
+
|Check code
+
|basically the sum of all bytes up to the check code
+
 
|-
 
|-
 +
|3.3V
 +
|BME280-VCC
 +
|
 
|}
 
|}
  
Data is encoded in big-endian format.
+
Special thanks to [[User:Crashjuh|Crashjuh]] for helping with the cable, putting dupont connectors on them, making it a lot easier to connect the module to an ESP8266.
  
=== Protocol incoming data ===
+
== Software ==
This protocol allows commands to be sent to the module, also in frames.
+
The software archive can be found at github, it consists of the following parts:
Each command frame consists of 7 bytes.
+
* experimental (not yet working) [https://github.com/bertrik/sds011 arduino software for reading the sds011 dust sensor]
It starts with two marker bytes, then a command byte, two data bytes and finally two checksum bytes.  
+
* [https://github.com/bertrik/pms7003_esp arduino software reading the PMS7003] and sending it as an MQTT stream;
 +
* [https://github.com/bertrik/sds011 arduino software reading the SDS011] and sending it as an MQTT stream;
 +
* a Java based [https://github.com/bertrik/samenmetenbridge bridge application] that takes the MQTT data produced by the arduino and forwards it to other backends, like the RIVM influx database, luftdaten.info API.
 +
 
 +
=== Dust sensor ===
 +
The dust sensor software is written for the Arduino environment.
 +
 
 +
Typing 'make' builds and runs unit tests that verify parsing of measurement data and construction of command data.
 +
The sub-directory 'pms7003_esp' contains the .ino file to be opened in the Arduino IDE.
 +
 
 +
Libraries used:
 +
* SoftwareSerial (built-in) for serial communication with the sensor
 +
* WiFiClient (built-in) for WiFi connectivity
 +
* WiFiManager (tzapu) to present a captive portal and allow selection of an AP to connect to the internet
 +
* PubSubClient (Nick O'Leary) to handle publishing of data over MQTT
 +
* BME280I2C (Tyler Glenn) and wire for interacting with a BME280 for basic meteo data (temperature, humidity, pressure)
 +
 
 +
==== PMS7003 ====
 +
Reading measurements from the pms7003 works, sending commands to the module does not. I don't know yet whether this is a hardware or software problem.
 +
 
 +
Typing 'make' builds and runs unit tests that verify parsing of measurement data and construction of command data.
 +
The sub-directory 'pms7003_esp' contains the .ino file to be opened in the Arduino IDE.
 +
 
 +
==== SDS011 ====
 +
Typing 'make' builds and runs unit tests that verify parsing of measurement data and construction of command data.
 +
The sub-directory 'sds011_esp' contains the .ino file to be opened in the Arduino IDE.
 +
 
 +
=== Infrastructure ===
 +
The idea is that the dust sensor send its data to an MQTT server.
 +
From there on, there is an application written in Java that picks up the data from MQTT and redistributes it to other backends, like samenmeten.rivm.nl and luftdaten.info.
 +
 
 +
The topic that the sensor publishes on is
 +
  bertrik/dust/<sensorid>
 +
where sensorid is some kind of unique id, like the id of the sensor itself, or the id of the esp8266 that it's connected to.
  
 
== References ==
 
== References ==
* a nice list of sensors [https://www.samenmetenaanluchtkwaliteit.nl/sensoren-voor-fijn-stof-pm25pm10 from "samen meten aan luchtkwaliteit"].
+
[https://keetweej.vanheusden.com/grafana/d/JUIM-ikmz/rivm-data?orgId=2 Grafana page of my sensor data].
* another [http://aqicn.org/sensor/ nice overview of dust sensors].
+
 
 +
[http://aqicn.org/sensor/pms5003-7003/ Page on aqicn about the PMS5003/7003]
 +
 
 +
List of dust sensors:
 +
* list of sensors [https://www.samenmetenaanluchtkwaliteit.nl/sensoren-voor-fijn-stof-pm25pm10 from "samen meten aan luchtkwaliteit"].
 +
* another [http://aqicn.org/sensor/ overview of dust sensors].
 +
 
 +
Citizen science projects for measuring airborne dust:
 +
* [https://www.luchtmeetnet.nl/stations/alle-provincies/alle-gemeentes/PM10 Dutch RIVM official air quality map]
 +
* [https://samenmeten.rivm.nl/dataportaal/ Dutch RIVM citizen science air quality map]
 +
* [http://meetnetdata.rivm.nl/vuurwerk/ Dutch RIVM fireworks smog monitoring during new year's eve]
 +
* [http://ik-adem.be/ Belgian project "ik adem" - fijnstofmetingen]
 +
* [http://luftdaten.info/ German project luftdaten - measure air data by yourself]
 +
 
 +
Dust measurement blog:
 +
* [https://scapeler.wordpress.com/ scapeler]
 +
 
 +
== Making graphs of dust data ==
 +
To create nice graphs, I used the following stack of tools/applications:
 +
* a dust sensor, as described here, that publishes measurement data towards an MQTT server
 +
* an MQTT server to accept the data and forward it to subscribers
 +
* the 'Telegraf' importer that listens on the MQTT stream and converts the data to influx database
 +
* an influx database, to store the measurement data
 +
* grafana, to grab the data from the database and display it
 +
 
 +
=== Sensor ===
 +
The sensor produces JSON, grouping the information from one message from the module together. Example
 +
  bertrik/pms7003/json {"pms7003":{"pm1_0":2,"pm2_5":3,"pm10":4},"bme280":{"t":21.1,"rh":50,"p":1012.4}}
 +
 
 +
=== Telegraf ===
 +
Things I did:
 +
* downloaded and installed the Telegraf .deb from [https://github.com/influxdata/telegraf here].
 +
* generated a default configuration using:
 +
  telegraf --input-filter mqtt_consumer --output-filter influxdb config >telegraf.conf
 +
* edited the configuration to set mqtt and influxdb settings
 +
** influxdb output plugin
 +
*** urls = ["http://172.29.0.1:8086"]
 +
** mqtt_consumer plugin
 +
*** topics=[ "bertrik/pms7003/json" ]
 +
*** data_format="json"
 +
*** data_type="integer"
 +
* test-run using 'telegraf <TODO>'
 +
* copied the final telegraf.conf to /etc/telegraf and restarted the telegraf service
 +
  systemctl restart telegraf
 +
 
 +
=== Grafana ===
 +
Add a data source, pointing to the influx DB. Provide credentials and verify by pressing the 'test connection' button.
 +
 
 +
Add a dashboard, add a row to the dashboard, add a graph panel to the row.
 +
Under 'metrics', add a query with the following properties:
 +
* FROM mqtt_consumer WHERE topic = bertrik/pms7003/json
 +
* SELECT field(<b>amb_pm10</b>)
 +
* GROUP BY
 +
* ALIAS BY <b>PM10</b>
 +
* repeat for other particle sizes (amb_pm2_5 and amb_pm_1_0)
 +
 
 +
== Regelgeving ==
 +
From: https://www.rivm.nl/Documenten_en_publicaties/Algemeen_Actueel/Uitgaven/Milieu_Leefomgeving/Dossier_Fijn_stof/Maart_2013/Regelgeving.pdf
 +
 
 +
  Regelgeving voor fijn stof (PM10)
 +
  De regelgeving voor fijn stof (PM10) kent twee doelstellingen:
 +
  - Een grenswaarde voor het jaargemiddelde: <b>40 µg/m3 als jaargemiddelde</b> mag niet worden
 +
    overschreden. Aan deze grenswaarde moet sinds 2005 worden voldaan. Behoudens
 +
    ‘derogatie’ zijn geen uitzonderingen mogelijk (->Derogatie). Deze grenswaarde beoogt
 +
    vooral bescherming te bieden tegen de langetermijneffecten van fijn stof.
 +
  - Een grenswaarde voor het daggemiddelde: <b>50 µg/m3 als daggemiddelde mag op niet meer
 +
    dan 35 dagen per jaar worden overschreden</b>. 5 Aan deze grenswaarde moet sinds 2005
 +
    worden voldaan. Behoudens ‘derogatie’ zijn geen uitzonderingen mogelijk (->Derogatie).
 +
    Deze grenswaarde is vooral bedoeld om bescherming te bieden tegen de
 +
    kortetermijneffecten van fijn stof.
 +
 
 +
== Luftdaten.info ==
 +
I'm forwarding my data also to the [https://luftdaten.info/ luftdaten.info] website
 +
so it appears on the [http://netherlands.maps.luftdaten.info/#11/52.0138/4.7059 lufdaten.info map].
 +
I use the same kind of mechanism as used for RIVM: write a Java program to capture the MQTT stream and convert it to their API.
 +
 
 +
Luftdaten.info have a [http://luftdaten.info/feinstaubsensor-bauen/ pretty good description] of how to build your own sensor for their network.
 +
They're keeping it simple, just wire an sds011 dust sensor with up with some du-pont cable to a nodemcu and put it in a plastic enclosure anyone can build using some drain water piping.
 +
 
 +
It appears hack42 is [https://hack42.nl/wiki/FijnstofMeten also considering to join the luftdaten.info network].
 +
 
 +
=== protocol ===
 +
Most of the [https://github.com/opendata-stuttgart/meta/wiki/APIs Luftdaten.info upload protocols] are described on the luftdaten wiki.
 +
 
 +
Some examples of how to use it, can be found here:
 +
[https://github.com/corny/luftdaten-python/blob/master/main.py#L82 here] and
 +
[https://github.com/verschwoerhaus/ttn-ulm-muecke/blob/master/tasks/luftdaten.py#L34 this code from ttn-ulm-muecke].
 +
 
 +
* data is sent as a HTTP POST to https://api.luftdaten.info/v1/push-sensor-data/ (NOTE: the trailing slash!)
 +
* the HTTP POST uses headers "X-Pin" and "X-Sensor" (not case-sensitive it appears)
 +
** header "X-Pin" indicates the type of data
 +
*** 1 = SDS011 or PMS7003
 +
*** 3 = BMP180
 +
*** 5 = PPD42NS
 +
*** 7 = DHT22
 +
*** 11 = BME280
 +
** header "X-Sensor" indicates the unique sensor id, for example "esp8266-9137604"
 +
** header "Content-Type" with value "application/json" (NOTE: API describes this header, but it's not explicitly sent by the implementations above)
 +
* the body of the POST is JSON with the following fields:
 +
** "software_version": string containing the software version of the sender, for example "python-dusty 0.0.1"
 +
** "sensordatavalues": array of structures containing measurement data, looking like this:
 +
*** "value_type" (when X-PIN=1): string describing the measurement item type, can be "P1" (PM10 value) or "P2" (PM2.5 value) with dust value in ug/m3 I suppose
 +
*** "value_type" (when X-PIN=7): string describing the measurement item type, can be "temperature", "humidity"
 +
*** "value_type" (when X-PIN=11): string describing the measurement item type, can be "temperature", "pressure", "humidity"
 +
*** "value": field containing the measurement value (NOTE: in string quotes, not as numeric values!)
 +
 
 +
As far as I understand, other meta-information like latitude/longitude of the sensor is sent by an e-mail registration process.
 +
This is linked to your measurements by means of the unique sensor id.

Latest revision as of 15:22, 22 April 2018

Project Dust Sensor
Pms7003.jpg
Experiments with a dust sensor
Status Completed
Contact bertrik
Last Update 2018-04-22

Introduction

To get an idea of the levels of fine dust around my house, I ordered a dust sensor module to play around with. In particular, I ordered this one, the Plantower PMS 7003, AliExpress link. It's being advertised as an advanced generation of dust sensor (7th generation), while still reasonably priced (E15,-). It uses a laser to perform the measurement and it contains a small fan to move the air around.

In parallel with the fine dust level measurement, my device also measures basic meteo data using a BME280 module: temperature, relative humidity and air pressure.

I recommend to also get the cable converter board. The pitch of the connector on the sensor module is slightly non-standard: 2 x 5 pins with a spacing of 0.05 inch (instead of the common 0.1 inch spacing).

The data produced by this sensor is sent as JSON to a MQTT server. From there it is picked up by two protocol converters: 1) the Telegraf plugin to insert it into my own influx db and 2) a custom written Java application to forward it to the RIVM samenmeten website

Future work

Next steps:

  • investigate whether it is possible to power the dust sensor off a solar panel (backup battery during the night), this would completely eliminate any wiring to the sensor
  • improve the casing such that the temperature reading is not influenced as much by direct solar irradiance
  • build a luftdaten.info sensor and put it up at RevSpace

Results

Below is a graph of the dust levels around new years eve 2017/2018, separated by particle size

Dust 2017 2018.png

You can clearly see a peak just after midnight.

See also the map of these two experiments:

Hardware

Dustsensor window.jpg

PMS7003 data sheets can be found:

The PMS7003 takes 5V to run and communicates using 3.3V levels. I connect it using a NodeMCU.

The module gives an estimate of the total mass of the particles (microgram/m3) in 3 categories: PM1.0, PM2.5 and PM10, both for "standard particle" (CF-1) and "standard atmosphere". It also makes an estimate of the raw number of particles per size category, total 6 categories: 0.3-0.5-1.0-2.5-5.0-10 micrometer. I don't know how it actually works on the inside and is able to make a distinction between particles of different size.

Connections
NodeMCU PMS7003/BME280 Remark
D3 PMS7003-RST Pulled-up to 3.3V on NodeMCU side, may not be actually needed
D4 PMS7003-SET Pulled-up to 3.3V on NodeMCU side, may not be actually needed
D5 BME280-SCL I2C-SCL
D6 BME280-SDA I2C-SDA,
D7 PMS7003-TX NodeMCU receive, PMS7003 transmit
D8 PMS7003-RX NodeMCU transmit, PMS7003 receive
GND PMS7003-GND / BME280-GND GND ground reference
VU PMS7003-VCC USB voltage (5V)
3.3V BME280-VCC

Special thanks to Crashjuh for helping with the cable, putting dupont connectors on them, making it a lot easier to connect the module to an ESP8266.

Software

The software archive can be found at github, it consists of the following parts:

Dust sensor

The dust sensor software is written for the Arduino environment.

Typing 'make' builds and runs unit tests that verify parsing of measurement data and construction of command data. The sub-directory 'pms7003_esp' contains the .ino file to be opened in the Arduino IDE.

Libraries used:

  • SoftwareSerial (built-in) for serial communication with the sensor
  • WiFiClient (built-in) for WiFi connectivity
  • WiFiManager (tzapu) to present a captive portal and allow selection of an AP to connect to the internet
  • PubSubClient (Nick O'Leary) to handle publishing of data over MQTT
  • BME280I2C (Tyler Glenn) and wire for interacting with a BME280 for basic meteo data (temperature, humidity, pressure)

PMS7003

Reading measurements from the pms7003 works, sending commands to the module does not. I don't know yet whether this is a hardware or software problem.

Typing 'make' builds and runs unit tests that verify parsing of measurement data and construction of command data. The sub-directory 'pms7003_esp' contains the .ino file to be opened in the Arduino IDE.

SDS011

Typing 'make' builds and runs unit tests that verify parsing of measurement data and construction of command data. The sub-directory 'sds011_esp' contains the .ino file to be opened in the Arduino IDE.

Infrastructure

The idea is that the dust sensor send its data to an MQTT server. From there on, there is an application written in Java that picks up the data from MQTT and redistributes it to other backends, like samenmeten.rivm.nl and luftdaten.info.

The topic that the sensor publishes on is

 bertrik/dust/<sensorid>

where sensorid is some kind of unique id, like the id of the sensor itself, or the id of the esp8266 that it's connected to.

References

Grafana page of my sensor data.

Page on aqicn about the PMS5003/7003

List of dust sensors:

Citizen science projects for measuring airborne dust:

Dust measurement blog:

Making graphs of dust data

To create nice graphs, I used the following stack of tools/applications:

  • a dust sensor, as described here, that publishes measurement data towards an MQTT server
  • an MQTT server to accept the data and forward it to subscribers
  • the 'Telegraf' importer that listens on the MQTT stream and converts the data to influx database
  • an influx database, to store the measurement data
  • grafana, to grab the data from the database and display it

Sensor

The sensor produces JSON, grouping the information from one message from the module together. Example

  bertrik/pms7003/json {"pms7003":{"pm1_0":2,"pm2_5":3,"pm10":4},"bme280":{"t":21.1,"rh":50,"p":1012.4}}

Telegraf

Things I did:

  • downloaded and installed the Telegraf .deb from here.
  • generated a default configuration using:
  telegraf --input-filter mqtt_consumer --output-filter influxdb config >telegraf.conf
  • edited the configuration to set mqtt and influxdb settings
    • influxdb output plugin
    • mqtt_consumer plugin
      • topics=[ "bertrik/pms7003/json" ]
      • data_format="json"
      • data_type="integer"
  • test-run using 'telegraf <TODO>'
  • copied the final telegraf.conf to /etc/telegraf and restarted the telegraf service
  systemctl restart telegraf

Grafana

Add a data source, pointing to the influx DB. Provide credentials and verify by pressing the 'test connection' button.

Add a dashboard, add a row to the dashboard, add a graph panel to the row. Under 'metrics', add a query with the following properties:

  • FROM mqtt_consumer WHERE topic = bertrik/pms7003/json
  • SELECT field(amb_pm10)
  • GROUP BY
  • ALIAS BY PM10
  • repeat for other particle sizes (amb_pm2_5 and amb_pm_1_0)

Regelgeving

From: https://www.rivm.nl/Documenten_en_publicaties/Algemeen_Actueel/Uitgaven/Milieu_Leefomgeving/Dossier_Fijn_stof/Maart_2013/Regelgeving.pdf

 Regelgeving voor fijn stof (PM10)
 De regelgeving voor fijn stof (PM10) kent twee doelstellingen:
 - Een grenswaarde voor het jaargemiddelde: 40 µg/m3 als jaargemiddelde mag niet worden
   overschreden. Aan deze grenswaarde moet sinds 2005 worden voldaan. Behoudens
   ‘derogatie’ zijn geen uitzonderingen mogelijk (->Derogatie). Deze grenswaarde beoogt
   vooral bescherming te bieden tegen de langetermijneffecten van fijn stof.
 - Een grenswaarde voor het daggemiddelde: 50 µg/m3 als daggemiddelde mag op niet meer
   dan 35 dagen per jaar worden overschreden. 5 Aan deze grenswaarde moet sinds 2005
   worden voldaan. Behoudens ‘derogatie’ zijn geen uitzonderingen mogelijk (->Derogatie).
   Deze grenswaarde is vooral bedoeld om bescherming te bieden tegen de
   kortetermijneffecten van fijn stof.

Luftdaten.info

I'm forwarding my data also to the luftdaten.info website so it appears on the lufdaten.info map. I use the same kind of mechanism as used for RIVM: write a Java program to capture the MQTT stream and convert it to their API.

Luftdaten.info have a pretty good description of how to build your own sensor for their network. They're keeping it simple, just wire an sds011 dust sensor with up with some du-pont cable to a nodemcu and put it in a plastic enclosure anyone can build using some drain water piping.

It appears hack42 is also considering to join the luftdaten.info network.

protocol

Most of the Luftdaten.info upload protocols are described on the luftdaten wiki.

Some examples of how to use it, can be found here: here and this code from ttn-ulm-muecke.

  • data is sent as a HTTP POST to https://api.luftdaten.info/v1/push-sensor-data/ (NOTE: the trailing slash!)
  • the HTTP POST uses headers "X-Pin" and "X-Sensor" (not case-sensitive it appears)
    • header "X-Pin" indicates the type of data
      • 1 = SDS011 or PMS7003
      • 3 = BMP180
      • 5 = PPD42NS
      • 7 = DHT22
      • 11 = BME280
    • header "X-Sensor" indicates the unique sensor id, for example "esp8266-9137604"
    • header "Content-Type" with value "application/json" (NOTE: API describes this header, but it's not explicitly sent by the implementations above)
  • the body of the POST is JSON with the following fields:
    • "software_version": string containing the software version of the sender, for example "python-dusty 0.0.1"
    • "sensordatavalues": array of structures containing measurement data, looking like this:
      • "value_type" (when X-PIN=1): string describing the measurement item type, can be "P1" (PM10 value) or "P2" (PM2.5 value) with dust value in ug/m3 I suppose
      • "value_type" (when X-PIN=7): string describing the measurement item type, can be "temperature", "humidity"
      • "value_type" (when X-PIN=11): string describing the measurement item type, can be "temperature", "pressure", "humidity"
      • "value": field containing the measurement value (NOTE: in string quotes, not as numeric values!)

As far as I understand, other meta-information like latitude/longitude of the sensor is sent by an e-mail registration process. This is linked to your measurements by means of the unique sensor id.