Running a SDS011 particulate sensor on a Mac using PHP

The Novafit SDS011 particulate sensor is an a very affordable sensor for detecting particulate pollution. It is capable of detecting both PM2.5 and PM10 with a relative error margin of +/- 10µg/m3.

It can output data via it’s serial port. The one I bought came with a serial to USB adaptor, allowing it to be plugged into my Mac. It did need a driver, and I used ch340g-ch34g-ch34x-mac-os-x-driver.

Data is sent at 9600 baud, with 8 data bits, no parity bit, and 1 stop bit. 10 bytes are sent at a time.

Byte Name Content
0 Message Header AA
1 Commander No C0
2 DATA 1 PM2.5 Low byte
3 DATA 2 PM2.5 High byte
4 DATA 3 PM10 Low byte
5 DATA 4 PM10 High byte
6 DATA 5 ID byte 1
7 DATA 6 ID byte 2
8 Check-sum DATA 1+DATA 2+..+DATA 6
9 Message tail AB

PM2.5 (μg /m3) = ((PM2.5 High byte *256) + PM2.5 low byte)/10
PM10 (μg /m3) = ((PM10 high byte*256) + PM10 low byte)/10

We can read this using PHP. The following PHP script can be run on the command line and outputs the PM2.5 and PM10 levels every 2 seconds to a terminal window.

<?php
exec('stty -f /dev/cu.wchusbserial1420 9600 raw');
while (true) {
    $handle = @fopen( '/dev/cu.wchusbserial1420', 'r' ); # Open device for Read access
    if ($handle) {
        $binarydata = fread( $handle, 10 ); # Read data from device
        $data = unpack('H2header/H2commander/vpm25/vpm10/Sid/H2checksum/H2tail', $binarydata);
        echo sprintf("PM2.5: %dµg/m³\nPM10:  %dµg/m³\n", $data['pm25']/10, $data['pm10']/10);
        fclose ($handle); # Close device file
    } else {
        echo "Unable to connect to pollution sensor\n";
    }
    sleep(2);
}

The device is used by reading the 10 bytes it returns each message from the USB device. We can use PHP’s unpack function to break the binary data returned into an associative array for ease of use. We do have to do divide the PM2.5 and PM10 results by 10 to get their real values though. This can then be echo’d to the terminal.