This project demonstrate how flutter mobile app integrates with the Blynk Iot Platform. Monitor the following sensory data:-
- Temperature
- Humidity
- Door State
- Movement/Motion
Future work will be using supervised machine learning classification algorithms to detect human pressence in the room.
https://github.com/armut/Occupancy-Detection
This project is a starting point for a Flutter application.
A few resources to get you started if this is your first Flutter project:
For help getting started with Flutter, view our online documentation, which offers tutorials, samples, guidance on mobile development, and a full API reference.
- Room's temperature
- Room's humidity
- Room's door state
firmware/Xiaomi_ESP32_Blynk/Xiaomi_ESP32_Blynk.ino
#define BLYNK_PRINT Serial #include <WiFi.h> #include <WiFiClient.h> #include <BlynkSimpleEsp32.h> //#include <EEPROM.h> #include "BLEDevice.h" #include "soc/soc.h" #include "soc/rtc_cntl_reg.h" String receivedTemperatureValue = ""; String receivedHumidityValue = ""; #define uS_TO_S_FACTOR 1000000 //Conversion factor for micro seconds to seconds #define TIME_TO_SLEEP 20 //Time ESP32 will go to sleep (in seconds) RTC_DATA_ATTR int bootCount = 0; static BLEAddress *addressOfOurThermometer; BLERemoteService* remoteServiceOfTheThermometer; static BLERemoteCharacteristic* characteristicOfTheTemperatureMeasurementValue; BLERemoteDescriptor* descriptorForStartingAndEndingNotificationsFromCharacteristic; BLEClient* thisOurMicrocontrollerAsClient; unsigned long startTime PROGMEM ; const int doorSensor = 4; const int greenLED = 2; // You should get Auth Token in the Blynk App. // Go to the Project Settings (nut icon). char auth[] = "xxx"; // Your WiFi credentials. // Set password to "" for open networks. char ssid[] = "xxx"; char pass[] = "xxxx"; BlynkTimer timer; class theEventsThatWeAreInterestedInDuringScanning: public BLEAdvertisedDeviceCallbacks { void onResult(BLEAdvertisedDevice advertisedDevice) { if (advertisedDevice.getName() == "MJ_HT_V1") { advertisedDevice.getScan()->stop(); addressOfOurThermometer = new BLEAddress(advertisedDevice.getAddress()); } } }; static void notifyAsEachTemperatureValueIsReceived(BLERemoteCharacteristic* pBLERemoteCharacteristic, uint8_t* receivedNotification, size_t length, bool isNotify) { for (int i=2; i<=5; i++) { receivedTemperatureValue += (char)*(receivedNotification+i); } for (int i=9; i<=12; i++) { receivedHumidityValue += (char)*(receivedNotification+i); } Serial.println(receivedTemperatureValue); Serial.println(receivedHumidityValue); delay(3000); if (receivedTemperatureValue.length() < 0 && receivedHumidityValue.length() < 0) return; int doorstate = digitalRead(doorSensor); if(doorstate == 1){ Blynk.virtualWrite(V2, "Open"); Serial.println("Open"); digitalWrite(greenLED,HIGH); }else{ Blynk.virtualWrite(V2, "Closed"); Serial.println("Closed"); digitalWrite(greenLED,LOW); } delay(2000); Blynk.virtualWrite(V0, receivedTemperatureValue); Blynk.virtualWrite(V1, receivedHumidityValue); Serial.println("Disconnect from BLE device."); thisOurMicrocontrollerAsClient->disconnect(); hibernate(); } void hibernate() { esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR); Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) + " Seconds"); Serial.println("Going to sleep now."); Serial.flush(); delay(1000); esp_deep_sleep_start(); } void readTempHumidity() { if (thisOurMicrocontrollerAsClient->isConnected() == false) { thisOurMicrocontrollerAsClient->disconnect(); delay(20); thisOurMicrocontrollerAsClient->connect(*addressOfOurThermometer); startTime = millis(); } // Here the our ESP32 as a client asks for a connection to the desired target device. if( thisOurMicrocontrollerAsClient->isConnected() == false ) { Serial.println(F("e4 Connection couln't be established")); } if (remoteServiceOfTheThermometer == nullptr) { remoteServiceOfTheThermometer = thisOurMicrocontrollerAsClient->getService("226c0000-6476-4566-7562-66734470666d"); } if (remoteServiceOfTheThermometer == nullptr) { thisOurMicrocontrollerAsClient->disconnect(); } if (characteristicOfTheTemperatureMeasurementValue == nullptr) { characteristicOfTheTemperatureMeasurementValue = remoteServiceOfTheThermometer->getCharacteristic("226caa55-6476-4566-7562-66734470666d"); } if (characteristicOfTheTemperatureMeasurementValue == nullptr) { thisOurMicrocontrollerAsClient->disconnect(); } if(characteristicOfTheTemperatureMeasurementValue != nullptr){ characteristicOfTheTemperatureMeasurementValue->registerForNotify(notifyAsEachTemperatureValueIsReceived); } if (descriptorForStartingAndEndingNotificationsFromCharacteristic == nullptr) { descriptorForStartingAndEndingNotificationsFromCharacteristic = characteristicOfTheTemperatureMeasurementValue->getDescriptor(BLEUUID((uint16_t)0x2902)); } if (descriptorForStartingAndEndingNotificationsFromCharacteristic == nullptr) { thisOurMicrocontrollerAsClient->disconnect(); } uint8_t startNotifications[2] = {0x01,0x00}; if(descriptorForStartingAndEndingNotificationsFromCharacteristic != nullptr){ descriptorForStartingAndEndingNotificationsFromCharacteristic->writeValue(startNotifications, 2, false); } // Ideas: https://stackoverflow.com/questions/1269568/how-to-pass-a-constant-array-literal-to-a-function-that-takes-a-pointer-without startTime = millis(); while( ( (millis() - startTime) < 5000) && (receivedTemperatureValue.length() < 4) ) { if (thisOurMicrocontrollerAsClient->isConnected() == false) { } } characteristicOfTheTemperatureMeasurementValue->registerForNotify(NULL); uint8_t endNotifications[2] = {0x00,0x00}; descriptorForStartingAndEndingNotificationsFromCharacteristic->writeValue(endNotifications, 2, false); if (receivedTemperatureValue.length() < 4) Serial.println(F("e14 No proper temperature measurement value catched.")); thisOurMicrocontrollerAsClient->disconnect(); } void setup() { Serial.begin(115200); WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); Serial.setDebugOutput(0); pinMode(doorSensor, INPUT); pinMode(greenLED, OUTPUT); BLEDevice::init("esp32tempsensor"); BLEScan* myBLEScanner = BLEDevice::getScan(); myBLEScanner->setAdvertisedDeviceCallbacks(new theEventsThatWeAreInterestedInDuringScanning()); myBLEScanner->setActiveScan(true); while (addressOfOurThermometer == nullptr) { myBLEScanner->start(30); startTime=millis(); while ( (millis()-startTime <50) && (addressOfOurThermometer == nullptr) ) { delay(1); } } thisOurMicrocontrollerAsClient = BLEDevice::createClient(); digitalWrite(greenLED,LOW); Blynk.begin(auth, ssid, pass); Blynk.syncAll(); timer.setInterval(1000L, readTempHumidity); timer.setInterval(30*1000, reconnectBlynk); //run every 30s } void reconnectBlynk() { if (!Blynk.connected()) { Serial.println("Lost connection"); if(Blynk.connect()) { Serial.println("Reconnected"); } else { Serial.println("Not reconnected"); } } } void loop() { if (Blynk.connected()) { // If connected run as normal Blynk.run(); } timer.run(); } - Human/living life form movment
firmware/MotionDetector/MotionDetector.ino
#include <WiFi.h> #include <HTTPClient.h> const int motionSensor PROGMEM = 12; const char* ssid = "xxx"; const char* password = "xxx"; WiFiClient espClient; void invokeRequest(String value){ HTTPClient http; http.begin(value); //Specify the URL int httpCode = http.GET(); //Make the request if (httpCode > 0) { //Check for the returning code String payload = http.getString(); Serial.println(httpCode); Serial.println(payload); } else { Serial.println("Error on HTTP request"); ESP.restart(); } http.end(); //Free the resources } void turnONLight(){ invokeRequest("http://blynk-cloud.com/85a4ddf0b61149149fdffx2506590484c/update/V1?value=255"); //v1 to 255 delay(50); invokeRequest("http://blynk-cloud.com/85a4ddf0b61149149fdfxf2506590484c/update/V2?value=255"); //v2 to 255 delay(50); invokeRequest("http://blynk-cloud.com/85a4ddf0b61149149fdxff2506590484c/update/V3?value=255"); //v3 to 255 delay(50); invokeRequest("http://blynk-cloud.com/238dc3bbbcfc4ed39a97c2x12d51f313a/update/V3?value=1"); //v3 to 1 delay(50); } void offLight(){ invokeRequest("http://blynk-cloud.com/85a4ddf0b61149149fxdff2506590484c/update/V1?value=0"); //v1 to 0 delay(50); invokeRequest("http://blynk-cloud.com/85a4ddf0b61149149fdfxf2506590484c/update/V2?value=0"); //v2 to 0 delay(50); invokeRequest("http://blynk-cloud.com/85a4ddxf0b61149149fdff2506590484c/update/V3?value=0"); //v3 to 0 delay(50); invokeRequest("http://blynk-cloud.com/238dc3bbbcfcx4ed39a97c212d51f313a/update/V3?value=0"); //v3 to 1 delay(50); } void setup_wifi() { delay(10); // We start by connecting to a WiFi network Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); } void setup() { Serial.begin(115200); Serial.setDebugOutput(0); pinMode(motionSensor, INPUT); setup_wifi(); printWifiStatus(); offLight(); } void loop() { int motion = digitalRead(motionSensor); Serial.println(motion); if(motion == 1){ Serial.println("MOTION DETECTED!!!"); Serial.println("LOSER !!!"); turnONLight(); delay(15000); offLight(); } Serial.println("WINNER !!!"); delay(2000); } void printWifiStatus() { // print the SSID of the network you're attached to: Serial.print("SSID: "); Serial.println(WiFi.SSID()); // print your WiFi shield's IP address: IPAddress ip = WiFi.localIP(); Serial.print("IP Address: "); Serial.println(ip); // print the received signal strength: long rssi = WiFi.RSSI(); Serial.print("signal strength (RSSI):"); Serial.print(rssi); Serial.println(" dBm"); } 



