Skip to content

Instantly share code, notes, and snippets.

@JanX2
Forked from geoffwatts/sds011.py
Created February 9, 2018 15:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JanX2/87ac6ccef5f56bba4a3f055ab2b4e6e9 to your computer and use it in GitHub Desktop.
Save JanX2/87ac6ccef5f56bba4a3f055ab2b4e6e9 to your computer and use it in GitHub Desktop.
Read an SDS011 Laser PM2.5 Sensor (Nova PM Sensor) with Python
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# Requires pyserial. Install via:
# pip install pyserial
from __future__ import print_function
from serial import Serial, EIGHTBITS, STOPBITS_ONE, PARITY_NONE
import time, struct
port = "/dev/tty.wchusbserial1a150" # Set this to your serial port.
baudrate = 9600
# Prepare serial connection.
ser = Serial(port, baudrate=baudrate, bytesize=EIGHTBITS, parity=PARITY_NONE, stopbits=STOPBITS_ONE)
ser.flushInput()
HEADER_BYTE = b"\xAA"
COMMANDER_BYTE = b"\xC0"
TAIL_BYTE = b"\xAB"
byte, previousbyte = b"\x00", b"\x00"
while True:
previousbyte = byte
byte = ser.read(size=1)
#print(byte)
# We got a valid packet header.
if previousbyte == HEADER_BYTE and byte == COMMANDER_BYTE:
packet = ser.read(size=8) # Read 8 more bytes
#print(packet)
# Decode the packet - little endian, 2 shorts for pm2.5 and pm10, 2 ID bytes, checksum.
readings = struct.unpack('<HHcccc', packet)
# Measurements.
pm_25 = readings[0]/10.0
pm_10 = readings[1]/10.0
# ID
id = packet[4:6]
#print(id)
# Prepare checksums.
checksum = readings[4][0]
calculated_checksum = sum(packet[:6]) & 0xFF
checksum_verified = (calculated_checksum == checksum)
#print(checksum_verified)
# Message tail.
tail = readings[5]
if tail == TAIL_BYTE and checksum_verified:
#print("PM 2.5:", pm_25, "μg/m^3 PM 10:", pm_10, "μg/m^3")
print("PM 2.5:", pm_25, "µg/m³ PM 10:", pm_10, "µg/m³ ID:", bytes(id).hex())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment