teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

5

プログラムの修正

2021/07/31 03:30

投稿

jake0228
jake0228

スコア16

title CHANGED
File without changes
body CHANGED
@@ -1,9 +1,7 @@
1
1
  raspberry pi で環境センサーを使っています。enviro+というセンサーを利用して以下のプログラムを実行します。その際、24時間のデータを収集したいと思っております。すべてのデータを自動でファイルに出力させることができればと願っています。ターミナル上では10分ほどしか記録が残らないため、ターミナルからコピーすることができません。
2
2
  実行結果のファイルへの記録の方法を教えていただけますでしょうか。どうぞ宜しくお願い致します。
3
3
  ```python3
4
- コード
5
- ```python
6
- !/usr/bin/env python3
4
+ #!/usr/bin/env python3
7
5
 
8
6
  import time
9
7
  from bme280 import BME280

4

プログラムの修正

2021/07/31 03:30

投稿

jake0228
jake0228

スコア16

title CHANGED
File without changes
body CHANGED
@@ -2,6 +2,7 @@
2
2
  実行結果のファイルへの記録の方法を教えていただけますでしょうか。どうぞ宜しくお願い致します。
3
3
  ```python3
4
4
  コード
5
+ ```python
5
6
  !/usr/bin/env python3
6
7
 
7
8
  import time
@@ -36,4 +37,5 @@
36
37
  Pressure: {:05.2f} hPa
37
38
  Relative humidity: {:05.2f} %
38
39
  """.format(temperature, pressure, humidity))
39
- time.sleep(1)
40
+ time.sleep(1)
41
+ ```

3

プログラムの修正

2021/07/31 03:18

投稿

jake0228
jake0228

スコア16

title CHANGED
File without changes
body CHANGED
@@ -5,24 +5,13 @@
5
5
  !/usr/bin/env python3
6
6
 
7
7
  import time
8
- import colorsys
9
- import sys
10
- import ST7735
8
+ from bme280 import BME280
9
+
11
10
  try:
12
- Transitional fix for breaking change in LTR559
13
- from ltr559 import LTR559
11
+ from smbus2 import SMBus
14
- ltr559 = LTR559()
15
12
  except ImportError:
16
- import ltr559
13
+ from smbus import SMBus
17
14
 
18
- from bme280 import BME280
19
- from pms5003 import PMS5003, ReadTimeoutError as pmsReadTimeoutError, SerialTimeoutError
20
- from enviroplus import gas
21
- from subprocess import PIPE, Popen
22
- from PIL import Image
23
- from PIL import ImageDraw
24
- from PIL import ImageFont
25
- from fonts.ttf import RobotoMedium as UserFont
26
15
  import logging
27
16
 
28
17
  logging.basicConfig(
@@ -30,267 +19,21 @@
30
19
  level=logging.INFO,
31
20
  datefmt='%Y-%m-%d %H:%M:%S')
32
21
 
33
- logging.info("""combined.py - Displays readings from all of Enviro plus' sensors
22
+ logging.info("""weather.py - Print readings from the BME280 weather sensor.
34
23
 
35
24
  Press Ctrl+C to exit!
36
25
 
37
26
  """)
38
- BME280 temperature/pressure/humidity sensor
39
- bme280 = BME280()
40
27
 
41
- PMS5003 particulate sensor
42
- pms5003 = PMS5003()
28
+ bus = SMBus(1)
43
- time.sleep(1.0)
29
+ bme280 = BME280(i2c_dev=bus)
44
30
 
45
- Create ST7735 LCD display class
46
- st7735 = ST7735.ST7735(
47
- port=0,
48
- cs=1,
49
- dc=9,
50
- backlight=12,
51
- rotation=270,
52
- spi_speed_hz=10000000
53
- )
54
-
55
- Initialize display
56
- st7735.begin()
57
-
58
- WIDTH = st7735.width
59
- HEIGHT = st7735.height
60
-
61
- Set up canvas and font
62
- img = Image.new('RGB', (WIDTH, HEIGHT), color=(0, 0, 0))
63
- draw = ImageDraw.Draw(img)
64
- font_size_small = 10
65
- font_size_large = 20
66
- font = ImageFont.truetype(UserFont, font_size_large)
67
- smallfont = ImageFont.truetype(UserFont, font_size_small)
68
- x_offset = 2
69
- y_offset = 2
70
-
71
- message = ""
72
-
73
- The position of the top bar
74
- top_pos = 25
75
-
76
- Create a values dict to store the data
77
- variables = ["temperature",
78
- "pressure",
79
- "humidity",
80
- "light",
81
- "oxidised",
82
- "reduced",
83
- "nh3",
84
- "pm1",
85
- "pm25",
86
- "pm10"]
87
-
88
- units = ["C",
89
- "hPa",
90
- "%",
91
- "Lux",
92
- "kO",
93
- "kO",
94
- "kO",
95
- "ug/m3",
96
- "ug/m3",
97
- "ug/m3"]
98
-
99
- Define your own warning limits
100
- The limits definition follows the order of the variables array
101
- Example limits explanation for temperature:
102
- [4,18,28,35] means
103
- [-273.15 .. 4] -> Dangerously Low
104
- (4 .. 18] -> Low
105
- (18 .. 28] -> Normal
106
- (28 .. 35] -> High
107
- (35 .. MAX] -> Dangerously High
108
- DISCLAIMER: The limits provided here are just examples and come
109
- with NO WARRANTY. The authors of this example code claim
110
- NO RESPONSIBILITY if reliance on the following values or this
111
- code in general leads to ANY DAMAGES or DEATH.
112
- limits = [[4, 18, 28, 35],
113
- [250, 650, 1013.25, 1015],
114
- [20, 30, 60, 70],
115
- [-1, -1, 30000, 100000],
116
- [-1, -1, 40, 50],
117
- [-1, -1, 450, 550],
118
- [-1, -1, 200, 300],
119
- [-1, -1, 50, 100],
120
- [-1, -1, 50, 100],
121
- [-1, -1, 50, 100]]
122
-
123
- RGB palette for values on the combined screen
124
- palette = [(0, 0, 255), # Dangerously Low
125
- (0, 255, 255), # Low
126
- (0, 255, 0), # Normal
127
- (255, 255, 0), # High
128
- (255, 0, 0)] # Dangerously High
129
-
130
- values = {}
131
-
132
-
133
-
134
-
135
- Get the temperature of the CPU for compensation
136
- def get_cpu_temperature():
137
- process = Popen(['vcgencmd', 'measure_temp'], stdout=PIPE, universal_newlines=True)
138
- output, _error = process.communicate()
139
- return float(output[output.index('=') + 1:output.rindex("'")])
140
-
141
-
142
- def main():
143
- Tuning factor for compensation. Decrease this number to adjust the
144
- temperature down, and increase to adjust up
145
- factor = 2.25
146
-
147
- cpu_temps = [get_cpu_temperature()] * 5
148
-
149
- delay = 0.5 # Debounce the proximity tap
150
- mode = 10 # The starting mode
151
- last_page = 0
152
-
153
- for v in variables:
154
- values[v] = [1] * WIDTH
155
-
156
- The main loop
157
- try:
158
- while True:
31
+ while True:
159
- proximity = ltr559.get_proximity()
160
-
161
- If the proximity crosses the threshold, toggle the mode
162
- if proximity > 1500 and time.time() - last_page > delay:
163
- mode += 1
164
- mode %= (len(variables) + 1)
165
- last_page = time.time()
166
-
167
- One mode for each variable
168
- if mode == 0:
169
- variable = "temperature"
170
- unit = "C"
171
- cpu_temp = get_cpu_temperature()
172
- Smooth out with some averaging to decrease jitter
173
- cpu_temps = cpu_temps[1:] + [cpu_temp]
174
- avg_cpu_temp = sum(cpu_temps) / float(len(cpu_temps))
175
- raw_temp = bme280.get_temperature()
32
+ temperature = bme280.get_temperature()
176
- data = raw_temp - ((avg_cpu_temp - raw_temp) / factor)
177
- display_text(variables[mode], data, unit)
178
-
179
- if mode == 1:
180
- variable = "pressure"
181
- unit = "hPa"
182
- data = bme280.get_pressure()
183
- display_text(variables[mode], data, unit)
184
-
185
- if mode == 2:
186
- variable = "humidity"
187
- unit = "%"
188
- data = bme280.get_humidity()
189
- display_text(variables[mode], data, unit)
190
-
191
- if mode == 3:
192
- variable = "light"
193
- unit = "Lux"
194
- if proximity < 10:
195
- data = ltr559.get_lux()
196
- else:
197
- data = 1
198
- display_text(variables[mode], data, unit)
199
-
200
- if mode == 4:
201
- variable = "oxidised"
202
- unit = "kO"
203
- data = gas.read_all()
204
- data = data.oxidising / 1000
205
- display_text(variables[mode], data, unit)
206
-
207
- if mode == 5:
208
- variable = "reduced"
209
- unit = "kO"
210
- data = gas.read_all()
211
- data = data.reducing / 1000
212
- display_text(variables[mode], data, unit)
213
-
214
- if mode == 6:
215
- variable = "nh3"
216
- unit = "kO"
217
- data = gas.read_all()
218
- data = data.nh3 / 1000
219
- display_text(variables[mode], data, unit)
220
-
221
- if mode == 7:
222
- variable = "pm1"
223
- unit = "ug/m3"
224
- try:
225
- data = pms5003.read()
226
- except pmsReadTimeoutError:
227
- logging.warning("Failed to read PMS5003")
228
- else:
229
- data = float(data.pm_ug_per_m3(1.0))
230
- display_text(variables[mode], data, unit)
231
-
232
- if mode == 8:
233
- variable = "pm25"
234
- unit = "ug/m3"
235
- try:
236
- data = pms5003.read()
237
- except pmsReadTimeoutError:
238
- logging.warning("Failed to read PMS5003")
239
- else:
240
- data = float(data.pm_ug_per_m3(2.5))
241
- display_text(variables[mode], data, unit)
242
-
243
- if mode == 9:
244
- variable = "pm10"
245
- unit = "ug/m3"
246
- try:
247
- data = pms5003.read()
248
- except pmsReadTimeoutError:
249
- logging.warning("Failed to read PMS5003")
250
- else:
251
- data = float(data.pm_ug_per_m3(10))
252
- display_text(variables[mode], data, unit)
253
- if mode == 10:
254
- Everything on one screen
255
- cpu_temp = get_cpu_temperature()
256
- Smooth out with some averaging to decrease jitter
257
- cpu_temps = cpu_temps[1:] + [cpu_temp]
258
- avg_cpu_temp = sum(cpu_temps) / float(len(cpu_temps))
259
- raw_temp = bme280.get_temperature()
260
- raw_data = raw_temp - ((avg_cpu_temp - raw_temp) / factor)
261
- save_data(0, raw_data)
262
- display_everything()
263
- raw_data = bme280.get_pressure()
33
+ pressure = bme280.get_pressure()
264
- save_data(1, raw_data)
265
- display_everything()
266
- raw_data = bme280.get_humidity()
34
+ humidity = bme280.get_humidity()
267
- save_data(2, raw_data)
268
- if proximity < 10:
269
- raw_data = ltr559.get_lux()
270
- else:
271
- raw_data = 1
272
- save_data(3, raw_data)
273
- display_everything()
274
- gas_data = gas.read_all()
275
- save_data(4, gas_data.oxidising / 1000)
276
- save_data(5, gas_data.reducing / 1000)
277
- save_data(6, gas_data.nh3 / 1000)
278
- display_everything()
279
- pms_data = None
280
- try:
281
- pms_data = pms5003.read()
282
- except (SerialTimeoutError, pmsReadTimeoutError):
283
- logging.warning("Failed to read PMS5003")
35
+ logging.info("""Temperature: {:05.2f} *C
284
- else:
285
- save_data(7, float(pms_data.pm_ug_per_m3(1.0)))
36
+ Pressure: {:05.2f} hPa
286
- save_data(8, float(pms_data.pm_ug_per_m3(2.5)))
37
+ Relative humidity: {:05.2f} %
287
- save_data(9, float(pms_data.pm_ug_per_m3(10)))
38
+ """.format(temperature, pressure, humidity))
288
- display_everything()
289
-
290
- Exit cleanly
291
- except KeyboardInterrupt:
292
- sys.exit(0)
39
+ time.sleep(1)
293
-
294
-
295
- if __name__ == "__main__":
296
- main()

2

プログラムの修正

2021/07/31 00:38

投稿

jake0228
jake0228

スコア16

title CHANGED
File without changes
body CHANGED
@@ -1,5 +1,7 @@
1
1
  raspberry pi で環境センサーを使っています。enviro+というセンサーを利用して以下のプログラムを実行します。その際、24時間のデータを収集したいと思っております。すべてのデータを自動でファイルに出力させることができればと願っています。ターミナル上では10分ほどしか記録が残らないため、ターミナルからコピーすることができません。
2
2
  実行結果のファイルへの記録の方法を教えていただけますでしょうか。どうぞ宜しくお願い致します。
3
+ ```python3
4
+ コード
3
5
  !/usr/bin/env python3
4
6
 
5
7
  import time
@@ -7,7 +9,7 @@
7
9
  import sys
8
10
  import ST7735
9
11
  try:
10
- # Transitional fix for breaking change in LTR559
12
+ Transitional fix for breaking change in LTR559
11
13
  from ltr559 import LTR559
12
14
  ltr559 = LTR559()
13
15
  except ImportError:
@@ -33,47 +35,104 @@
33
35
  Press Ctrl+C to exit!
34
36
 
35
37
  """)
36
-
37
- # BME280 temperature/pressure/humidity sensor
38
+ BME280 temperature/pressure/humidity sensor
38
39
  bme280 = BME280()
39
40
 
40
- # PMS5003 particulate sensor
41
+ PMS5003 particulate sensor
41
42
  pms5003 = PMS5003()
42
43
  time.sleep(1.0)
43
44
 
45
+ Create ST7735 LCD display class
46
+ st7735 = ST7735.ST7735(
47
+ port=0,
48
+ cs=1,
49
+ dc=9,
50
+ backlight=12,
51
+ rotation=270,
52
+ spi_speed_hz=10000000
53
+ )
44
54
 
45
- # Saves the data to be used in the graphs later and prints to the log
46
- def save_data(idx, data):
47
- variable = variables[idx]
48
- # Maintain length of list
49
- values[variable] = values[variable][1:] + [data]
50
- unit = units[idx]
55
+ Initialize display
51
- message = "{}: {:.1f} {}".format(variable[:4], data, unit)
52
- logging.info(message)
56
+ st7735.begin()
53
57
 
58
+ WIDTH = st7735.width
59
+ HEIGHT = st7735.height
54
60
 
55
- # Displays all the text on the 0.96" LCD
56
- def display_everything():
61
+ Set up canvas and font
57
- draw.rectangle((0, 0, WIDTH, HEIGHT), (0, 0, 0))
62
+ img = Image.new('RGB', (WIDTH, HEIGHT), color=(0, 0, 0))
63
+ draw = ImageDraw.Draw(img)
64
+ font_size_small = 10
58
- column_count = 2
65
+ font_size_large = 20
66
+ font = ImageFont.truetype(UserFont, font_size_large)
59
- row_count = (len(variables) / column_count)
67
+ smallfont = ImageFont.truetype(UserFont, font_size_small)
60
- for i in range(len(variables)):
61
- variable = variables[i]
62
- data_value = values[variable][-1]
63
- unit = units[i]
64
- x = x_offset + ((WIDTH // column_count) * (i // row_count))
65
- y = y_offset + ((HEIGHT / row_count) * (i % row_count))
66
- message = "{}: {:.1f} {}".format(variable[:4], data_value, unit)
67
- lim = limits[i]
68
- rgb = palette[0]
68
+ x_offset = 2
69
- for j in range(len(lim)):
70
- if data_value > lim[j]:
71
- rgb = palette[j + 1]
69
+ y_offset = 2
72
- draw.text((x, y), message, font=smallfont, fill=rgb)
73
- st7735.display(img)
74
70
 
71
+ message = ""
75
72
 
73
+ The position of the top bar
74
+ top_pos = 25
75
+
76
+ Create a values dict to store the data
77
+ variables = ["temperature",
78
+ "pressure",
79
+ "humidity",
80
+ "light",
81
+ "oxidised",
82
+ "reduced",
83
+ "nh3",
84
+ "pm1",
85
+ "pm25",
86
+ "pm10"]
87
+
88
+ units = ["C",
89
+ "hPa",
90
+ "%",
91
+ "Lux",
92
+ "kO",
93
+ "kO",
94
+ "kO",
95
+ "ug/m3",
96
+ "ug/m3",
97
+ "ug/m3"]
98
+
99
+ Define your own warning limits
100
+ The limits definition follows the order of the variables array
101
+ Example limits explanation for temperature:
102
+ [4,18,28,35] means
103
+ [-273.15 .. 4] -> Dangerously Low
104
+ (4 .. 18] -> Low
105
+ (18 .. 28] -> Normal
106
+ (28 .. 35] -> High
107
+ (35 .. MAX] -> Dangerously High
108
+ DISCLAIMER: The limits provided here are just examples and come
109
+ with NO WARRANTY. The authors of this example code claim
110
+ NO RESPONSIBILITY if reliance on the following values or this
111
+ code in general leads to ANY DAMAGES or DEATH.
112
+ limits = [[4, 18, 28, 35],
113
+ [250, 650, 1013.25, 1015],
114
+ [20, 30, 60, 70],
115
+ [-1, -1, 30000, 100000],
116
+ [-1, -1, 40, 50],
117
+ [-1, -1, 450, 550],
118
+ [-1, -1, 200, 300],
119
+ [-1, -1, 50, 100],
120
+ [-1, -1, 50, 100],
121
+ [-1, -1, 50, 100]]
122
+
123
+ RGB palette for values on the combined screen
124
+ palette = [(0, 0, 255), # Dangerously Low
125
+ (0, 255, 255), # Low
126
+ (0, 255, 0), # Normal
127
+ (255, 255, 0), # High
128
+ (255, 0, 0)] # Dangerously High
129
+
130
+ values = {}
131
+
132
+
133
+
134
+
76
- # Get the temperature of the CPU for compensation
135
+ Get the temperature of the CPU for compensation
77
136
  def get_cpu_temperature():
78
137
  process = Popen(['vcgencmd', 'measure_temp'], stdout=PIPE, universal_newlines=True)
79
138
  output, _error = process.communicate()
@@ -81,8 +140,8 @@
81
140
 
82
141
 
83
142
  def main():
84
- # Tuning factor for compensation. Decrease this number to adjust the
143
+ Tuning factor for compensation. Decrease this number to adjust the
85
- # temperature down, and increase to adjust up
144
+ temperature down, and increase to adjust up
86
145
  factor = 2.25
87
146
 
88
147
  cpu_temps = [get_cpu_temperature()] * 5
@@ -94,23 +153,23 @@
94
153
  for v in variables:
95
154
  values[v] = [1] * WIDTH
96
155
 
97
- # The main loop
156
+ The main loop
98
157
  try:
99
158
  while True:
100
159
  proximity = ltr559.get_proximity()
101
160
 
102
- # If the proximity crosses the threshold, toggle the mode
161
+ If the proximity crosses the threshold, toggle the mode
103
162
  if proximity > 1500 and time.time() - last_page > delay:
104
163
  mode += 1
105
164
  mode %= (len(variables) + 1)
106
165
  last_page = time.time()
107
166
 
108
- # One mode for each variable
167
+ One mode for each variable
109
168
  if mode == 0:
110
- # variable = "temperature"
169
+ variable = "temperature"
111
170
  unit = "C"
112
171
  cpu_temp = get_cpu_temperature()
113
- # Smooth out with some averaging to decrease jitter
172
+ Smooth out with some averaging to decrease jitter
114
173
  cpu_temps = cpu_temps[1:] + [cpu_temp]
115
174
  avg_cpu_temp = sum(cpu_temps) / float(len(cpu_temps))
116
175
  raw_temp = bme280.get_temperature()
@@ -118,19 +177,19 @@
118
177
  display_text(variables[mode], data, unit)
119
178
 
120
179
  if mode == 1:
121
- # variable = "pressure"
180
+ variable = "pressure"
122
181
  unit = "hPa"
123
182
  data = bme280.get_pressure()
124
183
  display_text(variables[mode], data, unit)
125
184
 
126
185
  if mode == 2:
127
- # variable = "humidity"
186
+ variable = "humidity"
128
187
  unit = "%"
129
188
  data = bme280.get_humidity()
130
189
  display_text(variables[mode], data, unit)
131
190
 
132
191
  if mode == 3:
133
- # variable = "light"
192
+ variable = "light"
134
193
  unit = "Lux"
135
194
  if proximity < 10:
136
195
  data = ltr559.get_lux()
@@ -139,28 +198,28 @@
139
198
  display_text(variables[mode], data, unit)
140
199
 
141
200
  if mode == 4:
142
- # variable = "oxidised"
201
+ variable = "oxidised"
143
202
  unit = "kO"
144
203
  data = gas.read_all()
145
204
  data = data.oxidising / 1000
146
205
  display_text(variables[mode], data, unit)
147
206
 
148
207
  if mode == 5:
149
- # variable = "reduced"
208
+ variable = "reduced"
150
209
  unit = "kO"
151
210
  data = gas.read_all()
152
211
  data = data.reducing / 1000
153
212
  display_text(variables[mode], data, unit)
154
213
 
155
214
  if mode == 6:
156
- # variable = "nh3"
215
+ variable = "nh3"
157
216
  unit = "kO"
158
217
  data = gas.read_all()
159
218
  data = data.nh3 / 1000
160
219
  display_text(variables[mode], data, unit)
161
220
 
162
221
  if mode == 7:
163
- # variable = "pm1"
222
+ variable = "pm1"
164
223
  unit = "ug/m3"
165
224
  try:
166
225
  data = pms5003.read()
@@ -171,7 +230,7 @@
171
230
  display_text(variables[mode], data, unit)
172
231
 
173
232
  if mode == 8:
174
- # variable = "pm25"
233
+ variable = "pm25"
175
234
  unit = "ug/m3"
176
235
  try:
177
236
  data = pms5003.read()
@@ -182,7 +241,7 @@
182
241
  display_text(variables[mode], data, unit)
183
242
 
184
243
  if mode == 9:
185
- # variable = "pm10"
244
+ variable = "pm10"
186
245
  unit = "ug/m3"
187
246
  try:
188
247
  data = pms5003.read()
@@ -192,9 +251,9 @@
192
251
  data = float(data.pm_ug_per_m3(10))
193
252
  display_text(variables[mode], data, unit)
194
253
  if mode == 10:
195
- # Everything on one screen
254
+ Everything on one screen
196
255
  cpu_temp = get_cpu_temperature()
197
- # Smooth out with some averaging to decrease jitter
256
+ Smooth out with some averaging to decrease jitter
198
257
  cpu_temps = cpu_temps[1:] + [cpu_temp]
199
258
  avg_cpu_temp = sum(cpu_temps) / float(len(cpu_temps))
200
259
  raw_temp = bme280.get_temperature()
@@ -228,7 +287,7 @@
228
287
  save_data(9, float(pms_data.pm_ug_per_m3(10)))
229
288
  display_everything()
230
289
 
231
- # Exit cleanly
290
+ Exit cleanly
232
291
  except KeyboardInterrupt:
233
292
  sys.exit(0)
234
293
 

1

プログラムの記入

2021/07/30 23:08

投稿

jake0228
jake0228

スコア16

title CHANGED
File without changes
body CHANGED
@@ -1,2 +1,237 @@
1
1
  raspberry pi で環境センサーを使っています。enviro+というセンサーを利用して以下のプログラムを実行します。その際、24時間のデータを収集したいと思っております。すべてのデータを自動でファイルに出力させることができればと願っています。ターミナル上では10分ほどしか記録が残らないため、ターミナルからコピーすることができません。
2
- 実行結果のファイルへの記録の方法を教えていただけますでしょうか。どうぞ宜しくお願い致します。
2
+ 実行結果のファイルへの記録の方法を教えていただけますでしょうか。どうぞ宜しくお願い致します。
3
+ !/usr/bin/env python3
4
+
5
+ import time
6
+ import colorsys
7
+ import sys
8
+ import ST7735
9
+ try:
10
+ # Transitional fix for breaking change in LTR559
11
+ from ltr559 import LTR559
12
+ ltr559 = LTR559()
13
+ except ImportError:
14
+ import ltr559
15
+
16
+ from bme280 import BME280
17
+ from pms5003 import PMS5003, ReadTimeoutError as pmsReadTimeoutError, SerialTimeoutError
18
+ from enviroplus import gas
19
+ from subprocess import PIPE, Popen
20
+ from PIL import Image
21
+ from PIL import ImageDraw
22
+ from PIL import ImageFont
23
+ from fonts.ttf import RobotoMedium as UserFont
24
+ import logging
25
+
26
+ logging.basicConfig(
27
+ format='%(asctime)s.%(msecs)03d %(levelname)-8s %(message)s',
28
+ level=logging.INFO,
29
+ datefmt='%Y-%m-%d %H:%M:%S')
30
+
31
+ logging.info("""combined.py - Displays readings from all of Enviro plus' sensors
32
+
33
+ Press Ctrl+C to exit!
34
+
35
+ """)
36
+
37
+ # BME280 temperature/pressure/humidity sensor
38
+ bme280 = BME280()
39
+
40
+ # PMS5003 particulate sensor
41
+ pms5003 = PMS5003()
42
+ time.sleep(1.0)
43
+
44
+
45
+ # Saves the data to be used in the graphs later and prints to the log
46
+ def save_data(idx, data):
47
+ variable = variables[idx]
48
+ # Maintain length of list
49
+ values[variable] = values[variable][1:] + [data]
50
+ unit = units[idx]
51
+ message = "{}: {:.1f} {}".format(variable[:4], data, unit)
52
+ logging.info(message)
53
+
54
+
55
+ # Displays all the text on the 0.96" LCD
56
+ def display_everything():
57
+ draw.rectangle((0, 0, WIDTH, HEIGHT), (0, 0, 0))
58
+ column_count = 2
59
+ row_count = (len(variables) / column_count)
60
+ for i in range(len(variables)):
61
+ variable = variables[i]
62
+ data_value = values[variable][-1]
63
+ unit = units[i]
64
+ x = x_offset + ((WIDTH // column_count) * (i // row_count))
65
+ y = y_offset + ((HEIGHT / row_count) * (i % row_count))
66
+ message = "{}: {:.1f} {}".format(variable[:4], data_value, unit)
67
+ lim = limits[i]
68
+ rgb = palette[0]
69
+ for j in range(len(lim)):
70
+ if data_value > lim[j]:
71
+ rgb = palette[j + 1]
72
+ draw.text((x, y), message, font=smallfont, fill=rgb)
73
+ st7735.display(img)
74
+
75
+
76
+ # Get the temperature of the CPU for compensation
77
+ def get_cpu_temperature():
78
+ process = Popen(['vcgencmd', 'measure_temp'], stdout=PIPE, universal_newlines=True)
79
+ output, _error = process.communicate()
80
+ return float(output[output.index('=') + 1:output.rindex("'")])
81
+
82
+
83
+ def main():
84
+ # Tuning factor for compensation. Decrease this number to adjust the
85
+ # temperature down, and increase to adjust up
86
+ factor = 2.25
87
+
88
+ cpu_temps = [get_cpu_temperature()] * 5
89
+
90
+ delay = 0.5 # Debounce the proximity tap
91
+ mode = 10 # The starting mode
92
+ last_page = 0
93
+
94
+ for v in variables:
95
+ values[v] = [1] * WIDTH
96
+
97
+ # The main loop
98
+ try:
99
+ while True:
100
+ proximity = ltr559.get_proximity()
101
+
102
+ # If the proximity crosses the threshold, toggle the mode
103
+ if proximity > 1500 and time.time() - last_page > delay:
104
+ mode += 1
105
+ mode %= (len(variables) + 1)
106
+ last_page = time.time()
107
+
108
+ # One mode for each variable
109
+ if mode == 0:
110
+ # variable = "temperature"
111
+ unit = "C"
112
+ cpu_temp = get_cpu_temperature()
113
+ # Smooth out with some averaging to decrease jitter
114
+ cpu_temps = cpu_temps[1:] + [cpu_temp]
115
+ avg_cpu_temp = sum(cpu_temps) / float(len(cpu_temps))
116
+ raw_temp = bme280.get_temperature()
117
+ data = raw_temp - ((avg_cpu_temp - raw_temp) / factor)
118
+ display_text(variables[mode], data, unit)
119
+
120
+ if mode == 1:
121
+ # variable = "pressure"
122
+ unit = "hPa"
123
+ data = bme280.get_pressure()
124
+ display_text(variables[mode], data, unit)
125
+
126
+ if mode == 2:
127
+ # variable = "humidity"
128
+ unit = "%"
129
+ data = bme280.get_humidity()
130
+ display_text(variables[mode], data, unit)
131
+
132
+ if mode == 3:
133
+ # variable = "light"
134
+ unit = "Lux"
135
+ if proximity < 10:
136
+ data = ltr559.get_lux()
137
+ else:
138
+ data = 1
139
+ display_text(variables[mode], data, unit)
140
+
141
+ if mode == 4:
142
+ # variable = "oxidised"
143
+ unit = "kO"
144
+ data = gas.read_all()
145
+ data = data.oxidising / 1000
146
+ display_text(variables[mode], data, unit)
147
+
148
+ if mode == 5:
149
+ # variable = "reduced"
150
+ unit = "kO"
151
+ data = gas.read_all()
152
+ data = data.reducing / 1000
153
+ display_text(variables[mode], data, unit)
154
+
155
+ if mode == 6:
156
+ # variable = "nh3"
157
+ unit = "kO"
158
+ data = gas.read_all()
159
+ data = data.nh3 / 1000
160
+ display_text(variables[mode], data, unit)
161
+
162
+ if mode == 7:
163
+ # variable = "pm1"
164
+ unit = "ug/m3"
165
+ try:
166
+ data = pms5003.read()
167
+ except pmsReadTimeoutError:
168
+ logging.warning("Failed to read PMS5003")
169
+ else:
170
+ data = float(data.pm_ug_per_m3(1.0))
171
+ display_text(variables[mode], data, unit)
172
+
173
+ if mode == 8:
174
+ # variable = "pm25"
175
+ unit = "ug/m3"
176
+ try:
177
+ data = pms5003.read()
178
+ except pmsReadTimeoutError:
179
+ logging.warning("Failed to read PMS5003")
180
+ else:
181
+ data = float(data.pm_ug_per_m3(2.5))
182
+ display_text(variables[mode], data, unit)
183
+
184
+ if mode == 9:
185
+ # variable = "pm10"
186
+ unit = "ug/m3"
187
+ try:
188
+ data = pms5003.read()
189
+ except pmsReadTimeoutError:
190
+ logging.warning("Failed to read PMS5003")
191
+ else:
192
+ data = float(data.pm_ug_per_m3(10))
193
+ display_text(variables[mode], data, unit)
194
+ if mode == 10:
195
+ # Everything on one screen
196
+ cpu_temp = get_cpu_temperature()
197
+ # Smooth out with some averaging to decrease jitter
198
+ cpu_temps = cpu_temps[1:] + [cpu_temp]
199
+ avg_cpu_temp = sum(cpu_temps) / float(len(cpu_temps))
200
+ raw_temp = bme280.get_temperature()
201
+ raw_data = raw_temp - ((avg_cpu_temp - raw_temp) / factor)
202
+ save_data(0, raw_data)
203
+ display_everything()
204
+ raw_data = bme280.get_pressure()
205
+ save_data(1, raw_data)
206
+ display_everything()
207
+ raw_data = bme280.get_humidity()
208
+ save_data(2, raw_data)
209
+ if proximity < 10:
210
+ raw_data = ltr559.get_lux()
211
+ else:
212
+ raw_data = 1
213
+ save_data(3, raw_data)
214
+ display_everything()
215
+ gas_data = gas.read_all()
216
+ save_data(4, gas_data.oxidising / 1000)
217
+ save_data(5, gas_data.reducing / 1000)
218
+ save_data(6, gas_data.nh3 / 1000)
219
+ display_everything()
220
+ pms_data = None
221
+ try:
222
+ pms_data = pms5003.read()
223
+ except (SerialTimeoutError, pmsReadTimeoutError):
224
+ logging.warning("Failed to read PMS5003")
225
+ else:
226
+ save_data(7, float(pms_data.pm_ug_per_m3(1.0)))
227
+ save_data(8, float(pms_data.pm_ug_per_m3(2.5)))
228
+ save_data(9, float(pms_data.pm_ug_per_m3(10)))
229
+ display_everything()
230
+
231
+ # Exit cleanly
232
+ except KeyboardInterrupt:
233
+ sys.exit(0)
234
+
235
+
236
+ if __name__ == "__main__":
237
+ main()