
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.