Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UART fixes #10

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 81 additions & 2 deletions adafruit_pm25.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ def _read_into_buffer(self):
with self.i2c_device as i2c:
try:
i2c.readinto(self._buffer)
except OSError:
raise RuntimeError("Unable to read from PM2.5 over I2C")
except OSError as err:
raise RuntimeError("Unable to read from PM2.5 over I2C") from err


class PM25_UART(PM25):
Expand All @@ -169,6 +169,24 @@ def __init__(self, uart, reset_pin=None):
time.sleep(1)

self._uart = uart
# Set PM2.5 to active mode via UART command
self._uart.write([0x42, 0x4D, 0xE1, 0x00, 0x01, 0x01, 0x71])
# Check mode change response
r = self._uart.read(8)
if (len(r) == 8) and (r[0] == 0x42) and (r[1] == 0x4D):
if sum(r[0:6]) == struct.unpack(">H", r[6:8])[0]:
# print("UART active mode configured successfully")
time.sleep(0.1)
else:
raise RuntimeError(
"Error configuring PM2.5 sensor for active reading, \
checksum failure on mode change response"
)
else:
raise RuntimeError(
"Error configuring PM2.5 sensor for active reading, \
malformed mode change response"
)
super().__init__()

def _read_into_buffer(self):
Expand All @@ -186,3 +204,64 @@ def _read_into_buffer(self):
for i in range(31):
self._buffer[i + 1] = remain[i]
# print([hex(i) for i in self._buffer])


class PM25_UART_PASSIVE(PM25):
"""
A driver for the PM2.5 air quality sensor over UART in passive mode
"""

def __init__(self, uart, reset_pin=None, enable_pin=None):
# Reset enable pin, if present
if enable_pin:
enable_pin.direction = Direction.OUTPUT
enable_pin.value = False
time.sleep(0.1)
enable_pin.value = True
time.sleep(1)

if reset_pin:
reset_pin.direction = Direction.OUTPUT
reset_pin.value = False
time.sleep(0.01)
reset_pin.value = True
time.sleep(1)

self._uart = uart
# Set PM2.5 to passive mode via UART command
self._uart.write([0x42, 0x4D, 0xE1, 0x00, 0x00, 0x01, 0x70])
# Check mode change response
r = self._uart.read(8)
if (len(r) == 8) and (r[0] == 0x42) and (r[1] == 0x4D):
if sum(r[0:6]) == struct.unpack(">H", r[6:8])[0]:
# print("UART passive mode configured successfully")
time.sleep(0.1)
else:
raise RuntimeError(
"Error configuring PM2.5 sensor for active reading, \
checksum failure on mode change response"
)
else:
raise RuntimeError(
"Error configuring PM2.5 sensor for passive reading, \
malformed mode change response"
)
time.sleep(0.2)
super().__init__()

def _read_into_buffer(self):
self._uart.flushInput()
# Request data from PM2.5 via UART command
self._uart.write([0x42, 0x4D, 0xE2, 0x00, 0x00, 0x01, 0x71])
b = self._uart.read(32)
if (len(b) == 32) and (b[0] == 0x42) and (b[1] == 0x4D):
self._buffer = b
elif len(b) <= 8:
time.sleep(0.1)
self._uart.flushInput()
self._uart.write([0x42, 0x4D, 0xE2, 0x00, 0x00, 0x01, 0x71])
b = self._uart.read(32)
if (len(b) == 32) and (b[0] == 0x42) and (b[1] == 0x4D):
self._buffer(b)
else:
raise RuntimeError("Unable to read from PM2.5 (incomplete frame)")
9 changes: 9 additions & 0 deletions examples/pm25_simpletest.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@
# Connect to a PM2.5 sensor over UART
# pm25 = adafruit_pm25.PM25_UART(uart, reset_pin)

# Connect to a PM2.5 sensor over UART in passive mode on Enviro+ Hat on RPi
# enable_pin = DigitalInOut(board.D27)
# enable_pin.direction = Direction.OUTPUT
# reset_pin = DigitalInOut(board.D22)
# reset_pin.direction = Direction.OUTPUT
# import serial
# uart = serial.Serial("/dev/ttyAMA0", baudrate=9600, stopbits=1, parity="N", timeout=4)
# pm25 = adafruit_pm25.PM25_UART_PASSIVE(uart, pin)

# Create library object, use 'slow' 100KHz frequency!
i2c = busio.I2C(board.SCL, board.SDA, frequency=100000)
# Connect to a PM2.5 sensor over I2C
Expand Down