-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcode.py
More file actions
61 lines (50 loc) · 2.14 KB
/
code.py
File metadata and controls
61 lines (50 loc) · 2.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import board
import time
import pwmio
import adafruit_scd30
from adafruit_motor import servo
i2c = board.STEMMA_I2C()
# i2c = busio.I2C(board.SCL, board.SDA, frequency=50000)
scd = adafruit_scd30.SCD30(i2c)
# note, see info on calibration here: https://learn.adafruit.com/adafruit-scd30/field-calibration
# if self calibration won't work (there are requirements), but you have a known value or can set in fresh air, try forced calibration
# mine needed this calibration, was initially reading high by ~300ppm
scd.self_calibration_enabled = True
# note, we're using a 25kg servo (DS3225), your values may vary
# servo: https://a.co/d/30IFoco
# using an Adafruit QT Py ESP32-S2 board, your pin may vary
servo = servo.Servo(pwmio.PWMOut(board.TX, duty_cycle=0, frequency=50), min_pulse=400, max_pulse=2400)
# adjust these values to match your gauge and servo
SERVO_DIVISOR = 5.55555
ANGLE_MOD = 270
# simple range mapper, like Arduino map() - thanks to todbot https://github.com/todbot/circuitpython-tricks?tab=readme-ov-file#map-an-input-range-to-an-output-range
def map_range(s, a1, a2, b1, b2):
return b1 + ((s - a1) * (b2 - b1) / (a2 - a1))
def setGaugeToValue(servo, co2=500):
# keep value between 500 and 1500 as this matches the gauge markings
co2 = min(max(co2, 500), 1500)
# map the co2 value to an angle between 0 and 180
angle = map_range(co2, 500, 1500, 180, 0)
# angle = round(abs((co2 / SERVO_DIVISOR) - ANGLE_MOD))
print(f"setting to angle {angle}, co2 value is {co2}")
servo.angle = angle
# test values to see if we're hitting the markings on gauge correctly
def testValuesToMarkings():
setGaugeToValue(servo, 500)
time.sleep(3)
setGaugeToValue(servo, 750)
time.sleep(3)
setGaugeToValue(servo, 1000)
time.sleep(3)
setGaugeToValue(servo, 1250)
time.sleep(3)
setGaugeToValue(servo, 1500)
time.sleep(3)
while True:
# this call is not strictly necessary, but it will help if the sleep time is short (< 2secs) and on first read
if scd.data_available:
co2 = scd.CO2
setGaugeToValue(servo, co2)
print(f"CO2: {co2} PPM")
# sleep for 30 seconds
time.sleep(30)