# Key Outcomes
1kHz
Sample Rate
<5ms
Fault Detect
94%
ML Accuracy
60%
Downtime Cut
$40K
Savings/Event
50x
Nodes Scalable
# Problem & Solution
The Problem
- CNC machines failing without warning — $40K average cost per unplanned outage
- Existing vibration sensors needed expensive PLCs (Siemens S7) to interpret data
- No real-time visibility — operators checked machines manually every 4 hours
- Cloud-only solutions had 2–5 second latency — too slow for safety shutdowns
- Legacy RS-485 wiring had to be reused — no budget for new fieldbus
The Solution
- Bare-metal FreeRTOS firmware on RPi 4 — deterministic 1 kHz interrupt-driven sampling
- On-device FFT (CMSIS-DSP) identifies bearing fault harmonics in milliseconds
- µTensor ML model trained on 6 months of historical fault data — 94% accuracy
- Direct Modbus RTU master — bridges PLC data without new wiring
- 5ms local relay output for safety shutdown before cloud round-trip
# Firmware Architecture (Sample)
vibration_task.c — FreeRTOS vibration sampling task
/* vibration_task.c — 1kHz ADXL345 sampling with FFT fault detection */ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "arm_math.h" /* CMSIS-DSP FFT */ #include "adxl345_drv.h" #include "alarm_manager.h" #define FFT_SIZE 1024 #define SAMPLE_HZ 1000 #define BEARING_FREQ_HZ 87.3f /* BPFO for SKF 6205 bearing */ static float32_t fft_input[FFT_SIZE]; static float32_t fft_output[FFT_SIZE / 2]; static arm_rfft_fast_instance_f32 fft_inst; void vibration_task(void *pvParams) { arm_rfft_fast_init_f32(&fft_inst, FFT_SIZE); adxl345_init(SPI_BUS_0, GPIO_CS_PIN); TickType_t last_wake = xTaskGetTickCount(); for (;;) { /* Collect 1024 samples at 1kHz — fills buffer in exactly 1.024 s */ for (int i = 0; i < FFT_SIZE; i++) { fft_input[i] = (float32_t) adxl345_read_z_mg(); vTaskDelayUntil(&last_wake, pdMS_TO_TICKS(1)); } /* Run real FFT in-place */ arm_rfft_fast_f32(&fft_inst, fft_input, fft_output, 0); arm_cmplx_mag_f32(fft_output, fft_output, FFT_SIZE / 2); /* Check energy at bearing fault frequency ±2 bins */ uint32_t bin = (uint32_t)((BEARING_FREQ_HZ * FFT_SIZE) / SAMPLE_HZ); float32_t energy = fft_output[bin-2] + fft_output[bin] + fft_output[bin+2]; if (energy > FAULT_THRESHOLD_MG) { alarm_raise(ALARM_BEARING_FAULT, energy); relay_set(RELAY_SPINDLE_STOP, RELAY_ON); /* <5ms HW shutdown */ } mqtt_publish_vibration(fft_output, FFT_SIZE/2, energy); } }
modbus_master.c — RS-485 Modbus RTU for Siemens PLC integration
/* Reads spindle speed + current from Siemens S7-1200 via Modbus RTU */ typedef struct { uint16_t spindle_rpm; uint16_t motor_current_mA; uint16_t coolant_temp_dC; uint8_t fault_bits; } plc_data_t; esp_err_t modbus_read_plc(uint8_t slave_id, plc_data_t *out) { uint8_t req[] = {slave_id, 0x03, 0x00, 0x64, 0x00, 0x04}; crc16_append(req, sizeof(req) - 2); uart_write_bytes(UART_NUM_2, req, sizeof(req)); int len = uart_read_bytes(UART_NUM_2, resp_buf, 13, pdMS_TO_TICKS(50)); if (len == 13 && crc16_valid(resp_buf, len)) { out->spindle_rpm = parse_u16(resp_buf + 3); out->motor_current_mA = parse_u16(resp_buf + 5); out->coolant_temp_dC = parse_u16(resp_buf + 7); out->fault_bits = resp_buf[9]; return ESP_OK; } return ESP_ERR_TIMEOUT; }
# Full Tech Stack
Hardware
Raspberry Pi 4B (4GB)
ADXL345 (SPI)
MLX90614 IR (I²C)
MAX485 RS-485 Transceiver
4-Ch Relay HAT
7" DSI Industrial Touch
RTC DS3231
Custom breakout PCB (KiCad)
Firmware & Software
Embedded C (C99)
FreeRTOS (bare-metal)
CMSIS-DSP (FFT)
µTensor ML inference
Modbus RTU Master
MQTT (libmosquitto)
AWS IoT Core + Rules
InfluxDB + Grafana
# Project Timeline
Week 1
Hardware Design & Bring-up
KiCad schematic + PCB, sensor driver development (ADXL345 SPI, MLX90614 I²C), UART RS-485 loopback tests
Week 2
FreeRTOS Kernel & Task Design
Task hierarchy, ISR design, 1kHz sampling verified with logic analyser, ring buffer implementation
Week 3
FFT Engine & Modbus RTU
CMSIS-DSP integration, fault frequency bin mapping, Siemens S7-1200 Modbus register map, CRC16 implementation
Week 4
ML Model & Cloud Pipeline
µTensor model training (Python), model quantisation (INT8), AWS IoT Core certificate setup, InfluxDB schema
Week 5
Integration, Testing & Documentation
Factory acceptance testing, Grafana dashboards, operator manual, calibration SOP, client handover
Need This for Your Factory?
I'll custom-build a predictive maintenance system around your specific machine type, sensor suite, and PLC brand.