-
-
Save kadamski/92653913a53baf9dd1a8 to your computer and use it in GitHub Desktop.
#!/usr/bin/python | |
# coding=utf-8 | |
# "DATASHEET": http://cl.ly/ekot | |
from __future__ import print_function | |
import serial, struct, sys, time | |
DEBUG = 1 | |
CMD_MODE = 2 | |
CMD_QUERY_DATA = 4 | |
CMD_DEVICE_ID = 5 | |
CMD_SLEEP = 6 | |
CMD_FIRMWARE = 7 | |
CMD_WORKING_PERIOD = 8 | |
MODE_ACTIVE = 0 | |
MODE_QUERY = 1 | |
ser = serial.Serial() | |
ser.port = sys.argv[1] | |
ser.baudrate = 9600 | |
ser.open() | |
ser.flushInput() | |
byte, data = 0, "" | |
def dump(d, prefix=''): | |
print(prefix + ' '.join(x.encode('hex') for x in d)) | |
def construct_command(cmd, data=[]): | |
assert len(data) <= 12 | |
data += [0,]*(12-len(data)) | |
checksum = (sum(data)+cmd-2)%256 | |
ret = "\xaa\xb4" + chr(cmd) | |
ret += ''.join(chr(x) for x in data) | |
ret += "\xff\xff" + chr(checksum) + "\xab" | |
if DEBUG: | |
dump(ret, '> ') | |
return ret | |
def process_data(d): | |
r = struct.unpack('<HHxxBB', d[2:]) | |
pm25 = r[0]/10.0 | |
pm10 = r[1]/10.0 | |
checksum = sum(ord(v) for v in d[2:8])%256 | |
print("PM 2.5: {} μg/m^3 PM 10: {} μg/m^3 CRC={}".format(pm25, pm10, "OK" if (checksum==r[2] and r[3]==0xab) else "NOK")) | |
def process_version(d): | |
r = struct.unpack('<BBBHBB', d[3:]) | |
checksum = sum(ord(v) for v in d[2:8])%256 | |
print("Y: {}, M: {}, D: {}, ID: {}, CRC={}".format(r[0], r[1], r[2], hex(r[3]), "OK" if (checksum==r[4] and r[5]==0xab) else "NOK")) | |
def read_response(): | |
byte = 0 | |
while byte != "\xaa": | |
byte = ser.read(size=1) | |
d = ser.read(size=9) | |
if DEBUG: | |
dump(d, '< ') | |
return byte + d | |
def cmd_set_mode(mode=MODE_QUERY): | |
ser.write(construct_command(CMD_MODE, [0x1, mode])) | |
read_response() | |
def cmd_query_data(): | |
ser.write(construct_command(CMD_QUERY_DATA)) | |
d = read_response() | |
if d[1] == "\xc0": | |
process_data(d) | |
def cmd_set_sleep(sleep=1): | |
mode = 0 if sleep else 1 | |
ser.write(construct_command(CMD_SLEEP, [0x1, mode])) | |
read_response() | |
def cmd_set_working_period(period): | |
ser.write(construct_command(CMD_WORKING_PERIOD, [0x1, period])) | |
read_response() | |
def cmd_firmware_ver(): | |
ser.write(construct_command(CMD_FIRMWARE)) | |
d = read_response() | |
process_version(d) | |
def cmd_set_id(id): | |
id_h = (id>>8) % 256 | |
id_l = id % 256 | |
ser.write(construct_command(CMD_DEVICE_ID, [0]*10+[id_l, id_h])) | |
read_response() | |
if __name__ == "__main__": | |
cmd_set_sleep(0) | |
cmd_set_mode(1); | |
cmd_firmware_ver() | |
time.sleep(3) | |
cmd_query_data(); | |
cmd_set_mode(0); | |
cmd_set_sleep() |
Wicked, also check the /var/log/syslog file or dmesg, i remember low voltage warnings in one of them when I was doing too much with my weak 5v supply
Wicked, also check the /var/log/syslog file or dmesg, i remember low voltage warnings in one of them when I was doing too much with my weak 5v supply
It's been running in the backyard since yesterday evening, 0 hits on 'voltage' issues it seems. Ever since then it has measured 10 times with 1 second intervals, put the SDS011 to sleep for about 5 minutes, wake up and measure again. So I am still optimistic this works ;-)
Pics of the enclosure you can find here. Currently using a standard weatherproof junction box which was always my entention for the outdoor enclosure.
Remco
What needs to change in the code if I would not use Sensor Hat?
@alokvermaiitr what you mean by Sensor Hat?
For those still having the issue where it maxes out, I wrote some new code which seems to work past the 20,000 mark https://github.com/FaisalAhmed123/Nova-PM2.5-Sensor-Reading-Interpreter/blob/main/main.py
Wouldn't even know which value to pick; my knowledge of electronics is limited to none ;-) I did read on several posts/boards that others did try that, including circuits with diodes and all, but to no avail. Best I can do is logic and this seems to work as expected. Until I find some other solution, I'll tidy this up and move it to an enclosure outside to do further testing with the scripts I am working on. I want to collect the data to a database, do some graphs, send it properly formated to luftdaten. All knowledge gaps so I have quite some challenges. Your scripts helped me to get started with the SDS011 though, so many thanks for that :-)
Remco