Improvements to compensated temperature code
[EVA-2020-02-2.git] / examples / all-in-one.py
CommitLineData
d7b32dab
SM
1#!/usr/bin/env python
2
3import time
4import colorsys
5import os
6import sys
7import ST7735
8import ltr559
9
10from bme280 import BME280
11from pms5003 import PMS5003
12from enviroplus import gas
9d2c6929 13from subprocess import PIPE, Popen
d7b32dab
SM
14from PIL import Image
15from PIL import ImageDraw
16from PIL import ImageFont
17
18print("""all-in-one.py - Displays readings from all of Enviro plus' sensors
19
20Press Ctrl+C to exit!
21
22""")
23
24# BME280 temperature/pressure/humidity sensor
25bme280 = BME280()
26
27# PMS5003 particulate sensor
28pms5003 = PMS5003()
29
30# Create ST7735 LCD display class
31st7735 = ST7735.ST7735(
32 port=0,
33 cs=1,
34 dc=9,
35 backlight=12,
36 rotation=270,
37 spi_speed_hz=10000000
38)
39
40# Initialize display
41st7735.begin()
42
43WIDTH = st7735.width
44HEIGHT = st7735.height
45
46# Set up canvas and font
47img = Image.new('RGB', (WIDTH, HEIGHT), color=(0, 0, 0))
48draw = ImageDraw.Draw(img)
49path = os.path.dirname(os.path.realpath(__file__))
50font = ImageFont.truetype(path + "/fonts/Asap/Asap-Bold.ttf", 20)
51
52message = ""
53
54# The position of the top bar
55top_pos = 25
56
57# Displays data and text on the 0.96" LCD
58def display_text(variable, data, unit):
59 # Maintain length of list
60 values[variable] = values[variable][1:] + [data]
61 # Scale the values for the variable between 0 and 1
62 colours = [(v - min(values[variable]) + 1) / (max(values[variable]) - min(values[variable]) + 1) for v in values[variable]]
63 # Format the variable name and value
64 message = "{}: {:.1f} {}".format(variable[:4], data, unit)
65 print(message)
66 draw.rectangle((0, 0, WIDTH, HEIGHT), (255, 255, 255))
67 for i in range(len(colours)):
68 # Convert the values to colours from red to blue
69 colour = (1.0 - colours[i]) * 0.6
70 r, g, b = [int(x * 255.0) for x in colorsys.hsv_to_rgb(colour, 1.0, 1.0)]
71 # Draw a 1-pixel wide rectangle of colour
72 draw.rectangle((i, top_pos, i+1, HEIGHT), (r, g, b))
73 # Draw a line graph in black
74 line_y = HEIGHT - (top_pos + (colours[i] * (HEIGHT - top_pos))) + top_pos
75 draw.rectangle((i, line_y, i+1, line_y+1), (0, 0, 0))
76 # Write the text at the top in black
77 draw.text((0, 0), message, font=font, fill=(0, 0, 0))
78 st7735.display(img)
79
9d2c6929
SM
80# Get the temperature of the CPU for compensation
81def get_cpu_temperature():
82 process = Popen(['vcgencmd', 'measure_temp'], stdout=PIPE)
83 output, _error = process.communicate()
84 return float(output[output.index('=') + 1:output.rindex("'")])
85
86# Tuning factor for compensation. Decrease this number to adjust the
87# temperature down, and increase to adjust up
88factor = 0.8
89
90cpu_temps = [0] * 5
91
d7b32dab
SM
92delay = 0.5 # Debounce the proximity tap
93mode = 0 # The starting mode
94last_page = 0
95light = 1
96
97# Create a values dict to store the data
98variables = ["temperature",
99 "pressure",
100 "humidity",
101 "light",
102 "oxidised",
103 "reduced",
104 "nh3",
105 "pm1",
106 "pm25",
107 "pm10"]
108
109values = {}
110
111for v in variables:
112 values[v] = [1] * WIDTH
113
114# The main loop
115try:
116 while True:
117 proximity = ltr559.get_proximity()
118
119 # If the proximity crosses the threshold, toggle the mode
120 if proximity > 1500 and time.time() - last_page > delay:
121 mode += 1
122 mode %= len(variables)
123 last_page = time.time()
124
125 # One mode for each variable
126 if mode == 0:
127 variable = "temperature"
128 unit = "C"
9d2c6929
SM
129 cpu_temp = get_cpu_temperature()
130 # Smooth out with some averaging to decrease jitter
131 cpu_temps = cpu_temps[1:] + [cpu_temp]
132 avg_cpu_temp = sum(cpu_temps) / float(len(cpu_temps))
133 raw_temp = bme280.get_temperature()
134 data = raw_temp - ((avg_cpu_temp - raw_temp) / factor)
d7b32dab
SM
135 display_text(variable, data, unit)
136
137 if mode == 1:
138 variable = "pressure"
139 unit = "hPa"
140 data = bme280.get_pressure()
141 display_text(variable, data, unit)
142
143 if mode == 2:
144 variable = "humidity"
145 unit = "%"
146 data = bme280.get_humidity()
147 display_text(variable, data, unit)
148
149 if mode == 3:
150 variable = "light"
151 unit = "Lux"
152 if proximity < 10:
153 data = ltr559.get_lux()
154 else:
155 data = 1
156 display_text(variable, data, unit)
157
158 if mode == 4:
159 variable = "oxidised"
160 unit = "kO"
161 data = gas.read_all()
162 data = data.oxidising / 1000
163 display_text(variable, data, unit)
164
165 if mode == 5:
166 variable = "reduced"
167 unit = "kO"
168 data = gas.read_all()
169 data = data.reducing / 1000
170 display_text(variable, data, unit)
171
172 if mode == 6:
173 variable = "nh3"
174 unit = "kO"
175 data = gas.read_all()
176 data = data.nh3 / 1000
177 display_text(variable, data, unit)
178
179 if mode == 7:
180 variable = "pm1"
181 unit = "ug/m3"
182 data = pms5003.read()
183 data = data.pm_ug_per_m3(1.0)
184 display_text(variable, data, unit)
185
186 if mode == 8:
187 variable = "pm25"
188 unit = "ug/m3"
189 data = pms5003.read()
190 data = data.pm_ug_per_m3(2.5)
191 display_text(variable, data, unit)
192
193 if mode == 9:
194 variable = "pm10"
195 unit = "g/m3"
196 data = pms5003.read()
197 data = data.pm_ug_per_m3(10)
198 display_text(variable, data, unit)
199
200# Exit cleanly
201except KeyboardInterrupt:
202 sys.exit(0)