TinyML-Based Object Drop Classifier Using MPU6050 and W55RP20-EVB-Pico
Deploying a Fall Detection ML Model on W5500-EVB-Pico Using Edge Impulse

Introduction
Fall and object drop detection is a critical aspect of safety in industrial environments and for elderly individuals. This project demonstrates how to build a machine learning-based system using the MPU6050 6-axis IMU sensor, Edge Impulse platform, and the WIZnet W55RP20-EVB-Pico (RP2040-based) board to detect and classify fall or object drop events.
This guide walks you through the entire development process—from sensor data collection to model training and deployment on a microcontroller.
Core Hardware & Technology
Component | Description |
---|---|
W55RP20-EVB-Pico | RP2040 MCU integrated with W5500 Ethernet chip |
MPU6050 | 3-axis accelerometer + 3-axis gyroscope IMU sensor |
Edge Impulse | TinyML platform for embedded machine learning model training and deployment |
Arduino IDE | Environment for firmware development and deployment |
Implementation
✅ Data Collection
How to setup Pico as Edge device with Edge Impulse
Motion recognition + anomaly detection Guide
Used Edge Impulse's Data Forwarder to collect labeled sensor data for drop
and idle
states from the MPU6050
Data was streamed in real time over Serial and labeled within the Edge Impulse Studio
✅ Model Training
Signal processing: Spectral features
Classifier: Dense Neural Network
Target labels: drop
, idle
✅ Device Deployment and Inference
Trained model exported as an Arduino library (.zip) for deployment on RP2040
Real-time inference executed using the run_classifier()
function
Serial output triggered on detecting drop
, with support for event hooks
✅ WIZnet W55RP20-EVB-Pico Arduino build guide
>> How to Build W55RP20-EVB-Pico on Arduino
🧠 Code Logic
#include <W55RP20_MPU6050_inferencing.h>
#include <Wire.h>
#include <MPU6050.h>
#define CONVERT_G_TO_MS2 9.80665f
#define FREQUENCY_HZ EI_CLASSIFIER_FREQUENCY
#define INTERVAL_MS (1000 / (FREQUENCY_HZ + 1))
MPU6050 accelgyro;
int16_t ax, ay, az;
static unsigned long last_interval_ms = 0;
float features[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE];
size_t feature_ix = 0;
void setup() {
Serial.begin(115200);
while (!Serial);
Serial.println("[START] Drop Detection with Edge Impulse + MPU6050");
Wire.begin();
accelgyro.initialize();
if (!accelgyro.testConnection()) {
Serial.println("MPU6050 connection failed!");
while (1);
}
Serial.println("MPU6050 connected.");
run_classifier_init();
}
void loop() {
if (millis() > last_interval_ms + INTERVAL_MS) {
last_interval_ms = millis();
accelgyro.getAcceleration(&ax, &ay, &az);
features[feature_ix++] = (float)ax * CONVERT_G_TO_MS2;
features[feature_ix++] = (float)ay * CONVERT_G_TO_MS2;
features[feature_ix++] = (float)az * CONVERT_G_TO_MS2;
if (feature_ix >= EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE) {
ei_impulse_result_t result = { 0 };
signal_t signal;
numpy::signal_from_buffer(features, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE, &signal);
EI_IMPULSE_ERROR res = run_classifier(&signal, &result, false);
ei_printf("run_classifier returned: %d\n", res);
if (res != EI_IMPULSE_OK) return;
ei_printf("Predictions (DSP: %d ms., Classification: %d ms., Anomaly: %d ms.): \n",
result.timing.dsp, result.timing.classification, result.timing.anomaly);
for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
ei_printf("%s:\t%.5f\n", result.classification[ix].label, result.classification[ix].value);
if (strcmp(result.classification[ix].label, "drop") == 0 && result.classification[ix].value > 0.8f) {
Serial.println("\n🔥 drop detected! Take action!\n");
}
}
#if EI_CLASSIFIER_HAS_ANOMALY == 1
ei_printf("anomaly:\t%.3f\n", result.anomaly);
#endif
feature_ix = 0;
}
}
}
void ei_printf(const char *format, ...) {
static char print_buf[1024] = { 0 };
va_list args;
va_start(args, format);
int r = vsnprintf(print_buf, sizeof(print_buf), format, args);
va_end(args);
if (r > 0) {
Serial.write(print_buf);
}
}