Skip to content

Commit

Permalink
Merge pull request #8 from dglaude/library-to-package
Browse files Browse the repository at this point in the history
Library to package
  • Loading branch information
FoamyGuy authored Nov 10, 2020
2 parents 0940f71 + 4c71550 commit 21732d8
Show file tree
Hide file tree
Showing 6 changed files with 178 additions and 77 deletions.
73 changes: 0 additions & 73 deletions adafruit_pm25.py → adafruit_pm25/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,7 @@
"""

# imports
import time
import struct
from adafruit_bus_device.i2c_device import I2CDevice
from digitalio import Direction

__version__ = "0.0.0-auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_PM25.git"
Expand Down Expand Up @@ -117,72 +113,3 @@ def read(self):
) = frame

return self.aqi_reading


class PM25_I2C(PM25):
"""
A driver for the PM2.5 Air quality sensor over I2C
"""

def __init__(self, i2c_bus, reset_pin=None, address=0x12):
if reset_pin:
# Reset device
reset_pin.direction = Direction.OUTPUT
reset_pin.value = False
time.sleep(0.01)
reset_pin.value = True
# it takes at least a second to start up
time.sleep(1)

for _ in range(5): # try a few times, it can be sluggish
try:
self.i2c_device = I2CDevice(i2c_bus, address)
break
except ValueError:
time.sleep(1)
continue
else:
raise RuntimeError("Unable to find PM2.5 device")
super().__init__()

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")


class PM25_UART(PM25):
"""
A driver for the PM2.5 Air quality sensor over UART
"""

def __init__(self, uart, reset_pin=None):
if reset_pin:
# Reset device
reset_pin.direction = Direction.OUTPUT
reset_pin.value = False
time.sleep(0.01)
reset_pin.value = True
# it takes at least a second to start up
time.sleep(1)

self._uart = uart
super().__init__()

def _read_into_buffer(self):
while True:
b = self._uart.read(1)
if not b:
raise RuntimeError("Unable to read from PM2.5 (no start of frame)")
if b[0] == 0x42:
break
self._buffer[0] = b[0] # first byte and start of frame

remain = self._uart.read(31)
if not remain or len(remain) != 31:
raise RuntimeError("Unable to read from PM2.5 (incomplete frame)")
for i in range(31):
self._buffer[i + 1] = remain[i]
# print([hex(i) for i in self._buffer])
84 changes: 84 additions & 0 deletions adafruit_pm25/i2c.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# The MIT License (MIT)
#
# Copyright (c) 2020 ladyada for Adafruit Industries
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
"""
`adafruit_pm25.i2c`
================================================================================
I2C module for CircuitPython library for PM2.5 Air Quality Sensors
* Author(s): ladyada
Implementation Notes
--------------------
**Hardware:**
Works with most (any?) Plantower I2C interfaced PM2.5 sensor.
**Software and Dependencies:**
* Adafruit CircuitPython firmware for the supported boards:
https://github.com/adafruit/circuitpython/releases
* Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice
"""

# imports
import time
from digitalio import Direction
from adafruit_bus_device.i2c_device import I2CDevice
from . import PM25


class PM25_I2C(PM25):
"""
A module for using the PM2.5 Air quality sensor over I2C
"""

def __init__(self, i2c_bus, reset_pin=None, address=0x12):
if reset_pin:
# Reset device
reset_pin.direction = Direction.OUTPUT
reset_pin.value = False
time.sleep(0.01)
reset_pin.value = True
# it takes at least a second to start up
time.sleep(1)

for _ in range(5): # try a few times, it can be sluggish
try:
self.i2c_device = I2CDevice(i2c_bus, address)
break
except ValueError:
time.sleep(1)
continue
else:
raise RuntimeError("Unable to find PM2.5 device")
super().__init__()

def _read_into_buffer(self):
with self.i2c_device as i2c:
try:
i2c.readinto(self._buffer)
except OSError as err:
raise RuntimeError("Unable to read from PM2.5 over I2C") from err
82 changes: 82 additions & 0 deletions adafruit_pm25/uart.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# The MIT License (MIT)
#
# Copyright (c) 2020 ladyada for Adafruit Industries
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
"""
`adafruit_pm25.uart`
================================================================================
UART module for CircuitPython library for PM2.5 Air Quality Sensors
* Author(s): ladyada
Implementation Notes
--------------------
**Hardware:**
Works with most (any?) Plantower UART or I2C interfaced PM2.5 sensor.
**Software and Dependencies:**
* Adafruit CircuitPython firmware for the supported boards:
https://github.com/adafruit/circuitpython/releases
"""

import time
from digitalio import Direction
from . import PM25


class PM25_UART(PM25):
"""
A driver for the PM2.5 Air quality sensor over UART
"""

def __init__(self, uart, reset_pin=None):
if reset_pin:
# Reset device
reset_pin.direction = Direction.OUTPUT
reset_pin.value = False
time.sleep(0.01)
reset_pin.value = True
# it takes at least a second to start up
time.sleep(1)

self._uart = uart
super().__init__()

def _read_into_buffer(self):
while True:
b = self._uart.read(1)
if not b:
raise RuntimeError("Unable to read from PM2.5 (no start of frame)")
if b[0] == 0x42:
break
self._buffer[0] = b[0] # first byte and start of frame

remain = self._uart.read(31)
if not remain or len(remain) != 31:
raise RuntimeError("Unable to read from PM2.5 (incomplete frame)")
for i in range(31):
self._buffer[i + 1] = remain[i]
# print([hex(i) for i in self._buffer])
6 changes: 6 additions & 0 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,9 @@
.. automodule:: adafruit_pm25
:members:

.. automodule:: adafruit_pm25.i2c
:members:

.. automodule:: adafruit_pm25.uart
:members:
8 changes: 5 additions & 3 deletions examples/pm25_simpletest.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
import board
import busio
from digitalio import DigitalInOut, Direction, Pull
import adafruit_pm25
from adafruit_pm25.i2c import PM25_I2C


reset_pin = None
# If you have a GPIO, its not a bad idea to connect it to the RESET pin
Expand All @@ -33,12 +34,13 @@
# uart = serial.Serial("/dev/ttyUSB0", baudrate=9600, timeout=0.25)

# Connect to a PM2.5 sensor over UART
# pm25 = adafruit_pm25.PM25_UART(uart, reset_pin)
# from adafruit_pm25.uart import PM25_UART
# pm25 = PM25_UART(uart, reset_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
pm25 = adafruit_pm25.PM25_I2C(i2c, reset_pin)
pm25 = PM25_I2C(i2c, reset_pin)

print("Found PM2.5 sensor, reading data...")

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,5 @@
# simple. Or you can use find_packages().
# TODO: IF LIBRARY FILES ARE A PACKAGE FOLDER,
# CHANGE `py_modules=['...']` TO `packages=['...']`
py_modules=["adafruit_pm25"],
packages=["adafruit_pm25"],
)

0 comments on commit 21732d8

Please sign in to comment.