Skip to content

Instantly share code, notes, and snippets.

@vitorio
Last active July 20, 2023 03:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vitorio/a45e46eb9766b3dae3d8fae48e1421ed to your computer and use it in GitHub Desktop.
Save vitorio/a45e46eb9766b3dae3d8fae48e1421ed to your computer and use it in GitHub Desktop.
CO2 monitor using Pimoroni Tufty 2040 + Adafruit SCD-40, MicroPython 1.20.3
# https://github.com/pimoroni/pimoroni-pico/blob/main/micropython/examples/tufty2040/main.py
# https://github.com/pimoroni/pimoroni-pico/blob/main/micropython/examples/tufty2040/pride_badge.py
# https://github.com/pimoroni/pimoroni-pico/blob/main/micropython/examples/breakout_scd41/scd41_demo.py
from picographics import PicoGraphics, DISPLAY_TUFTY_2040, PEN_RGB332
import time, math, random, gc
from pimoroni import Button, BREAKOUT_GARDEN_I2C_PINS
import breakout_scd41
from pimoroni_i2c import PimoroniI2C
i2c = PimoroniI2C(**BREAKOUT_GARDEN_I2C_PINS)
breakout_scd41.init(i2c)
breakout_scd41.start()
display = PicoGraphics(display=DISPLAY_TUFTY_2040, pen_type=PEN_RGB332, rotate=180)
# convert a hue, saturation, and value into rgb values
def hsv_to_rgb(h, s, v, co2):
if s == 0.0: return v, v, v
i = int(h * 6.0)
f = (h * 6.0) - i
p, q, t = v * (1.0 - s), v * (1.0 - s * f), v * (1.0 - s * (1.0 - f))
v, t, p, q = int(v * 255), int(t * 255), int(p * 255), int(q * 255)
i = i % 6
#if i == 0: return v, t, p # yellows oranges and reds
#if i == 1: return q, v, p # greens and yellow
#if i == 2: return p, v, t # greens and blues
#if i == 3: return p, q, v # blues
#if i == 4: return t, p, v # pinkish purply blues
#if i == 5: return v, p, q # pinks and reds
if co2 < 600:
return p, v, t
elif co2 >= 800:
return v, t, p
else:
return q, v, p
button_up = Button(22, invert=False)
button_down = Button(6, invert=False)
BACKLIGHT = 1.0
display.set_backlight(BACKLIGHT)
WIDTH, HEIGHT = display.get_bounds()
WHITE = display.create_pen(255, 255, 255)
BLACK = display.create_pen(0, 0, 0)
NAME = "???"
co2 = 600
while True:
t = time.ticks_ms() / 1000.0
if button_up.read():
BACKLIGHT = BACKLIGHT + 0.1
if BACKLIGHT > 1.0:
BACKLIGHT = 1.0
if button_down.read():
BACKLIGHT = BACKLIGHT - 0.1
if BACKLIGHT < 0.3:
BACKLIGHT = 0.3
display.set_pen(display.create_pen(50, 50, 70))
display.clear()
# Change details here! Works best with a short, one word name
if breakout_scd41.ready():
co2, temperature, humidity = breakout_scd41.measure()
NAME=str(int(co2))
grid_size = 40
for y in range(0, HEIGHT / grid_size):
for x in range(0, WIDTH / grid_size):
h = x + y + int(t * 5)
h = h / 50.0
r, g, b = hsv_to_rgb(h, .5, 1, co2)
display.set_pen(display.create_pen(r, g, b))
display.rectangle(x * grid_size, y * grid_size, grid_size, grid_size)
# Change the colour of the text (swapping these works better on a light background)
TEXT_COLOUR = BLACK
DROP_SHADOW_COLOUR = WHITE
# Set a starting scale for text size.
# This is intentionally bigger than will fit on the screen, we'll shrink it to fit.
name_size = 20
# These loops adjust the scale of the text until it fits on the screen
while True:
display.set_font("bitmap8")
name_length = display.measure_text(NAME, name_size)
if name_length >= WIDTH - 20:
name_size -= 1
else:
# comment out this section if you hate drop shadow
DROP_SHADOW_OFFSET = 5
display.set_pen(DROP_SHADOW_COLOUR)
display.text(NAME, int((WIDTH - name_length) / 2 + 10) - DROP_SHADOW_OFFSET, 10 + DROP_SHADOW_OFFSET, WIDTH, name_size)
# draw name and stop looping
display.set_pen(TEXT_COLOUR)
display.text(NAME, int((WIDTH - name_length) / 2 + 10), 10, WIDTH, name_size)
break
display.set_backlight(BACKLIGHT)
display.update()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment