~derf / interblag / entry / Adding MQTT to Vindriktning particle sensors using an ESP8266 with NodeMCU firmware
dark mode

Vindriktning is a cheap USB-C powered particle sensor that uses three colored LEDs to indicate the amount of PM2.5 (i.e., particulate matter with a diameter of less than 2.5µm) as a proxy for indoor air quality. By default, it simply measures PM2.5 and indicates whether air quality is good, not so good, or poor – there is no digital read-out of PM2.5 values.

Luckily, adding an ESP8266 to integrate it with MQTT, HomeAssistant, InfluxDB, or other software is quite easy. However, while most examples use Arduino's C++ dialect for programming, I personally prefer to stick to the NodeMCU Lua firmware on ESP8266 boards. Here is my basic readout code for reference.

function uart_callback(data)
    if string.byte(data, 1) ~= 0x16 or string.byte(data, 2) ~= 0x11 or string.byte(data, 3) ~= 0x0b then
        print("invalid header")
        return
    end
    checksum = 0
    for i = 1, 20 do
        checksum = (checksum + string.byte(data, i)) % 256
    end
    if checksum ~= 0 then
        print("invalid checksum")
        return
    end
    pm25 = string.byte(data, 6) * 256 + string.byte(data, 7)
    print("pm25 = " .. pm25)
end

function setup_uart()
    port = softuart.setup(9600, nil, 2)
    port:on("data", 20, uart_callback)
end

setup_uart()

This code assumes that the Vindriktning's TX pin is connected to ESP8266 GPIO4 (labeled "D2" on most esp8266 devboards). As the ESP8266 only has a single RX channel, which we reserve for programming and debugging, I'm using a Software UART implementation. At 9600 baud, that's not an issue.