
I am doing this project to better understand how physical machines behave and how their signals can be turned into meaningful digital insight. By building a small, on-prem digital twin from real sensors and real data, I can learn how hardware, data pipelines, signal processing, and models fit together as one system. The goal is not a finished product, but practical understanding that transfers to larger industrial problems like monitoring, diagnostics, and predictive maintenance.
Build a learning-focused digital twin of a personal workshop.
Purpose: understand physical signals → data pipeline → digital representation
Focus on observability and system understanding
Not a production system
No machine control
Fully on-prem, LAN-only
Machines planned in the twin (3–4 total):
Lathe (first instrumented and active)
Mill
Furnace
3D printer
Phase-1 behavior:
Show machine state only
OFF / IDLE / RUNNING / FAULT / UNKNOWN
Visual indicators only
No start/stop or control actions
Dell Precision 3420
Ubuntu 22.04.5 LTS
Runs headless, 24/7
SSH hardened (key-only, no passwords)
Acts as:
MQTT broker
Data aggregation point
Visualization host
All devices on the same LAN
No internet dependency
MQTT used for all telemetry
Mosquitto
IP: 192.168.0.105
Port: 1883
Anonymous LAN access
Verified with CLI and live subscriptions
workshop/<machine>/heartbeat
workshop/<machine>/telemetry
(workshop/<machine>/state planned next)
FireBeetle ESP32-S3
Boots fully headless
Stable Wi-Fi and MQTT reconnect logic
Powered from wall USB supply (not machine USB)
LIS2DW12 accelerometer
I2C @ 100 kHz
Address: 0x19
Mounted directly on lathe structure
High-Performance mode
±2 g range
100 Hz internal ODR
Telemetry published at 5 Hz
Confirms device health and connectivity.
{
"device": "firebeetle-esp32s3",
"machine": "lathe",
"uptime_ms": 186373,
"rssi": -46
}
Raw acceleration in physical units.
{
"device": "firebeetle-esp32s3",
"machine": "lathe",
"uptime_ms": 186573,
"accel_mps2": [-1.42, 9.77, -0.18]
}
End-to-end verified:
Sensor → ESP32 → Wi-Fi → MQTT → subscriber
Derived on the server side:
Acceleration magnitude
mag = sqrt(x² + y² + z²)
Vibration proxy
vib = |mag − baseline|
Baseline = slow EMA to remove gravity and orientation
Observed behavior:
Machine OFF → low, stable vib
Machine RUNNING → sustained elevated vib
Impacts / tool contact → sharp spikes
The signal clearly separates machine states.
Live plots of the last ~10 seconds
Shows:
Raw acceleration magnitude
Vibration proxy
Confirms real-time response to machine behavior
Device only ran when Arduino IDE opened
Root cause: while (!Serial) blocking boot
Fixed by removing serial dependency
Sensor failures when mounted on machine
Root causes: power quality, timing, EMI sensitivity
Fixed with:
Wall power
I2C speed reduction
Retry-based sensor initialization
✅ Hardware stable
✅ Telemetry streaming reliably
✅ Signal quality sufficient for classification
✅ End-to-end data path proven
⏸️ No ML or state inference yet
Machine-learning–based state inference
Start with OFF vs RUNNING
Use vibration features:
RMS
Variance
Frequency energy
Decide inference location:
Server-side first
Edge later if needed
Publish results to:
workshop/lathe/state