edge lab LIVE! starts Tuesday in Munich. Grab a workshop seat and take home the board you build on. Code FRIEND-HACKSTER saves 20%. () Learn more!
balli2000in
Published © GPL3+

Real-Time Motor Vibration Anomaly Detection Using Edge AI

Detect abnormal motor vibrations in real time by running a NanoEdge AI Machine Learning model directly on an STM32 microcontroller.

AdvancedFull instructions provided2 hours61
Real-Time Motor Vibration Anomaly Detection Using Edge AI

Things used in this project

Hardware components

STM32F103C8T6
×1
Analog Accelerometer: ADXL335
Adafruit Analog Accelerometer: ADXL335
×1
SparkFun USB to Serial Breakout - FT232RL
SparkFun Electronics SparkFun USB to Serial Breakout - FT232RL
×1
5 mm LED: Red
5 mm LED: Red
×1
5 mm LED: Green
5 mm LED: Green
×1
Resistor 220 ohm
Resistor 220 ohm
×2
Male/Female Jumper Wires
Male/Female Jumper Wires
×1
Male/Male Jumper Wires
×1
ST Link V2 Programmer For STM8 and STM32
×1
Nano USB A-Mini B 1.2m Cable Nickel-Plated Connector
×1
DC Cooling Blade Fan
×1

Software apps and online services

Arduino IDE
Arduino IDE
Nano Edge AI Studio

Hand tools and fabrication machines

Mastech MS8217 Autorange Digital Multimeter
Digilent Mastech MS8217 Autorange Digital Multimeter
Wire Stripper & Cutter, 18-10 AWG / 0.75-4mm² Capacity Wires
Wire Stripper & Cutter, 18-10 AWG / 0.75-4mm² Capacity Wires

Story

Read more

Schematics

Circuit Diagram for this Project

Code

capture vibration data from the GY-61 For Training and Testing of ML

C/C++
Collect vibration data
// ============================================================
// STM32F103C8T6 + GY-61
// Non-Blocking High-Speed Data Logger (True 1000 Hz)
// ============================================================

#define ACC_X PA0
#define ACC_Y PA1
#define ACC_Z PA2

HardwareSerial MySerial(PA10, PA9);

const uint16_t BUFFER_SIZE = 256;
const uint32_t SAMPLE_PERIOD_US = 1000; // 1 ms = 1000 Hz

// Storage arrays in RAM (takes only ~1.5 KB of STM32's 20 KB RAM)
uint16_t x_buf[BUFFER_SIZE];
uint16_t y_buf[BUFFER_SIZE];
uint16_t z_buf[BUFFER_SIZE];

void setup()
{
  analogReadResolution(12);
  MySerial.begin(115200);
  delay(1000);
}

void loop()
{
  uint32_t nextSampleTime = micros();

  // ------------------------------------------------
  // 1. FAST SAMPLING PHASE (Strict 1000 Hz, No Serial)
  // ------------------------------------------------
  for (uint16_t sample = 0; sample < BUFFER_SIZE; sample++)
  {
    while ((int32_t)(micros() - nextSampleTime) < 0)
    {
      // Wait for exact microsecond mark
    }
    nextSampleTime += SAMPLE_PERIOD_US;

    // Read ADC and store immediately in RAM (~40 us total)
    x_buf[sample] = analogRead(ACC_X);
    y_buf[sample] = analogRead(ACC_Y);
    z_buf[sample] = analogRead(ACC_Z);
  }

  // ------------------------------------------------
  // 2. DUMP PHASE (Transmit safely after collection)
  // ------------------------------------------------
  for (uint16_t sample = 0; sample < BUFFER_SIZE; sample++)
  {
    MySerial.print(x_buf[sample]);
    MySerial.print(" ");
    MySerial.print(y_buf[sample]);
    MySerial.print(" ");
    MySerial.print(z_buf[sample]);

    if (sample < BUFFER_SIZE - 1)
    {
      MySerial.print(" ");
    }
  }
  MySerial.println(); // Signal end of buffer to NanoEdge AI

  // Brief pause before capturing next signal window
  delay(50);
}

final Edge AI application used to detect Anomaly

C/C++
Run ML inference and detect anomalies
#include "NanoEdgeAI.h"

// ---------------- SENSOR PINS ----------------
#define ACC_X PA0
#define ACC_Y PA1
#define ACC_Z PA2

// ---------------- STATUS LED PINS ----------------
#define LED_PC13 PC13  // Onboard Blue Pill LED (Active-LOW)
#define LED_PA5  PA5   // Normal indicator LED (Active-HIGH)
#define LED_PA6  PA6   // Anomaly indicator LED (Active-HIGH)

// UART debug on PA9/PA10
HardwareSerial MySerial(PA10, PA9);

// Buffer size: 256 * 3 = 768 floats[cite: 1]
float input_signal[NEAI_INPUT_SIGNAL_LENGTH * NEAI_INPUT_AXIS_NUMBER];
uint8_t similarity = 0;

void setup() {
  // Configure LED pins as outputs
  pinMode(LED_PC13, OUTPUT);
  pinMode(LED_PA5, OUTPUT);
  pinMode(LED_PA6, OUTPUT);

  // Default state: all LEDs OFF at start
  digitalWrite(LED_PC13, HIGH); // PC13 is active-low (HIGH = OFF)
  digitalWrite(LED_PA5, LOW);   // PA5 OFF
  digitalWrite(LED_PA6, LOW);   // PA6 OFF

  // 12-bit ADC configuration
  analogReadResolution(12);

  MySerial.begin(115200);
  delay(1000);

  // Initialize NEAI with pretrained model[cite: 1]
  bool use_pretrained = true;
  enum neai_state state = neai_anomalydetection_init(use_pretrained);
  
  if (state != NEAI_OK) {
    MySerial.print("Init Error: ");
    MySerial.println(state);
    while (1); // Halt
  }
  MySerial.println("NEAI Model Ready.");
}

void loop() {
  uint32_t nextSampleTime = micros();

  // 1000 Hz hardware-aligned capture
  for (uint16_t sample = 0; sample < NEAI_INPUT_SIGNAL_LENGTH; sample++) {
    while ((int32_t)(micros() - nextSampleTime) < 0);
    nextSampleTime += 1000;

    uint16_t idx = sample * NEAI_INPUT_AXIS_NUMBER;
    input_signal[idx]     = (float)analogRead(ACC_X);
    input_signal[idx + 1] = (float)analogRead(ACC_Y);
    input_signal[idx + 2] = (float)analogRead(ACC_Z);
  }

  // Run Inference[cite: 1]
  enum neai_state state = neai_anomalydetection_detect(input_signal, &similarity);

  if (state == NEAI_OK) {
    MySerial.print("Similarity: ");
    MySerial.print(similarity);

    if (similarity < 85) {
      // ---------------- ANOMALY DETECTED ----------------
      MySerial.println("% -> [ANOMALY]");

      // Turn OFF normal LEDs
      digitalWrite(LED_PC13, HIGH); // PC13 OFF (active-low)
      digitalWrite(LED_PA5, LOW);   // PA5 OFF

      // Turn ON anomaly LED
      digitalWrite(LED_PA6, HIGH);  // PA6 ON
    } else {
      // ---------------- NORMAL OPERATION ----------------
      MySerial.println("% -> [NORMAL]");

      // Turn ON normal LEDs
      digitalWrite(LED_PC13, LOW);  // PC13 ON (active-low)
      digitalWrite(LED_PA5, HIGH);  // PA5 ON

      // Turn OFF anomaly LED
      digitalWrite(LED_PA6, LOW);   // PA6 OFF
    }
  }
}

Credits

balli2000in
5 projects • 1 follower

Comments