Created
August 7, 2020 18:29
-
-
Save joeycastillo/e70529e759756d3994640dee444d62d6 to your computer and use it in GitHub Desktop.
Air quality monitor using the Open Book and Adafruit PMSA003I Air Quality Breakout
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import displayio | |
from adafruit_display_text.label import Label | |
class LinePlot(displayio.Group): | |
def __init__( | |
self, | |
font, | |
*, | |
x=0, | |
y=0, | |
width=300, | |
height=200, | |
color=0xFFFFFF, | |
**kwargs | |
): | |
super().__init__(max_size=5, **kwargs) | |
self.x = x | |
self.y = y | |
self.width = width | |
self.height = height | |
self.color = color | |
self._palette = displayio.Palette(2) | |
self._palette[0] = 0 | |
self._palette.make_transparent(0) | |
self._palette[1] = color | |
char_width = font.get_glyph(ord("M")).width | |
char_height = font.get_glyph(ord("M")).height | |
self._label_ymax = Label(font, x=0, y=0, max_glyphs=5, color=color) | |
self._label_ymin = Label(font, x=0, y=height - char_height, max_glyphs=5, color=color) | |
self._plot_image = displayio.Bitmap(width - 5 * char_width, height, 2) | |
self._plot_origin_x = 5 * char_width | |
self.max_values = self._plot_image.width - 1 | |
self.values = [0] * self.max_values | |
self._plot_added = False | |
self.draw_plot() | |
self.append(self._label_ymax) | |
self.append(self._label_ymin) | |
def push_value(self, value): | |
self.values.pop(0) | |
self.values.append(value) | |
self.draw_plot() | |
def draw_plot(self): | |
self._plot_image.fill(0) | |
for x in range(0, self._plot_image.width): | |
self._plot_image[x, self._plot_image.height - 1] = 1 | |
for y in range(0, self._plot_image.height): | |
self._plot_image[0, y] = 1 | |
ymin = min(self.values) | |
ymax = max(self.values) | |
self._label_ymax.text = f"{ymax:5}" | |
self._label_ymin.text = f"{ymin:5}" | |
if ymin != ymax: | |
for i in range(0, len(self.values)): | |
scaled_value = self._plot_image.height - 1 - round((float(self.values[i] - ymin) / float(ymax - ymin)) * float(self._plot_image.height - 1)) | |
self._plot_image[i + 1, int(scaled_value)] = 1 | |
if self._plot_added: | |
self.pop(0) | |
plot = displayio.TileGrid(self._plot_image, pixel_shader=self._palette, x=self._plot_origin_x, y=0) | |
self.insert(0, plot) | |
self._plot_added = True | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import time | |
import board | |
import busio | |
from digitalio import DigitalInOut, Direction, Pull | |
from analogio import AnalogIn | |
import adafruit_pm25 | |
import displayio | |
import terminalio | |
from adafruit_display_text.label import Label | |
from lineplot import LinePlot | |
display = board.DISPLAY | |
# air quality sensor | |
i2c = busio.I2C(board.SCL, board.SDA, frequency=100000) | |
pm25 = adafruit_pm25.PM25_I2C(i2c) | |
# power monitors | |
vbat = AnalogIn(board.BATTERY) | |
vbus = AnalogIn(board.USB) | |
ui = displayio.Group(max_size=16) | |
title_label = Label(terminalio.FONT, x=6, y=4, max_glyphs=48, color=0xFFFFFF) | |
ui.append(title_label) | |
white_bitmap = displayio.Bitmap(300, 376, 1) | |
white_palette = displayio.Palette(1) | |
white_palette[0] = 0xFFFFFF | |
background = displayio.TileGrid(white_bitmap, pixel_shader=white_palette, x=0, y=24) | |
ui.append(background) | |
plots = list() | |
particles = [0.3, 0.5, 1, 2.5, 5, 10] | |
for i in range(0, len(particles)): | |
label = Label(terminalio.FONT, x=0, y=56 + i * 63, text="> {}um\n /dL".format(particles[i]), color=0, line_spacing=0.75) | |
plot = LinePlot(terminalio.FONT, x=20, y=27 + i * 63, width=280, height=58, color=0) | |
plots.append(plot) | |
ui.append(label) | |
ui.append(plot) | |
display.show(ui) | |
while True: | |
title_label.text = f"Air Quality Monitor VBat: {2 * 3.3 * vbat.value / 65535:4.3}V VBus: {2 * 3.3 * vbus.value / 65535:4.3}V" | |
try: | |
aqdata = pm25.read() | |
print(aqdata) | |
except RuntimeError: | |
print("Unable to read from sensor, retrying...") | |
continue | |
plots[0].push_value(aqdata["particles 03um"]) | |
plots[1].push_value(aqdata["particles 05um"]) | |
plots[2].push_value(aqdata["particles 10um"]) | |
plots[3].push_value(aqdata["particles 25um"]) | |
plots[4].push_value(aqdata["particles 50um"]) | |
plots[5].push_value(aqdata["particles 100um"]) | |
display.refresh() | |
time.sleep(10) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment