The PMS7003 is being advertised as an advanced generation of dust sensor (7th generation), while still reasonably priced (E15,-).
They use 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 PMS7003 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

for the PMS7003: do a time-weighted average and report at higher resolution than 1 ug/m3

for RIVM samenmeten: automatically determine geo position from wifi APs and the google/mozilla wifi location APIs

for RIVM samenmeten: use a scheme where the unique id is derived from the ESP id, this should make it very easy to add more sensors with minimal administrative overhead

Results

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

Hardware

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:

a Java based 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

The Arduino software has platformio.org configuration files, so if you're using that, you can just build it with

pio run

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 the id of the ESP8266, in hexadecimal format, e.g. AB12CD

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.