How to Create an Indoor Temperature, Humidity, and Air Quality Monitoring System with ESP32-C6
Poor indoor air quality can lead to health problems. An indoor environment monitoring system based on the FireBeetle 2 ESP32-C6 IoT Development Board and other open-source hardware platforms is not only easy to configure and assemble but also more cost-effective than many commercial air monitoring systems. This tutorial will guide you through building an indoor environment monitoring system using the ESP32 development board, SHT31 temperature and humidity sensor, ENS160 air quality sensor, and a lithium battery. You'll be able to monitor and record indoor temperature, humidity, air quality index (AQI), volatile organic compounds (VOCs), and eCO2 in real-time.
Hardware Connections
Data Collection and Processing
The ESP32 microcontroller serves as the core processing unit, responsible for collecting sensor data, processing and analyzing it, and transmitting the data wirelessly to a server. The software logic includes:
1. Battery Voltage Collection:
- Use the ESP32 IO0 pin to collect battery voltage.
- Convert the collected analog voltage signal to a digital signal via ADC for further processing.
2. Temperature, Humidity, and Air Quality Data Collection:
- Use the ESP32's I2C to read data from the sensors.
3. Data Reporting:
- Connect to a wireless network using the ESP32 WiFi module.
- Report the collected data to a server via HTTP for remote monitoring and management.
Sample code
#include <WiFi.h>
#include <HTTPClient.h>
#include <DFRobot_SHT3x.h>
#include <DFRobot_ENS160.h>
DFRobot_SHT3x sht3x;
DFRobot_ENS160_I2C ENS160(&Wire, /*iicAddr*/ 0x53);
// #define DATA_SEND_INTERVAL_MS 15 * 60 * 1000
#define DATA_SEND_INTERVAL_MS 60 * 1000
int lastDataSentTimestamp = 0;
unsigned long previousMillis = 0;
unsigned long interval = 30000;
// WiFi network information
const char* ssid = "your_SSID";
const char* password = "your_PASSWORD";
// Server URL
const char* serverName = "http://192.168.1.236:5000/update";
const char* serverToken = "your_influx_token";
// Define ADC pin
const int batteryPin = 0; // IO0
void sendData() {
// Collect battery voltage
int batteryVoltage = analogReadMilliVolts(batteryPin)*2;
Serial.print("BAT millivolts value = ");
Serial.print(batteryVoltage);
Serial.println("mV");
// Collect temperature and humidity
float temperature = sht3x.getHumidityRH();
Serial.print("Temperature(C):");
Serial.println(temperature);
float humidity = sht3x.getTemperatureC();
Serial.print("Humidity(RH):");
Serial.println(humidity);
// Collect air quality
ENS160.setTempAndHum(temperature, humidity);
uint8_t AQI = ENS160.getAQI();
Serial.print("AIQ : ");
Serial.println(AQI);
uint16_t TVOC = ENS160.getTVOC();
Serial.print("TVOC(ppb): ");
Serial.println(TVOC);
uint16_t ECO2 = ENS160.getECO2();
Serial.print("ECO2(ppm): ");
Serial.println(ECO2);
// Create HTTP client
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin(serverName);
http.addHeader("Content-Type", "text/plain");
http.addHeader("authorization", serverToken);
// Create POST data
String httpRequestData = "batteryVoltage=" + String(batteryVoltage) + "&Temperature=" + String(temperature) + "&Humidity=" + String(humidity) + "&AIQ=" + String(AQI) + "&TVOC=" + String(TVOC) + "&ECO2=" + String(ECO2);
// Send HTTP POST request
int httpResponseCode = http.POST(httpRequestData);
// Print response result
if (httpResponseCode > 0) {
String response = http.getString();
Serial.println(httpResponseCode);
Serial.println(response);
} else {
Serial.print("Error on sending POST: ");
Serial.println(httpResponseCode);
}
// End HTTP request
http.end();
}
}
void setup() {
Serial.begin(115200);
// Initialize SHT31
while (sht3x.begin() != 0) {
Serial.println("SHT31 error");
delay(1000);
}
// Initialize ENS160
while( NO_ERR != ENS160.begin() ){
Serial.println("ENS160 error");
delay(1000);
}
ENS160.setPWRMode(ENS160_STANDARD_MODE);
// Connect to WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
sendData();
}
void loop() {
unsigned long currentMillis = millis();
// if WiFi is down, try reconnecting
if ((WiFi.status() != WL_CONNECTED) && (currentMillis - previousMillis >= interval)) {
Serial.print(millis());
Serial.println("Reconnecting to WiFi...");
WiFi.disconnect();
WiFi.reconnect();
previousMillis = currentMillis;
}
if (millis() > lastDataSentTimestamp + DATA_SEND_INTERVAL_MS) {
sendData();
Serial.print("Millis since last measurement: ");
Serial.println(millis() - lastDataSentTimestamp);
lastDataSentTimestamp = millis();
}
}
Server Setup
1. Install Python 3.
2. Install Flask:
- Press Win+R, type cmd, and open the command prompt.
- Enter pip install flask to install Flask.
3. Run the Python code in the command line.
from flask import Flask, request, jsonify
app = Flask(__name__)
# Endpoint to handle data from Arduino
@app.route('/update', methods=['POST'])
def update():
auth_header = request.headers.get('authorization')
if (auth_header == 'your_influx_token'):
data = request.data.decode('utf-8')
print(f"Received data: {data}")
# Process the data sent from Arduino here, such as storing it in a database
return jsonify({"status": "success", "message": "Data received"}), 200
else:
return jsonify({"status": "error", "message": "Unauthorized"}), 401
@app.route('/')
def home():
return "Hello from Flask server!", 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
Now you can check the data:
Learn More About the Data:
For more information on interpreting air quality data, refer to: ENS160 Air Quality Sensor Wiki
Project Expansion
The onboard GDI interface allows for easy connection to screens, ensuring efficient data visualization. Detailed screen lists and configuration tutorials are provided to facilitate seamless integration of ESP32-C6 functionalities into any setup.
DFRobot's all Gravity and Fermion series sensors are compatible with the FireBeetle 2 ESP32-C6, offering a comprehensive selection for various projects.
Conclusion
This guide details the design and implementation of an indoor environment monitoring system based on the ESP32 development board, SHT31 temperature and humidity sensor, ENS160 air quality sensor, and a lithium battery. By integrating these advanced hardware devices and IoT technology, we successfully achieved real-time monitoring and data analysis of key indoor air quality parameters.