#include <WiFi.h>
#include <FirebaseESP32.h>
#include <DHT.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <addons/TokenHelper.h>
LiquidCrystal_I2C LCD = LiquidCrystal_I2C(0x27, 16, 2);
#define NTP_SERVER "pool.ntp.org"
#define UTC_OFFSET 0
#define UTC_OFFSET_DST 0
#define DHTPIN 2
#define DHTTYPE DHT22
const int pmSensorPin = 34;
const int co2SensorPin = 35;
const int coSensorPin = 32;
const int no2SensorPin = 33;
const int so2SensorPin = 25;
// Initialize DHT sensor
DHT dht(DHTPIN, DHTTYPE);
// Device ID
#define DEVICE_ID "Device-01"
#define WIFI_SSID "Wokwi-GUEST"
#define WIFI_PASSWORD ""
#define API_KEY "AIzaSyCr2iBF2zNG9LnIP0N1hw9-d_5tV3BN4Vk"
#define DATABASE_URL "air-quality-88ca7-default-rtdb.firebaseio.com"
#define USER_EMAIL "[email protected]"
#define USER_PASSWORD "Test@1234"
// Device Location config
String deviceLocation = "Railway station - Bambalapitiya";
// Variables to hold sensor readings
float temperature = 0;
float humidity = 0;
float pm25 = 0;
float co2 = 0;
float co = 0;
float no2 = 0;
float so2 = 0;
//Firebase Data object
FirebaseData fbdo;
FirebaseJson deviceJson;
FirebaseJson temperatureJson;
FirebaseJson humidityJson;
FirebaseJson pm25Json;
FirebaseJson co2Json;
FirebaseJson coJson;
FirebaseJson no2Json;
FirebaseJson so2Json;
FirebaseAuth auth;
FirebaseConfig config;
unsigned long sendDataPrevMillis = 0;
void WifiInit() {
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Connecting to Wi-Fi");
LCD.setCursor(0, 0);
LCD.print("Connecting to");
LCD.setCursor(0, 1);
LCD.print("WiFi...");
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
delay(300);
}
Serial.println();
Serial.print("Connected with IP: ");
Serial.println(WiFi.localIP());
Serial.println();
}
void firebaseInit() {
config.api_key = API_KEY;
auth.user.email = USER_EMAIL;
auth.user.password = USER_PASSWORD;
config.database_url = DATABASE_URL;
config.token_status_callback = tokenStatusCallback;
Firebase.begin(&config, &auth);
Firebase.reconnectWiFi(true);
Firebase.setDoubleDigits(5);
}
void dhtInit() {
dht.begin();
// Initialise device json data
deviceJson.add("device_id", DEVICE_ID);
deviceJson.add("location", deviceLocation);
// Print out initial device values
String jsonDeviceStr;
deviceJson.toString(jsonDeviceStr, true);
Serial.println(jsonDeviceStr);
// Initialise temprature json data
temperatureJson.add("name", "Temperature");
temperatureJson.add("type", "DHT22");
temperatureJson.add("value", temperature);
// Print out initial temperature values
String jsonTempStr;
temperatureJson.toString(jsonTempStr, true);
Serial.println(jsonTempStr);
// Initialise humidity json data
humidityJson.add("name", "Humidity");
humidityJson.add("type", "DHT22");
humidityJson.add("value", humidity);
// Print out initial humidity values
String jsonHumidityStr;
humidityJson.toString(jsonHumidityStr, true);
Serial.println(jsonHumidityStr);
// Initialise PM.25 json data
pm25Json.add("name", "PM.25");
pm25Json.add("type", "SDS011");
pm25Json.add("value", pm25);
// Print out initial PM.25 values
String jsonPm2Str;
pm25Json.toString(jsonPm2Str, true);
Serial.println(jsonPm2Str);
// Initialise CO2 json data
co2Json.add("name", "CO2");
co2Json.add("type", "MQ-135");
co2Json.add("value", co2);
// Print out initial CO2 values
String jsonCo2Str;
co2Json.toString(jsonCo2Str, true);
Serial.println(jsonCo2Str);
// Initialise CO json data
coJson.add("name", "CO");
coJson.add("type", "MQ-7");
coJson.add("value", co);
// Print out initial CO values
String jsonCoStr;
coJson.toString(jsonCoStr, true);
Serial.println(jsonCoStr);
// Initialise NO json data
no2Json.add("name", "NO");
no2Json.add("type", "MICS-2714");
no2Json.add("value", no2);
// Print out initial NO values
String jsonNoStr;
no2Json.toString(jsonNoStr, true);
Serial.println(jsonNoStr);
// Initialise SO2 json data
so2Json.add("name", "SO2");
so2Json.add("type", "DGS-SO2");
so2Json.add("value", so2);
// Print out initial SO2 values
String jsonSo2Str;
so2Json.toString(jsonSo2Str, true);
Serial.println(jsonSo2Str);
}
void setup() {
Serial.begin(115200);
// Initialize the measurement:
long start = micros();
LCD.init();
LCD.backlight();
WifiInit();
firebaseInit();
dhtInit();
LCD.clear();
LCD.setCursor(0, 0);
LCD.println(DEVICE_ID);
LCD.setCursor(0, 1);
LCD.println(deviceLocation);
long duration = micros() - start;
}
void updateSensorReadings(){
Serial.println("Reading Sensor data ...");
humidity = dht.readHumidity();
temperature = dht.readTemperature();
int pmValue = analogRead(pmSensorPin);
int co2Value = analogRead(co2SensorPin);
int coValue = analogRead(coSensorPin);
int no2Value = analogRead(no2SensorPin);
int so2Value = analogRead(so2SensorPin);
pm25 = map(pmValue, 0, 1023, 0, 100); // Map the value to a PM2.5 range
co2 = map(co2Value, 0, 1023, 0, 5000); // Map to CO2 range
co = map(coValue, 0, 1023, 0, 100); // Map to CO range
no2 = map(no2Value, 0, 1023, 0, 10); // Map to NO2 range
so2 = map(so2Value, 0, 1023, 0, 10); // Map to SO2 range
// Check if any reads failed and exit early (to try again).
if (isnan(temperature) || isnan(humidity)) {
Serial.println(F("Failed to read from DHT sensor!"));
return;
}
Serial.printf("Temperature reading: %.2f \n", temperature);
Serial.printf("Humidity reading: %.2f \n", humidity);
Serial.printf("PM.25 reading: %.2f \n", pm25);
Serial.printf("Co2 reading: %.2f \n", co2);
Serial.printf("Co reading: %.2f \n", co);
Serial.printf("No2 reading: %.2f \n", no2);
Serial.printf("So2 reading: %.2f \n", so2);
temperatureJson.set("value", temperature);
humidityJson.set("value", humidity);
pm25Json.set("value", pm25);
co2Json.set("value", co2);
coJson.set("value", co);
no2Json.set("value", no2);
so2Json.set("value", so2);
}
void uploadSensorData() {
if (Firebase.ready() && (millis() - sendDataPrevMillis > 1000 || sendDataPrevMillis == 0)) {
sendDataPrevMillis = millis();
updateSensorReadings();
String deviceNode = "/Railway station - Bambalapitiya/device";
String temperatureNode = "/Railway station - Bambalapitiya/temperature";
String humidityNode = "/Railway station - Bambalapitiya/humidity";
String pmNode = "/Railway station - Bambalapitiya/pm25";
String co2Node = "/Railway station - Bambalapitiya/co2";
String coNode = "/Railway station - Bambalapitiya/co";
String no2Node = "/Railway station - Bambalapitiya/no2";
String so2Node = "/Railway station - Bambalapitiya/so2";
if (Firebase.setJSON(fbdo, deviceNode.c_str(), deviceJson)) {
Serial.println("PASSED_DEVICE");
} else {
Serial.println("FAILED_DEVICE");
}
if (Firebase.setJSON(fbdo, temperatureNode.c_str(), temperatureJson)) {
Serial.println("PASSED_TEMPERATURE");
} else {
Serial.println("FAILED_TEMPERATURE");
}
if (Firebase.setJSON(fbdo, humidityNode.c_str(), humidityJson)) {
Serial.println("PASSED_HUMIDITY");
} else {
Serial.println("FAILED_HUMIDITY");
}
if (Firebase.setJSON(fbdo, pmNode.c_str(), pm25Json)) {
Serial.println("PASSED_PM.25");
} else {
Serial.println("FAILED_PM.25");
}
if (Firebase.setJSON(fbdo, co2Node.c_str(), co2Json)) {
Serial.println("PASSED_CO2");
} else {
Serial.println("FAILED_CO2");
}
if (Firebase.setJSON(fbdo, coNode.c_str(), coJson)) {
Serial.println("PASSED_CO");
} else {
Serial.println("FAILED_CO");
}
if (Firebase.setJSON(fbdo, no2Node.c_str(), no2Json)) {
Serial.println("PASSED_NO2");
} else {
Serial.println("FAILED_NO2");
}
if (Firebase.setJSON(fbdo, so2Node.c_str(), so2Json)) {
Serial.println("PASSED_SO2");
} else {
Serial.println("FAILED_SO2");
}
}
}
void loop() {
uploadSensorData();
}