Differences

This shows you the differences between two versions of the page.

Link to this comparison view

iothings:proiecte:2023:earthquakedetector [2024/01/13 17:16]
stefania.frunza
iothings:proiecte:2023:earthquakedetector [2024/01/16 00:07] (current)
stefania.frunza [Hardware]
Line 4: Line 4:
   * Master: AAC   * Master: AAC
   * Academic year: 2023-2024   * Academic year: 2023-2024
 +  * Source files: {{:​iothings:​proiecte:​2023:​earthquake_alg.zip|}}
 +  * [[https://​ctipub-my.sharepoint.com/:​p:/​g/​personal/​stefania_frunza_stud_acs_upb_ro/​EarzChLzdI5HsabqWMbrtRUBHImtb95MCGP3-NyDnDz_sA?​e=MOVfD3|Presentation slides]]
 +  * [[https://​youtu.be/​qQ3m6rQsA1Q|Demo]]
 +
 =====Introduction===== =====Introduction=====
 ===Context=== ===Context===
-TBD+Earthquakes,​ as natural disasters, pose a dual threat—potentially resulting in the loss of human lives and causing substantial material damage. The project we have developed centers around monitoring earthquake occurrences,​ providing users with timely notifications via phone and web interfaces, and archiving records in a database. This comprehensive approach enables users to promptly assess seismic activity at the sensor'​s location, empowering them to take immediate and informed measures in response to potential earthquakes. 
 ===Project Description=== ===Project Description===
-TBD+The idea of this project is to gather measurements from a MPU-6050 sensor (with an accelerometer and a gyroscope) and to process the data in order to detect the occurrence of an earthquake. When an earthquake is detected, the following things will happen: 
 +  * on a webpage in the LAN the "​Earthquake detected"​ message will be displayed 
 +  * on the connected LCD the "​Earthquake detected"​ message will be displayed 
 +  * a notification will be sent on the user's phone 
 +  * an entry will be added to the InfluxDB project'​s readings
  
 =====Architecture===== =====Architecture=====
 ====System overview==== ====System overview====
-TBD+{{:​iothings:​proiecte:​2023:​eqd_overview.png?​800|}} 
 ====Hardware==== ====Hardware====
 ===Components=== ===Components===
-  * BOARD: +  * Board 
-    * **NodeMCU-32S** - based on the ESP-WROOM-32 module that integrates WIFI and Bluetooth+    * [[https://​ardushop.ro/​ro/​home/​1449-nodemcu-32s-38.html?​search_query=esp32&​results=22|NodeMCU-32S - based on the ESP-WROOM-32 module that integrates WIFI and Bluetooth]]
  
-  * SENSOR+  * Sensor
-    * **MPU-6050** - an integrated circuit with accelerometer,​ gyroscope and temperature sensor with an I2C interface+    * [[https://​ardushop.ro/​ro/​electronica/​179-modul-giroscop-accelerometru-3-axe.html|MPU-6050 - an integrated circuit with accelerometer,​ gyroscope and temperature sensor with an I2C interface]]
  
   * LCD:   * LCD:
-    * **LCD 16x2** - an LCD screen with yellow-green backlighting and an I2C interface+    * [[https://​ardushop.ro/​ro/​electronica/​36-lcd-1602.html|LCD 16x2 - an LCD screen with yellow-green backlighting and an I2C interface]] 
 + 
 +  * Breadboard 
 + 
 +  * Wires 
  
 ===Circuit Diagram=== ===Circuit Diagram===
-TBD+In order to use the Earthquake Detector system, the ESP32 board has to be connected to a power source. The hardware assembly should be positioned in a place free from unwanted moves (e.g. tram or elevator trepidations). Depending on the needs, the user can access the webpage in the LAN that will signalize the occurrence of an earthquake. Anyway, When an earthquake is detected, the user will receive a notification on the phone and will be able to visualize the moment of occurrence in the database. 
 + 
 +{{:​iothings:​proiecte:​2023:​eqd_diagram.png?​750|}} 
 + 
 +The Pinout scheme of the ESP32 board that I used is the following:​ 
 + 
 +{{:​iothings:​proiecte:​2023:​esp-nodemcu-32s_pinout_w600.jpg?​400|}}
  
 ===Real-life view=== ===Real-life view===
-TBD+{{:​iothings:​proiecte:​2023:​real_life_view_eqd.jpeg?​300|}}
  
 ====Software==== ====Software====
-===Earthquake Detection algorithm=== +{{:​iothings:​proiecte:​2023:​eqd_flow_2_.png|}}
-TBD+
  
 +===Setup function===
  
-===Code & Structure=== +The first step is to initialize the MPU-6050 sensor, the SPIFFS (since the html code is uploaded on the board'​s SPIFFS), the LCD and to connect the board to Wi-Fi. Also, because we use a notification system and InluxDB, we had to sync time, then we check the InfluxDB server connection. Then, we start the server for HTTP requests and create a handler for web server events.
-TBD+
  
-==Arduino== +<code C> 
-TBD+void setup() { 
 +  Serial.begin(115200);​ 
 +  initMPU();​ 
 +  initSPIFFS();​ 
 +  initWiFi();​ 
 +  initLCD();
  
-==Web app== +  configTime(gmtOffset_sec,​ daylightOffset_sec,​ ntpServer);​ 
-TBD+ 
 +  sensor.addTag("​device",​ "​ESP32"​);​ 
 +  sensor.addTag("​location",​ "​office"​);​ 
 +  sensor.addTag("​WiFi_Name",​ WIFI_NAME);​ 
 + 
 +  // Accurate time is necessary for certificate validation and writing in batches 
 +  // For the fastest time sync find NTP servers in your area: https://​www.pool.ntp.org/​zone/​ 
 +  // Syncing progress and the time will be printed to Serial. 
 +  timeSync(TZ_INFO,​ ntpServer, "​time.nis.gov"​);​ 
 + 
 +  // Check server connection 
 +  if (client.validateConnection()) { 
 +    Serial.print("​Connected to InfluxDB: "); 
 +    Serial.println(client.getServerUrl());​ 
 +  } else { 
 +    Serial.print("​InfluxDB connection failed: "); 
 +    Serial.println(client.getLastErrorMessage());​ 
 +  } 
 + 
 +  server.on("/",​ HTTP_GET, [](AsyncWebServerRequest *request){ 
 +    request->​send(SPIFFS,​ "/​index.html",​ "​text/​html"​);​ 
 +  }); 
 + 
 +  server.serveStatic("/",​ SPIFFS, "/"​);​ 
 + 
 +  // Handle Web Server Events 
 +  events.onConnect([](AsyncEventSourceClient *client){ 
 +     
 +    if(client->​lastId()){ 
 +      Serial.printf("​Client reconnected! Last message ID that it got is: %u\n", client->​lastId());​ 
 +    } 
 +    client->​send("​{\"​message\":​ \"​hello!\"​}",​ NULL, millis(), 10000); 
 +  }); 
 +  server.addHandler(&​events);​ 
 + 
 +  server.begin();​ 
 + 
 +
 +</​code>​ 
 + 
 +===Loop function=== 
 +We start the loop function by making the first read of the MPU-6050 sensor'​s data. This way we get the data against which we will compare the following readings, always storing data from 2 consecutive readings. If the difference between any of the gyroscope or accelerometer'​s data is over a threshold, then an earthquake has been detected. In this case the following actions will take place: 
 +  * an event will be sent in order to make a POST request to the webpage with the information "​Earthquake detected":​ 
 +<code C> 
 +events.send("​Earthquake_detected","​eqd",​millis());​ 
 +</​code>​ 
 +  * a notification will be sent to the user's phone, to warn him about the occurrence of an earthquake:​ 
 +<code C> 
 +sendNotification();​ 
 +</​code>​ 
 +  * the LCD screen will display the message "​Earthquake detected":​ 
 +<code C> 
 +    lcd.backlight();​ 
 +    lcd.setCursor(0,​ 0); 
 +    lcd.print(" ​  ​Earthquake ​  "​);​ 
 +    lcd.setCursor(0,​ 1); 
 +    lcd.print(" ​   detected ​   ");  
 +    //... 
 +    delay(5000);​ 
 +    lcd.clear();​ 
 +</​code>​ 
 +  * add information to the database: 
 +<code C> 
 +    // Store measured value into point 
 +    sensor.clearFields();​ 
 +    // Report RSSI of currently connected network 
 +    sensor.addField("​event",​ "​Earthquake occured"​);​ 
 +    // Print what are we exactly writing 
 +    Serial.print("​Writing:​ "); 
 +    Serial.println(client.pointToLineProtocol(sensor));​ 
 +    // If no Wifi signal, try to reconnect it 
 +    // Write point 
 +    if (!client.writePoint(sensor)) { 
 +      Serial.print("​InfluxDB write failed: "); 
 +      Serial.println(client.getLastErrorMessage());​ 
 +    } 
 +</​code>​ 
 +  * print on the Serial about the occurrence of the earthquake and show the subtraction'​s results between old and new MPU's readings. 
 +This is the body of loop function: 
 +<code C> 
 +void loop() { 
 + 
 +  old_a = a; 
 +  old_g = g; 
 +  old_temp = temp; 
 + 
 +  mpu.getEvent(&​a,​ &g, &​temp);​ 
 + 
 +  if((old_a.acceleration.x == 0) && (old_a.acceleration.y == 0) && (old_a.acceleration.z == 0) &&  
 +     ​(old_g.gyro.x == 0) && (old_g.gyro.y == 0) && (old_g.gyro.z == 0)) { 
 + 
 +    Serial.println("​a.acceleration.x = " + String(a.acceleration.x));​ 
 +    Serial.println("​a.acceleration.y = " + String(a.acceleration.y));​ 
 +    Serial.println("​a.acceleration.z = " + String(a.acceleration.z));​ 
 +    Serial.println("​g.gyro.x = " + String(g.gyro.x));​ 
 +    Serial.println("​g.gyro.y = " + String(g.gyro.y));​ 
 +    Serial.println("​g.gyro.z = " + String(g.gyro.z));​ 
 + 
 +    return; 
 +  } 
 + 
 +  if((abs(g.gyro.x - old_g.gyro.x) >= gyroTh) ||  
 +     ​(abs(g.gyro.y - old_g.gyro.y) >= gyroTh) || 
 +     ​(abs(g.gyro.z - old_g.gyro.z) >= gyroTh) || 
 +     ​(abs(a.acceleration.x - old_a.acceleration.x) >= accTh) ||  
 +     ​(abs(a.acceleration.y - old_a.acceleration.y) >= accTh) ||  
 +     ​(abs(a.acceleration.z - old_a.acceleration.z) >= accTh)) { 
 + 
 +     
 +    events.send("​Earthquake_detected","​eqd",​millis());​ 
 +    sendNotification();​ 
 +     
 + 
 +    lcd.backlight();​ 
 +    lcd.setCursor(0,​ 0); 
 +    lcd.print(" ​  ​Earthquake ​  "​);​ 
 +    lcd.setCursor(0,​ 1); 
 +    lcd.print(" ​   detected ​   ");  
 + 
 +    // Store measured value into point 
 +    sensor.clearFields();​ 
 +    // Report RSSI of currently connected network 
 +    sensor.addField("​event",​ "​Earthquake occured"​);​ 
 +    // Print what are we exactly writing 
 +    Serial.print("​Writing:​ "); 
 +    Serial.println(client.pointToLineProtocol(sensor));​ 
 +    // If no Wifi signal, try to reconnect it 
 +    // Write point 
 +    if (!client.writePoint(sensor)) { 
 +      Serial.print("​InfluxDB write failed: "); 
 +      Serial.println(client.getLastErrorMessage());​ 
 +    } 
 +     
 +    Serial.println("​Earthquake detected."​);​ 
 +    Serial.println("​g.gyro.x - old_g.gyro.x = " + String(g.gyro.x - old_g.gyro.x));​ 
 +    Serial.println("​g.gyro.y - old_g.gyro.y = " + String(g.gyro.y - old_g.gyro.y));​ 
 +    Serial.println("​g.gyro.z - old_g.gyro.z = " + String(g.gyro.z - old_g.gyro.z));​ 
 +     
 +    Serial.println("​a.acceleration.x - old_a.acceleration.x = " + String(a.acceleration.x - old_a.acceleration.x));​ 
 +    Serial.println("​a.acceleration.y - old_a.acceleration.y = " + String(a.acceleration.y - old_a.acceleration.y));​ 
 +    Serial.println("​a.acceleration.z - old_a.acceleration.z = " + String(a.acceleration.z - old_a.acceleration.z));​ 
 + 
 +    a.acceleration.x = old_a.acceleration.x;​ 
 +    a.acceleration.y = old_a.acceleration.y;​ 
 +    a.acceleration.z = old_a.acceleration.z;​ 
 +    g.gyro.x = old_g.gyro.x;​ 
 +    g.gyro.y = old_g.gyro.y;​ 
 +    g.gyro.z = old_g.gyro.z;​ 
 +     
 +    delay(5000);​ 
 +    lcd.clear();​ 
 +  } else { 
 +    events.send("​No_earthquake_detected","​neqd",​millis());​ 
 +    delay(100);​ 
 +  } 
 +
 +</​code>​ 
 + 
 +===sendNotification() function=== 
 +For sending notifications,​ we used the Pushover App, which allows you to receive notifications from custom applications. It offers a free 30-day trial period, so it was just enough for developing this project. I created a Pushover account and then a new application. With the generated API Token and user key we were able to send notifications to users' devices. 
 +<code C> 
 +void sendNotification() { 
 +  // Make HTTPS POST request to send notification 
 +  if (WiFi.status() == WL_CONNECTED) { 
 +    // Create a JSON object with notification details 
 +    // Check the API parameters: https://​pushover.net/​api 
 +    StaticJsonDocument<​512>​ notification;​  
 +    notification["​token"​] = apiToken; //​required 
 +    notification["​user"​] = userToken; //​required 
 +    notification["​message"​] = "​Earthquake detected at " + getLocalTime();​ //​required 
 +    notification["​title"​] = "BAD NEWS"; //​optional 
 +    notification["​url"​] = "";​ //​optional 
 +    notification["​url_title"​] = "";​ //​optional 
 +    notification["​html"​] = "";​ //​optional 
 +    notification["​priority"​] = "";​ //​optional 
 +    notification["​sound"​] = "";​ //​optional 
 +    notification["​timestamp"​] = "";​ //​optional 
 + 
 +    // Serialize the JSON object to a string 
 +    String jsonStringNotification;​ 
 +    serializeJson(notification,​ jsonStringNotification);​ 
 + 
 +    // Create a WiFiClientSecure object 
 +    WiFiClientSecure client; 
 +    // Set the certificate 
 +    client.setCACert(PUSHOVER_ROOT_CA);​ 
 + 
 +    // Create an HTTPClient object 
 +    HTTPClient https; 
 + 
 +    // Specify the target URL 
 +    https.begin(client,​ pushoverApiEndpoint);​ 
 + 
 +    // Add headers 
 +    https.addHeader("​Content-Type",​ "​application/​json"​);​ 
 + 
 +    // Send the POST request with the JSON data 
 +    int httpResponseCode = https.POST(jsonStringNotification);​ 
 + 
 +    // Check the response 
 +    if (httpResponseCode > 0) { 
 +      Serial.printf("​HTTP response code: %d\n", httpResponseCode);​ 
 +      String response = https.getString();​ 
 +      Serial.println("​Response:"​);​ 
 +      Serial.println(response);​ 
 +    } else { 
 +      Serial.printf("​HTTP response code: %d\n", httpResponseCode);​ 
 +    } 
 + 
 +    // Close the connection 
 +    https.end();​ 
 +  } 
 +
 +</​code>​ 
 + 
 +===Web app==
 +The times when I was running away from web developing have finally come to an end. With a very simple interface and some JavaScript code, we managed to send the information to the webpage in real time and show a message accordingly to the occurrence of an earthquake. 
 +<code html> 
 +<​!DOCTYPE html> 
 +<html lang="​en">​ 
 +<​head>​ 
 +    <meta charset="​UTF-8">​ 
 +    <meta name="​viewport"​ content="​width=device-width,​ initial-scale=1.0">​ 
 +    <link rel="​icon"​ href="/​favicon.ico"​ type="​image/​x-icon">​ 
 + 
 +    <​title>​ESP32 MPU-6050 Earthquake Detection</​title>​ 
 +    <​style>​ 
 +        body { 
 +            font-family:​ Arial, sans-serif;​ 
 +            text-align: center; 
 +            margin: 50px; 
 +        } 
 + 
 +        h1 { 
 +            color: #333; 
 +        } 
 + 
 +        #status { 
 +            font-size: 24px; 
 +            margin-top: 20px; 
 +        } 
 + 
 +        .earthquake { 
 +            color: red; 
 +        } 
 + 
 +        .no-earthquake { 
 +            color: green; 
 +        } 
 +    </​style>​ 
 +</​head>​ 
 +<​body>​ 
 +    <​h1>​ESP32 MPU-6050 Earthquake Detection</​h1>​ 
 +    <div id="​status"​ class="​no-earthquake">​No earthquake detected</​div>​ 
 + 
 +    <​script>​ 
 +        if (!!window.EventSource) { 
 +         var source = new EventSource('/​events'​);​ 
 +          
 +         ​source.addEventListener('​open',​ function(e) { 
 +          console.log("​Events Connected"​);​ 
 +         }, false); 
 +         ​source.addEventListener('​error',​ function(e) { 
 +          if (e.target.readyState != EventSource.OPEN) { 
 +            console.log("​Events Disconnected"​);​ 
 +          } 
 +         }, false); 
 +          
 +         ​source.addEventListener('​message',​ function(e) { 
 +          console.log("​message",​ e.data); 
 +         }, false); 
 +          
 +         ​source.addEventListener('​eqd',​ function(e) { 
 +          console.log("​eqd",​ e.data); 
 +          document.getElementById('​status'​).innerText = '​Earthquake detected';​ 
 +          document.getElementById('​status'​).classList.add('​earthquake'​);​ 
 +          document.getElementById('​status'​).classList.remove('​no-earthquake'​);​ 
 +         }, false); 
 +          
 +         ​source.addEventListener('​neqd',​ function(e) { 
 +          console.log("​neqd",​ e.data); 
 +          document.getElementById('​status'​).innerText = 'No earthquake detected';​ 
 +          document.getElementById('​status'​).classList.remove('​earthquake'​);​ 
 +          document.getElementById('​status'​).classList.add('​no-earthquake'​);​ 
 +         }, false); 
 +        } 
 +        </​script>​ 
 + 
 +</​body>​ 
 +</​html>​ 
 +</​code>​
  
 =====Results===== =====Results=====
-TBD+===Web interface=== 
 +When no earthquake is detected, this is how the webpage looks like: 
 + 
 +{{:​iothings:​proiecte:​2023:​webpage_neqd.png?​500|}} 
 + 
 +When an earthquake is detected, this is how the webpage looks like: 
 + 
 +{{:​iothings:​proiecte:​2023:​webpage_eqd.png?​500|}} 
 + 
 +===Notifications=== 
 +In the notification bar, the notification about the occurrence of an earthquake will look like this: 
 + 
 +{{:​iothings:​proiecte:​2023:​notification_bar_eqd.jpeg?​300|}} 
 + 
 +In the Pushover App, the notification history will be stored like this: 
 + 
 +{{:​iothings:​proiecte:​2023:​notification_list_eqd.jpeg?​500|}} 
 + 
 +===InfluxDB=== 
 +This is how are stored the events in InfluxDB: 
 + 
 +{{:​iothings:​proiecte:​2023:​influxdb_eqd.png?​800|}} 
 + 
 +=====Conclusion and Future Work===== 
 +This project can accomplish its purpose if there are some others conditions met. For example, the board with the sensor must be placed in a stable place, free from unwanted moves (e.g. tram or elevator trepidations). Otherwise, it is possible to return false positive results. However, the algorithm used in earthquake detection is a simplistic one and is also prone to wrong results.
  
-=====Conclusion===== +I tried to add MQTT to this project, in order to make the results more accessible for a large number of clients. I will keep this in mind as a future development for this project. Also, I would like to improve the detection algorithm, so that it will take into account readings from the IMU sensor over a larger amount of time (2 seconds, so we can compare the mean of these readings with a threshold).
-TBD+
  
 =====References===== =====References=====
Line 58: Line 396:
 [[https://​randomnerdtutorials.com/​esp32-mpu-6050-accelerometer-gyroscope-arduino/​|ESP32 with MPU-6050 Accelerometer,​ Gyroscope and Temperature Sensor]] [[https://​randomnerdtutorials.com/​esp32-mpu-6050-accelerometer-gyroscope-arduino/​|ESP32 with MPU-6050 Accelerometer,​ Gyroscope and Temperature Sensor]]
  
-[[https://​randomnerdtutorials.com/​esp32-esp8266-i2c-lcd-arduino-ide/​How to Use I2C LCD with ESP32 on Arduino IDE]]+[[https://​randomnerdtutorials.com/​esp32-esp8266-i2c-lcd-arduino-ide/​|How to Use I2C LCD with ESP32 on Arduino IDE]]
  
-[[https://​randomnerdtutorials.com/​esp32-web-server-sent-events-sse/​|Update Sensor Readings Automatically ​Tutoria]]+[[https://​randomnerdtutorials.com/​esp32-web-server-sent-events-sse/​|ESP32 Web Server using Server-Sent Events (Update Sensor Readings Automatically)]]
  
-[[https://​randomnerdtutorials.com/​esp32-pushover-notifications-arduino/​|Pushover Notifications ​Tutorial]]+[[https://​randomnerdtutorials.com/​esp32-pushover-notifications-arduino/​|ESP32: Send Pushover Notifications ​(Arduino IDE)]] 
 + 
 +[[https://​randomnerdtutorials.com/​esp32-date-time-ntp-client-server-arduino/​|ESP32 NTP Client-Server:​ Get Date and Time]] 
 + 
 +[[https://​randomnerdtutorials.com/​esp32-influxdb/​|ESP32:​ Getting Started with InfluxDB]]
  
 [[https://​pushover.net/​api|Pushover API]] [[https://​pushover.net/​api|Pushover API]]
 +
 +[[https://​www.espressif.com/​sites/​default/​files/​documentation/​esp32-wroom-32_datasheet_en.pdf|ESP32 Datasheet]]
  
 [[https://​www.waveshare.com/​datasheet/​LCD_en_PDF/​LCD1602.pdf|LCD Datasheet]] [[https://​www.waveshare.com/​datasheet/​LCD_en_PDF/​LCD1602.pdf|LCD Datasheet]]
  
 [[https://​invensense.tdk.com/​wp-content/​uploads/​2015/​02/​MPU-6000-Datasheet1.pdf|MPU-6050 Datasheet]] [[https://​invensense.tdk.com/​wp-content/​uploads/​2015/​02/​MPU-6000-Datasheet1.pdf|MPU-6050 Datasheet]]
- 
  
iothings/proiecte/2023/earthquakedetector.1705159002.txt.gz · Last modified: 2024/01/13 17:16 by stefania.frunza
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0