/****************************************************************************************************************************** * Date: 28/02/2023 * Filename: LabSage_v1.1.5 * Description: ESP Multitasking + EMS * Update - Changing thresholds, re-timing tasks - Resetting GAS threshold as constant value due to large difference *****************************************************************************************************************************/ // INCLUDE LIBRARIES #include // Install TaskScheduler Arduino Library #include // Install WiFiManager Library #include // Install Firebase ESP8266 library (Mobitz?) #include #include #include // Install DHT11 Library and Adafruit Unified Sensor Library #include #include #include // Install Adafruit ADXL345 accelerometer library // FIREBASE RTDB PATH AND KEY #define FIREBASE_HOST "https://smartlab-9b83e-default-rtdb.firebaseio.com/" #define FIREBASE_AUTH "AIzaSyCiO5owTmUgosDyjL0_SqpxRoAwgKtn5-o" // SETTING PINS FOR SENSORS #define LED D1 #define DHTPIN D2 // Connect Data pin of DHT to D2 #define GASPIN A0 // Gas sensor analog pin #define BUZZERPIN D7 // Connect LED to D7 #define SDA D5 #define SCL D6 // DHT VARIABLE SET #define DHTTYPE DHT11 // OBJECT DECLARATIONS Scheduler runner; WiFiManager wm; DHT dht(DHTPIN, DHTTYPE); Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345); //MQ2 parameter for LPG/Smoke sensing float gasSensor_volt; float RS; const float R0 = 2.12; const float b = 1.5120222; const float m = -0.33975668; float RS_R0_ratio; float ppm_log; float ppm; // VARIABLE DEFINITION float t, h, g; String buzz = "0"; String coll = "0"; float x, y, z; String PATH = "Devices/"; String UID = ""; float sum = 0; int k = 0; // THRESHOLD VALUES const float COLLISION_THRESHOLD = 10.0; // Too sensitive perhaps? const float SMOKE_THRESHOLD = 15000; // NEEDS TO BE UPLOADED TO THE BOARD YET!!! // DEFINE FIREBASE DATA OBJECT FirebaseData firebaseData; FirebaseData buzzerData; FirebaseJson json; // FUNCTION DECLARATION void dhtSetup(void); void gasSetup(void); void ambiRead(void); void accelSetup(void); void accelRead(void); void sensorUpdate(void); void upload(void); void uploadAlert(void); void sensorReset(void); void reconnection(void); // TASK SCHEDULE FUNCTIONS void task1Callback() { // Sensor update // code for task 1 sensorUpdate(); } void task2Callback() { // Sensor value upload // code for task 2 if (WiFi.status() == WL_CONNECTED) { upload(); } else { Serial.println("Connection Lost!"); digitalWrite(LED, !digitalRead(LED)); Serial.println("Please Reconnect to a different WiFi.\nStarting Soft API..."); reconnection(); } } void task3Callback(){ // Reset receive and execute if (WiFi.status() == WL_CONNECTED){ if (Firebase.getString(buzzerData, PATH + "/reset") && buzzerData.stringData() == "1") { //Read from firebase for application Serial.println("Call to reset"); sensorReset(); if (Firebase.setString(firebaseData, PATH + "/reset", "0")) { Serial.println("PASSED"); Serial.println("PATH: " + firebaseData.dataPath()); Serial.println("TYPE: " + firebaseData.dataType()); Serial.println("ETag: " + firebaseData.ETag()); Serial.println("------------------------------------"); Serial.println(); } else { Serial.println("FAILED"); Serial.println("REASON: " + firebaseData.errorReason()); Serial.println("------------------------------------"); Serial.println(); } uploadAlert(); } if (buzz == "1" || coll== "1"){ uploadAlert(); } } else { Serial.println("Connection Lost!"); digitalWrite(LED, !digitalRead(LED)); Serial.println("Please Reconnect to a different WiFi.\nStarting Soft API..."); reconnection(); } } Task t1(1000, TASK_FOREVER, &task1Callback); // Task rate: Once every second Task t2(60000, TASK_FOREVER, &task2Callback); // Task rate: Once every minute Task t3(3000, TASK_FOREVER, &task3Callback); // Task rate: Once every 3 seconds // SETUP void setup(){ pinMode(LED, OUTPUT); digitalWrite(LED, LOW); pinMode(BUZZERPIN, OUTPUT); Serial.begin(9600); dhtSetup(); gasSetup(); accelSetup(); UID = ESP.getChipId(); // Extract Unique Chip ID for authentication and identity purposes Serial.printf("ESP8266 Unique Chip id = %s\n", UID); // For hex representation, use %08X Serial.println(); Serial.println("Opening WiFi AP"); // wm.resetSettings(); // Comment out before deployment bool res; wm.setConnectTimeout(60); wm.setConfigPortalTimeoutCallback(reconnection); wm.setWiFiAutoReconnect(true); res = wm.autoConnect("SMI_LBS_ESP"); // auto generated AP name from chipid if (!res) { Serial.println("Failed to connect"); } else { //if you get here you have connected to the WiFi Serial.println("Connected"); } Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH); // Begin Firebase Server Firebase.reconnectWiFi(true); Serial.println(PATH.concat(UID)); // Dynamic database path allocation digitalWrite(LED, HIGH); runner.init(); // Initialise Scheduler, add tasks to it, and then enable the tasks for multitasking runner.addTask(t1); runner.addTask(t2); runner.addTask(t3); t1.enable(); t2.enable(); t3.enable(); } // MAIN LOOP CODE void loop() { runner.execute(); // Run the tasks simultaneously } void reconnection(void) { // Re-establishing network with new Wi-Fi using Soft AP bool res = wm.autoConnect(); if (!res) { Serial.println("Failed to connect"); } else { Serial.println("Connected"); } } void accelSetup(void) { // Setup Accelerometer Serial.println("Accelerometer Test"); Serial.println(""); // Initialise I2C communication as MASTER Wire.begin(SDA, SCL); if (!accel.begin()) { Serial.println("Failed to initialize ADXL345 sensor."); while (1); } accel.setRange(ADXL345_RANGE_16_G); // Setting Max Range // Get accelerometer data sensors_event_t event; accel.getEvent(&event); // Assign current values to states x = event.acceleration.x; y = event.acceleration.y; z = event.acceleration.z; Serial.println("Accelerometer Ready!"); Serial.println(""); } void accelRead(void) { // Read Accelerometer // Get accelerometer data sensors_event_t event; accel.getEvent(&event); // Print the accelerometer data to serial monitor Serial.print("Acceleration: "); Serial.print(event.acceleration.x); Serial.print(" m/s^2 "); Serial.print(event.acceleration.y); Serial.print(" m/s^2 "); Serial.print(event.acceleration.z); Serial.println(" m/s^2 "); if (isnan(event.acceleration.x) || isnan(event.acceleration.y) || isnan(event.acceleration.z)) { Serial.println(F("Failed to read from Accelerometer!")); return; } // Check if there is a collision if ((abs(event.acceleration.x - x)) > COLLISION_THRESHOLD || (abs(event.acceleration.y - y)) > COLLISION_THRESHOLD || (abs(event.acceleration.z - z)) > COLLISION_THRESHOLD) { Serial.println("Collision detected!"); coll = "1"; tone(BUZZERPIN, 100); } // Assign current values to states x = event.acceleration.x; y = event.acceleration.y; z = event.acceleration.z; } void dhtSetup(void) { // Setup DHT11 Serial.println(F("DHT11 setting up...")); dht.begin(); Serial.println("DHT11 ready!"); } void gasSetup(void) { // Setup MQ-2 Smoke Sensor Serial.println("Gas Sensor setting up..."); pinMode(GASPIN, INPUT_PULLUP); Serial.println("Gas Sensor ready!"); Serial.printf("\nSmoke Threshold: %f ppm\n", SMOKE_THRESHOLD); Serial.println(""); } void ambiRead(void) { // Temp, Humidity, Gas reading // Read relative humidity in % (the default) h = dht.readHumidity(); // Read temperature as Celsius (the default) t = dht.readTemperature(); // Read gas sensor analog data float gasSensorValue = analogRead(GASPIN); gasSensor_volt = gasSensorValue / 1024 * 5.0; RS = ((5 - gasSensor_volt) / gasSensor_volt); RS_R0_ratio = RS / R0; ppm_log = ((log (RS_R0_ratio) - b) / m); ppm = pow (10, ppm_log); g = ppm; // Check if any reads failed and exit early (to try again). if (isnan(h) || isnan(t)) { Serial.println(F("Failed to read from DHT sensor!")); return; } if(isnan(g)){ Serial.println(F("Failed to read from Gas sensor!")); return; } // Check if there is a fire/smoke if (g > SMOKE_THRESHOLD) { sum += g; k++; Serial.println("Smoke detected!"); buzz = "1"; tone(BUZZERPIN, 400); } else { if(k<=10){ buzz = "0"; if (coll == "0") { noTone(BUZZERPIN); }} } Serial.print(F("Humidity: ")); Serial.print(h); Serial.print(F("% Temperature: ")); Serial.print(t); Serial.print(F("C PPM:")); Serial.print(g); Serial.println(); } void sensorUpdate(void) { ambiRead(); accelRead(); } void sensorReset(void) { coll = "0"; buzz = "0"; noTone(BUZZERPIN); sum = 0; k = 0; } void upload(void) { if (Firebase.setFloat(firebaseData, PATH + "/temperature", t)) { Serial.println("PASSED"); Serial.println("PATH: " + firebaseData.dataPath()); Serial.println("TYPE: " + firebaseData.dataType()); Serial.println("ETag: " + firebaseData.ETag()); Serial.println("------------------------------------"); Serial.println(); } else { Serial.println("FAILED"); Serial.println("REASON: " + firebaseData.errorReason()); Serial.println("------------------------------------"); Serial.println(); } if (Firebase.setFloat(firebaseData, PATH + "/humidity", h)) { Serial.println("PASSED"); Serial.println("PATH: " + firebaseData.dataPath()); Serial.println("TYPE: " + firebaseData.dataType()); Serial.println("ETag: " + firebaseData.ETag()); Serial.println("------------------------------------"); Serial.println(); } else { Serial.println("FAILED"); Serial.println("REASON: " + firebaseData.errorReason()); Serial.println("------------------------------------"); Serial.println(); } if (Firebase.setFloat(firebaseData, PATH + "/ppm", g)) { Serial.println("PASSED"); Serial.println("PATH: " + firebaseData.dataPath()); Serial.println("TYPE: " + firebaseData.dataType()); Serial.println("ETag: " + firebaseData.ETag()); Serial.println("------------------------------------"); Serial.println(); } else { Serial.println("FAILED"); Serial.println("REASON: " + firebaseData.errorReason()); Serial.println("------------------------------------"); Serial.println(); } if (Firebase.setFloat(firebaseData, PATH + "/x", x)) { Serial.println("PASSED"); Serial.println("PATH: " + firebaseData.dataPath()); Serial.println("TYPE: " + firebaseData.dataType()); Serial.println("ETag: " + firebaseData.ETag()); Serial.println("------------------------------------"); Serial.println(); } else { Serial.println("FAILED"); Serial.println("REASON: " + firebaseData.errorReason()); Serial.println("------------------------------------"); Serial.println(); } if (Firebase.setFloat(firebaseData, PATH + "/y", y)) { Serial.println("PASSED"); Serial.println("PATH: " + firebaseData.dataPath()); Serial.println("TYPE: " + firebaseData.dataType()); Serial.println("ETag: " + firebaseData.ETag()); Serial.println("------------------------------------"); Serial.println(); } else { Serial.println("FAILED"); Serial.println("REASON: " + firebaseData.errorReason()); Serial.println("------------------------------------"); Serial.println(); } if (Firebase.setFloat(firebaseData, PATH + "/z", z)) { Serial.println("PASSED"); Serial.println("PATH: " + firebaseData.dataPath()); Serial.println("TYPE: " + firebaseData.dataType()); Serial.println("ETag: " + firebaseData.ETag()); Serial.println("------------------------------------"); Serial.println(); } else { Serial.println("FAILED"); Serial.println("REASON: " + firebaseData.errorReason()); Serial.println("------------------------------------"); Serial.println(); } } void uploadAlert(void){ if (Firebase.setString(firebaseData, PATH + "/buzzer", buzz)) { Serial.println("PASSED"); Serial.println("PATH: " + firebaseData.dataPath()); Serial.println("TYPE: " + firebaseData.dataType()); Serial.println("ETag: " + firebaseData.ETag()); Serial.println("------------------------------------"); Serial.println(); } else { Serial.println("FAILED"); Serial.println("REASON: " + firebaseData.errorReason()); Serial.println("------------------------------------"); Serial.println(); } if (Firebase.setString(firebaseData, PATH + "/collision", coll)) { Serial.println("PASSED"); Serial.println("PATH: " + firebaseData.dataPath()); Serial.println("TYPE: " + firebaseData.dataType()); Serial.println("ETag: " + firebaseData.ETag()); Serial.println("------------------------------------"); Serial.println(); } else { Serial.println("FAILED"); Serial.println("REASON: " + firebaseData.errorReason()); Serial.println("------------------------------------"); Serial.println(); } } /* void startCustomConfigPortal() { WiFiManager wifiManager; wifiManager.setConfigPortalTimeout(120); wifiManager.setMinimumSignalQuality(-1); const char * pass = "SM1ota#W"; //"46EAD57A89F1D240CBD7704B6FAD544C"; //"46ead57a89f1d240cbd7704b6fad544c"; WiFiManagerParameter password("", "Developer Options Password", "", 40); wifiManager.addParameter(&password); WiFiManagerParameter customHtmlOptions("
Info  Update"); const char * c1 = customHtmlOptions.getValue(); wifiManager.setCustomHeadElement(c1); if (!wifiManager.startConfigPortal("Custom Config Portal")) { Serial.println("Failed to connect and hit timeout"); delay(3000); ESP.reset(); delay(5000); } const char * uPass = password.getValue(); Serial.println(); if (strcmp(uPass, pass) == 0) { WiFiManagerParameter customHtmlDeveloperOptions("
Info  Update"); const char * c = customHtmlDeveloperOptions.getValue(); wifiManager.setCustomHeadElement(c); } else { wifiManager.setCustomHeadElement(""); wifiManager.startConfigPortal("Custom Config Portal"); } } */