
Materials used in this project
Hardware components
- Particle M-SoM LTE-M/2G + Wi-Fi (M404)
- Particle M.2 SoM Breakout Board
- Seeed Studio Grove – D7S Vibration Sensor
- SparkFun 16×2 SerLCD
- M5Stack Watering Unit
- Seeed Studio Grove – Qwiic Hub
- Buzzer
Software apps and online services
- Particle Console
- Visual Studio Code
- Pushcut
Story
Earthquake early warning systems are vital because they detect ground motion at the start of an earthquake, sending alerts that provide people with valuable seconds to prepare. These systems can save lives by issuing warnings, allowing individuals and automated systems to take protective actions before the most destructive waves hit. Similarly, emergency shutdown systems are crucial as they offer a safety measure during emergencies, helping to prevent catastrophic economic, environmental, and operational impacts.
This project aims to integrate seismic activity detection with automated emergency response protocols. It involves setting up a sensor to detect early signs of an earthquake. Upon detection, the system will send instant notifications to a dedicated mobile app via a cellular network. Users will receive timely alerts to take necessary precautions. The app can also send shutdown commands to deactivate water pumps, preventing potential hazards such as flooding due to seismic activity.
In an ideal scenario, an automated system will make the decision and safely shut down the machinery. However, we have designed a system that grants us the flexibility to manually control the process, giving us the ability to make decisions based on the situation at hand. This approach ensures that in the event of a false alarm, the production unit will not be needlessly halted, preventing any unnecessary disruption.
Hardware setup
We will use a Particle M-SoM LTE-M (M404) and an M.2 SoM Breakout Board to set up and sample sensor readings, control actuators, and, most importantly, ensure cellular network connectivity. The M.2 breakout board features two power modules: PM-BAT and PM-DC. Since this setup is intended as a fixed installation, we will install the PM-DC module into the power module socket.
The Particle M-SoM is a multi-radio device featuring a high-end microcontroller, specifically a 200MHz Cortex-M33 with 16MB of flash memory and 4.5MB of RAM. We need to install the M-SoM in the M.2 socket and secure it with a thumbscrew.
For real-time monitoring of seismic activities, we will utilize the Grove – D7S Vibration Sensor which is based on the advanced D7S module developed by Omron Corporation. It is a high-precision earthquake sensor that utilizes a 3-axis acceleration sensor and a unique SI value calculation algorithm.
The SI value (Spectral Intensity) is equivalent to the average value of the integrated velocity response spectrum. It is an index that measures the destructive force of seismic motion and is closely related to damage to structures. The SI value is strongly correlated with the seismic intensity scale of Japan.
The M5Stack Watering Unit is used as a water pump. Since the water pump draws a high current, it is directly powered by a power bank using an M5Stack USB TypeC2Grove unit.
To display the sensor calibration state, system readiness state, and received commands, we are utilizing a Sparkfun 16×2 SerLCD.
We mounted a buzzer on the expansion headers that activates immediately upon detecting seismic activity during an earthquake, providing clear audio alerts to ensure safety and prompt local responses. A prototyping plate is used to secure the device in place using screws. This setup will ensure the calibration of the D7S module and allow for movement to create a tremor effect later on. We are using a glass container filled with water and a hobby water pump for our proof-of-concept project. This setup simulates an industrial environment where a powerful pump, or a similar hydraulic system, controls the filling and emptying of large tanks designated for storing hazardous chemicals or fuel.
Schematics
The D7S Vibration Sensor and Sparkfun 16×2 SerLCD are connected to the Qwiic connector and communicate over the I2C protocol. The Watering Unit is connected to the breakout board’s Grove connector. The buzzer is connected to one of the GPIO pins on the breakout board’s pin headers.
Set up M-SoM
Before starting to run the application make sure to set up your M-SoM. Please create a new account at login.particle.io/signup, then visit setup.particle.io and follow the instructions.
Set up iOS App
For this project, we wanted to use a mobile app to get alerts notifications and send a command to shutdown the water pump. We will use the Pushcut app for iOS, which allows us to create actionable notifications using a webhook and trigger an action, such as a web request, using the Apple Shortcuts, a preinstalled automation app. The Pushcut app can be installed using the App store. First, we will create a shortcut and add an action.
We will add a Get Contents of URL action that can be searched by typing “web request” keyword.
We will set up the action by configuring the following settings:
URL: https://api.particle.io/v1/devices/{DEVICE_ID}/controlPump
Method: POST
Headers: Authorization: Bearer <token>”
Request body: { “body”: { “command”: “off” } }
The controlPump is the name of a Particle Cloud function implemented in the application code. This function will be invoked by the request mentioned above. You can find the DEVICE_ID in the Particle Console, and you can create the authorization token using the Particle CLI.
$ particle token create ? Using account xyz@example.com Please enter your password: [hidden] New access token expires on Thu Jun 26 2025 00:14:07 GMT+0900 xx10f5fcfdd6cbxxxxxxxxxxc86b31aefefc0000
Now open the Pushcut app and create a new notification.
Once we have successfully saved the configuration, make sure to copy the autogenerated Webhook URL. This URL will be crucial for setting up the cloud integration in the Particle console later on. To the newly created notification, we will add an action and select the Get Component of URL shortcut.
Cloud services integration
Particle Cloud service integrations allow for efficient interaction with internet-based services, including both third-party and custom options. We will be integrating the Pushcut app as a custom webhook integration. First, we need to select the device we want to configure in the Particle Console.
Click on the Cloud services > Integrations from the left menu.
Then select the Custom Webhook from the gallery.
We need to configure the custom webhook as shown below. The chosen event name is “EarthquakeEvent” which will be set in the firmware code later. Copy and paste the webhook URL from the Pushcut app.
Build and flash the firmware
To build the firmware and upload a binary to the M-SoM, Particle provides the Workbench Visual Studio Code extension. Please follow the instructions provided at the link below.
https://docs.particle.io/quickstart/workbench
- In Workbench, select Particle: Create New Project and select the project.properties file from the project directory.
- Write the application code in the generated *.cpp file.
- Use Particle: Configure Project for Device and select M-SoM as a target platform and choose the version deviceOS@6.2.1.
- Compile with Particle: Compile application and DeviceOS (local).
- Flash with Particle: Flash application & DeviceOS (local).
Firmware
Below is the complete application code.
#include "D7S.h" #include "Particle.h" #include "SerLCD.h" #define BUZZER_PIN A0 #define PUMP_PIN A2 SYSTEM_MODE(AUTOMATIC); SYSTEM_THREAD(ENABLED); SerialLogHandler logHandler(LOG_LEVEL_INFO); SerLCD lcd; float oldSI = 0; float oldPGA = 0; typedef struct { bool enabled; uint32_t start_time; void (*buzz)(); } buzzer_t; buzzer_t buzzer; bool earthquakeOccured = false; int controlPump(String cmd) { lcd.clear(); lcd.setBacklight(153, 204, 255); lcd.setCursor(0, 0); lcd.print("Command Received"); lcd.setCursor(0, 1); lcd.print(cmd); if (cmd == "on") { digitalWrite(PUMP_PIN, HIGH); } if (cmd == "off") { digitalWrite(PUMP_PIN, LOW); } return 1; } void mainScreen(bool refreshHeader) { if (refreshHeader) { lcd.clear(); lcd.setCursor(0, 0); lcd.setBacklight(255, 255, 0); lcd.print("Earthquake Alert"); lcd.setCursor(0, 1); lcd.print("System"); } lcd.setCursor(7, 1); lcd.printf("%02d:%02d:%02d", Time.hour(), Time.minute(), Time.second()); } void setup() { Serial.begin(115200); // Enable 3V3_AUX (Do only first time) SystemPowerConfiguration powerConfig = System.getPowerConfiguration(); powerConfig.auxiliaryPowerControlPin(D23).interruptPin(A6); System.setPowerConfiguration(powerConfig); pinMode(PUMP_PIN, OUTPUT); pinMode(BUZZER_PIN, OUTPUT); digitalWrite(BUZZER_PIN, LOW); digitalWrite(PUMP_PIN, LOW); buzzer.enabled = false; buzzer.start_time = 0; Serial.print("Starting D7S communications (it may take some time)..."); D7S.begin(); lcd.begin(Wire); lcd.setBacklight(255, 255, 0); lcd.disableSystemMessages(); lcd.setContrast(5); lcd.clear(); // Set splash one time lcd.setCursor(0, 0); lcd.print("Earthquake Alert"); lcd.setCursor(0, 1); lcd.print(" System "); lcd.saveSplash(); lcd.enableSplash(); lcd.setCursor(0, 0); lcd.print("Starting D7S..."); delay(1000); while (!D7S.isReady()) { delay(500); } lcd.setCursor(0, 1); lcd.print("Done"); delay(1000); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Calibrating D7S"); lcd.setCursor(0, 1); lcd.print("Don't move!"); D7S.setAxis(SWITCH_AT_INSTALLATION); delay(2000); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Completed"); delay(1000); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Initializing..."); D7S.initialize(); while (!D7S.isReady()) { delay(500); } lcd.setCursor(0, 1); lcd.print("Done"); // reset the events shutoff/collapse memorized into the D7S D7S.resetEvents(); Time.setFormat("hh:mm:ss"); Time.zone(9); Particle.function("controlPump", controlPump); mainScreen(true); delay(1000); digitalWrite(PUMP_PIN, HIGH); } void loop() { if (D7S.isEarthquakeOccuring()) { earthquakeOccured = true; float currentSI = D7S.getInstantaneusSI(); float currentPGA = D7S.getInstantaneusPGA(); if (currentSI > oldSI || currentPGA > oldPGA) { if (!buzzer.enabled) { buzzer.enabled = true; buzzer.start_time = millis(); } lcd.clear(); lcd.setCursor(0, 0); lcd.printf("SI: %.1f m/s", currentSI); lcd.setCursor(0, 1); lcd.printf("PGA: %.1f m/s^2", currentPGA); lcd.setBacklight(255, 102, 255); Serial.print("\tInstantaneus SI: "); Serial.print(currentSI); Serial.println(" [m/s]"); Serial.print("\tInstantaneus PGA (Peak Ground Acceleration): "); Serial.print(currentPGA); Serial.println(" [m/s^2]\n"); char buf[100] = {0}; JSONBufferWriter writer(buf, sizeof(buf)); writer.beginObject(); writer.name("SI").value(currentSI); writer.name("PGA").value(currentPGA); writer.endObject(); Particle.publish("EarthquakeEvent", buf); oldSI = currentSI; oldPGA = currentPGA; } if (buzzer.enabled) { tone(BUZZER_PIN, 2500, 500); delay(500); if (millis() - buzzer.start_time > 5000) { buzzer.enabled = false; } } } else { if (earthquakeOccured) { mainScreen(true); } else { mainScreen(false); } earthquakeOccured = false; oldPGA = 0; oldSI = 0; D7S.resetEvents(); } delay(1000); }
Demo
For the demonstration, we attempted to simulate an industrial environment to display the functionality of a water pump with running liquid. While a real industrial setting is significantly more complex, this setup serves the intended purpose.
Conclusion
This project represents a significant leap forward in disaster response technology. It seamlessly integrates a cellular network with a mobile application to swiftly and reliably alert individuals of seismic events. The remote water pump shutdown feature via the app is crucial in preventing infrastructure damage and mitigating post-earthquake water-related risks. This project conclusively demonstrates the effectiveness of utilizing cost-effective and reliable bi-directional communication via cellular networks in emergency management systems.