-
Notifications
You must be signed in to change notification settings - Fork 0
/
air_quality_sensor.ino
232 lines (180 loc) · 6.16 KB
/
air_quality_sensor.ino
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SPI.h>
// Use dedicated hardware SPI pins
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
//Battery Monitor
#include "Adafruit_MAX1704X.h"
Adafruit_MAX17048 maxlipo;
//SCD40 air sensor
#include <Wire.h>
#include "SparkFun_SCD4x_Arduino_Library.h"
SCD4x mySensor;
#include <Arduino.h>
#include <SensirionI2CScd4x.h>
#include <Wire.h>
SensirionI2CScd4x scd4x;
//SGP MOX gas sensor
#include "Adafruit_SGP40.h"
#include "Adafruit_SHT31.h"
Adafruit_SGP40 sgp;
Adafruit_SHT31 sht31;
struct battery_val {
float volt;
float percent;
};
struct air_val {
uint16_t co2;
float temperature;
float relative_humidity;
};
struct voc_val {
uint16_t sraw;
int32_t voc_index;
};
struct air_val get_air_values() {
uint16_t error;
char errorMessage[256];
struct air_val air_values;
error = scd4x.readMeasurement(air_values.co2, air_values.temperature, air_values.relative_humidity);
if (error) {
Serial.print("Error trying to execute readMeasurement(): ");
errorToString(error, errorMessage, 256);
Serial.println(errorMessage);
} else if (air_values.co2 == 0) {
Serial.println("Invalid sample detected, skipping.");
}
return air_values;
}
struct voc_val get_voc(float temperature, float relative_humidity) {
// Get VOC index
struct voc_val voc_values;
voc_values.sraw = sgp.measureRaw(temperature, relative_humidity);
Serial.print("Raw measurement: ");
Serial.println(voc_values.sraw);
voc_values.voc_index = sgp.measureVocIndex(temperature, relative_humidity);
Serial.print("Voc Index: ");
Serial.println(voc_values.voc_index);
return voc_values;
}
void updateTFT(float temp, float humidity, uint16_t co_two, int32_t voc_index, uint16_t voc_raw , float batt_volt, float batt_perc) {
int text_size = 2;
tft.setTextSize(text_size);
tft.setCursor(0, 0);
tft.fillScreen(ST77XX_BLACK);
tft.setTextColor(ST77XX_WHITE);
tft.print(F("Temp: ")); tft.print(temp); tft.println(" C");
tft.print(F("Temp: ")); tft.print( ((temp*9)/5) + 32); tft.println(" F");
tft.setTextColor(ST77XX_YELLOW);
tft.print(F("Rel Humidity: ")); tft.print(humidity); tft.println(" %");
tft.setTextColor(ST77XX_GREEN);
tft.print(F("CO2:")); tft.print(co_two); tft.println(" ppm");
tft.setTextColor(ST77XX_BLUE);
//tft.print("VOC: "); tft.print(voc_raw); tft.println(" ppm");
tft.print("VOC Raw: "); tft.println(voc_raw);
tft.print("VOC Index: "); tft.println(voc_index);
tft.setTextColor(ST77XX_ORANGE);
tft.print(F("Batt Voltage: ")); tft.print(batt_volt,1); tft.println(" V");
tft.print(F("Batt Charge: ")); tft.print(batt_perc,1); tft.println(" %");
}
void setup(void) {
Serial.begin(9600);
/*
while (!Serial) {
delay(100);
}
*/
Serial.println(F("Serial Terminal Initialized"));
Serial.println(F("Starting Initialization of TFT Display"));
// turn on backlite
pinMode(TFT_BACKLITE, OUTPUT);
digitalWrite(TFT_BACKLITE, HIGH);
// turn on the TFT / I2C power supply
pinMode(TFT_I2C_POWER, OUTPUT);
digitalWrite(TFT_I2C_POWER, HIGH);
delay(10);
// initialize TFT
tft.init(135, 240); // Init ST7789 240x135
tft.setRotation(3);
tft.fillScreen(ST77XX_BLACK);
//Configure tft
tft.setTextWrap(false);
Serial.println(F("Initialized TFT Display"));
////////////////////////////////////////
//check for battery
if (!maxlipo.begin()) {
Serial.println(F("Couldnt find Adafruit MAX17048?\nMake sure a battery is plugged in!"));
while (1) delay(10);
}
Serial.print(F("Found MAX17048")); Serial.print(F(" with Chip ID: 0x")); Serial.println(maxlipo.getChipID(), HEX);
////////////////////////////////////////
////////////////////////////////////////
// Initialize SCD40
Serial.println(F("Starting Initialization of SC40 Air Sensor"));
Wire.begin();
uint16_t error;
char errorMessage[256];
scd4x.begin(Wire);
// stop potentially previously started measurement
error = scd4x.stopPeriodicMeasurement();
if (error) {
Serial.print("Error trying to execute stopPeriodicMeasurement(): ");
errorToString(error, errorMessage, 256);
Serial.println(errorMessage);
}
////////////////////////////////////////
////////////////////////////////////////
// Initialize SCD40
Serial.println(F("Starting Initialization of SC40 Air Sensor"));
uint16_t serial0;
uint16_t serial1;
uint16_t serial2;
error = scd4x.getSerialNumber(serial0, serial1, serial2);
if (error) {
Serial.print("Error trying to execute getSerialNumber(): ");
errorToString(error, errorMessage, 256);
Serial.println(errorMessage);
}
// Start Measurement
error = scd4x.startPeriodicMeasurement();
if (error) {
Serial.print("Error trying to execute startPeriodicMeasurement(): ");
errorToString(error, errorMessage, 256);
Serial.println(errorMessage);
}
//delay(5000);
Serial.println(F("Initialized of SC40 Air Sensor"));
////////////////////////////////////////
////////////////////////////////////////
// Start the MOX sensoe
Serial.println("SGP40 test with SHT31 compensation, it takes time to start and get enough values");
if (! sgp.begin()){
Serial.println("SGP40 sensor not found :(");
while (1);
}
if (! sht31.begin(0x44)) { // Set to 0x45 for alternate i2c addr
//if (! sht31.begin(0x45)) { // Set to 0x45 for alternate i2c addr
Serial.println("Couldn't find SHT31");
// while (1);
}
Serial.print("Found SHT3x + SGP40 serial #");
Serial.print(sgp.serialnumber[0], HEX);
Serial.print(sgp.serialnumber[1], HEX);
Serial.println(sgp.serialnumber[2], HEX);
////////////////////////////////////////
delay(5000);
Serial.println("done");
}
void loop() {
struct battery_val battery;
struct air_val air;
struct voc_val voc_values;
// get batter status
battery.volt = maxlipo.cellVoltage();
battery.percent = maxlipo.cellPercent();
air = get_air_values();
voc_values = get_voc(air.temperature, air.relative_humidity);
//Update display
updateTFT(air.temperature,air.relative_humidity,air.co2,voc_values.voc_index,voc_values.sraw,battery.volt,battery.percent);
delay(5000);
}