11# SPDX-FileCopyrightText: 2023 Liz Clark for Adafruit Industries
22# SPDX-License-Identifier: MIT
33
4- import os
5- import ssl
64import time
7- import microcontroller
85import board
9- import wifi
10- import socketpool
11- import adafruit_requests
126import neopixel
137import displayio
148from adafruit_ticks import ticks_ms , ticks_add , ticks_diff
15- from adafruit_io .adafruit_io import IO_HTTP , AdafruitIO_RequestError
169from adafruit_pm25 .i2c import PM25_I2C
1710import adafruit_scd4x
1811from adafruit_display_text import bitmap_label
1912from adafruit_bitmap_font import bitmap_font
2013from adafruit_display_shapes .roundrect import RoundRect
2114
22- # connect to SSID
23- wifi .radio .connect (os .getenv ('CIRCUITPY_WIFI_SSID' ), os .getenv ('CIRCUITPY_WIFI_PASSWORD' ))
24-
25- pool = socketpool .SocketPool (wifi .radio )
26- requests = adafruit_requests .Session (pool , ssl .create_default_context ())
27-
28- pool = socketpool .SocketPool (wifi .radio )
29-
30- # adafruit IO info
31- aio_username = os .getenv ('aio_username' )
32- aio_key = os .getenv ('aio_key' )
33- location = "America/New York"
34-
35- # io HTTP for getting the time from the internet
36- io = IO_HTTP (aio_username , aio_key , requests )
37-
38- def reset_on_error (delay , error ):
39- print ("Error:\n " , str (error ))
40- print ("Resetting microcontroller in %d seconds" % delay )
41- time .sleep (delay )
42- microcontroller .reset ()
43-
44- def c_to_f (temp_data ):
45- temperature_celsius = temp_data
46- temperature_fahrenheit = temperature_celsius * 9 / 5 + 32
47- return int (temperature_fahrenheit )
48-
49- # setup NeoPixels
5015pixel_pin = board .D13
5116num_pixels = 8
5217
53- pixels = neopixel .NeoPixel (pixel_pin , num_pixels , brightness = 0.3 , auto_write = False )
18+ pixels = neopixel .NeoPixel (pixel_pin , num_pixels , brightness = 0.1 , auto_write = False )
5419
55- red = (255 , 0 , 0 )
56- yellow = (255 , 125 , 0 )
57- green = (0 , 255 , 0 )
20+ red = (80 , 0 , 0 )
21+ yellow = (75 , 80 , 0 )
22+ green = (0 , 80 , 0 )
5823
5924i2c = board .STEMMA_I2C ()
6025
@@ -66,15 +31,30 @@ def c_to_f(temp_data):
6631scd4x = adafruit_scd4x .SCD4X (i2c )
6732scd4x .start_periodic_measurement ()
6833
69- time .sleep (2 )
34+ time .sleep (5 )
7035
71- co2 = int ( scd4x .CO2 )
72- temp = c_to_f ( scd4x .temperature )
73- humidity = int ( scd4x .relative_humidity )
36+ co2 = scd4x .CO2
37+ temp = scd4x .temperature
38+ humidity = scd4x .relative_humidity
7439
7540pm2 = int (aqdata ["pm25 standard" ])
76- pm2_x = [94 , 94 , 94 , 94 , 140 , 185 ]
77- pm2_colors = [green , green , green , green , yellow , red ]
41+
42+ def rate_pm25 (pm25_data ):
43+ if pm25_data <= 12 :
44+ pm25_outline = 94
45+ pm25_color = green
46+ elif pm25_data <= 35 :
47+ pm25_color = yellow
48+ pm25_outline = 140
49+ else :
50+ pm25_color = red
51+ pm25_outline = 185
52+ return pm25_color , pm25_outline
53+
54+ def c_to_f (temp_data ):
55+ temperature_celsius = temp_data
56+ temperature_fahrenheit = temperature_celsius * 9 / 5 + 32
57+ return temperature_fahrenheit
7858
7959# display setup
8060display = board .DISPLAY
@@ -90,7 +70,7 @@ def c_to_f(temp_data):
9070big_font_file = "/OCRA_big.pcf"
9171big_font = bitmap_font .load_font (big_font_file )
9272
93- pm2_text = bitmap_label .Label (big_font , text = "%d" % pm2 , x = 42 , y = 40 , color = 0xFFFFFF )
73+ pm2_text = bitmap_label .Label (big_font , text = "%d" % pm2 , x = 37 , y = 40 , color = 0xFFFFFF )
9474group .append (pm2_text )
9575
9676co2_text = bitmap_label .Label (small_font , text = "%d" % co2 , x = 50 , y = 107 , color = 0xFFFFFF )
@@ -100,78 +80,36 @@ def c_to_f(temp_data):
10080group .append (temp_text )
10181group .append (humid_text )
10282
103- pm2_outline = RoundRect (pm2_x [ pm2 ] , 19 , 46 , 46 , 10 , fill = None , outline = 0xFFFFFF , stroke = 3 )
83+ pm2_outline = RoundRect (94 , 19 , 46 , 46 , 10 , fill = None , outline = 0xFFFFFF , stroke = 3 )
10484group .append (pm2_outline )
10585
106- pixels .fill (pm2_colors [pm2 ])
107- pixels .show ()
108-
10986display .show (group )
11087
11188sensor_texts = [pm2_text , co2_text , temp_text , humid_text ]
11289sensor_data = [pm2 , co2 , temp , humidity ]
11390
11491sensor_clock = ticks_ms ()
115- io_clock = ticks_ms ()
11692
117- sensor_check = 30000
118- io_check = 300000
93+ sensor_check = 5000
11994first_run = True
12095
121- try :
122- # get feed
123- pm25_feed = io .get_feed ("pm25" )
124- except AdafruitIO_RequestError :
125- # if no feed exists, create one
126- pm25_feed = io .create_new_feed ("pm25" )
127- try :
128- # get feed
129- temp_feed = io .get_feed ("temp" )
130- except AdafruitIO_RequestError :
131- # if no feed exists, create one
132- temp_feed = io .create_new_feed ("temp" )
133- try :
134- # get feed
135- co2_feed = io .get_feed ("co2" )
136- except AdafruitIO_RequestError :
137- # if no feed exists, create one
138- co2_feed = io .create_new_feed ("co2" )
139- try :
140- # get feed
141- humid_feed = io .get_feed ("humid" )
142- except AdafruitIO_RequestError :
143- # if no feed exists, create one
144- humid_feed = io .create_new_feed ("humid" )
145-
146- sensor_feeds = [pm25_feed , co2_feed , temp_feed , humid_feed ]
147-
14896while True :
149- try :
150- if first_run or ticks_diff (ticks_ms (), sensor_clock ) > sensor_check :
151- if scd4x .data_ready :
152- co2 = int (scd4x .CO2 )
153- temp = c_to_f (scd4x .temperature )
154- humidity = int (scd4x .relative_humidity )
155- pm2 = int (aqdata ["pm25 standard" ])
156- pm2_outline .x = pm2_x [pm2 ]
157- pixels .fill (pm2_colors [pm2 ])
158- pixels .show ()
159- for s in range (4 ):
160- sensor_texts [s ].text = "%d" % sensor_data [s ]
161- print ("updated %d data" % sensor_data [s ])
162- time .sleep (0.2 )
163- sensor_clock = ticks_add (sensor_clock , sensor_check )
164-
165- if first_run or ticks_diff (ticks_ms (), io_clock ) > io_check :
166- for z in range (4 ):
167- io .send_data (sensor_feeds [z ]["key" ], sensor_data [z ])
168- print ("sent %d to io" % sensor_data [z ])
169- time .sleep (1 )
170- io_clock = ticks_add (io_clock , io_check )
171- if first_run :
172- sensor_clock = ticks_ms ()
173- io_clock = ticks_ms ()
174- first_run = False
175- # pylint: disable=broad-except
176- except Exception as e :
177- reset_on_error (10 , e )
97+ if first_run or ticks_diff (ticks_ms (), sensor_clock ) > sensor_check :
98+ co2 = scd4x .CO2
99+ temp = c_to_f (scd4x .temperature )
100+ humidity = scd4x .relative_humidity
101+ aqdata = pm25 .read ()
102+ pm2 = int (aqdata ["pm25 standard" ])
103+ pm2_color , pm2_outline .x = rate_pm25 (pm2 )
104+ sensor_data = [pm2 , co2 , temp , humidity ]
105+ pixels .fill (pm2_color )
106+ pixels .show ()
107+ for s in range (4 ):
108+ sensor_texts [s ].text = "%d" % sensor_data [s ]
109+ print ("updated %d data" % sensor_data [s ])
110+ time .sleep (0.2 )
111+ sensor_clock = ticks_add (sensor_clock , sensor_check )
112+
113+ if first_run :
114+ sensor_clock = ticks_ms ()
115+ first_run = False
0 commit comments