enum SystemStatus {
NORMAL,
WARNING,
FAULT
};
const int GREEN_LED = D2;
const int YELLOW_LED = D3;
const int RED_LED = D4;
const int NUM_SAMPLES = 20;
int vibrationSamples[NUM_SAMPLES];
int sampleIndex = 0;
float vibrationRMS = 0;
float temperature = 0;
float phase = 0.0;
// Timer flags
volatile bool tempReady = false;
volatile bool vibrationReady = false;
// Hardware timers
HardwareTimer tempTimer(TIM3);
HardwareTimer vibrationTimer(TIM16);
// Temperature timer interrupt
void onTempTimer() {
tempReady = true;
}
// Vibration timer interrupt
void onVibrationTimer() {
vibrationReady = true;
}
SystemStatus checkStatus(float temperature, float vibrationRMS) {
if (temperature >= 80 || vibrationRMS >= 50) {
return FAULT;
}
else if (temperature >= 60 || vibrationRMS >= 20) {
return WARNING;
}
else {
return NORMAL;
}
}
void showStatus(SystemStatus status) {
digitalWrite(GREEN_LED, LOW);
digitalWrite(YELLOW_LED, LOW);
digitalWrite(RED_LED, LOW);
if (status == NORMAL) {
digitalWrite(GREEN_LED, HIGH);
}
else if (status == WARNING) {
digitalWrite(YELLOW_LED, HIGH);
}
else if (status == FAULT) {
digitalWrite(RED_LED, HIGH);
}
}
void setup() {
Serial.begin(115200);
pinMode(GREEN_LED, OUTPUT);
pinMode(YELLOW_LED, OUTPUT);
pinMode(RED_LED, OUTPUT);
// Temperature every 500 ms
tempTimer.setOverflow(500000, MICROSEC_FORMAT);
tempTimer.attachInterrupt(onTempTimer);
tempTimer.resume();
// Vibration every 5 ms
vibrationTimer.setOverflow(5000, MICROSEC_FORMAT);
vibrationTimer.attachInterrupt(onVibrationTimer);
vibrationTimer.resume();
Serial.println("STM32 Condition Monitoring System");
Serial.println("--------------------------------");
}
void loop() {
// -----------------------
// VIBRATION SAMPLING
// -----------------------
if (vibrationReady) {
vibrationReady = false;
// Read potentiometer as vibration amplitude control
int amplitudeAdc = analogRead(A1);
// Map potentiometer 0-1023 to vibration amplitude 0-100 ADC counts
float amplitude = (amplitudeAdc / 1023.0) * 100.0;
static bool directionUp = true;
static float simulatedVibration = 512.0;
if (directionUp) {
simulatedVibration += amplitude * 0.1;
if (simulatedVibration >= 512.0 + amplitude) {
directionUp = false;
}
}
else {
simulatedVibration -= amplitude * 0.1;
if (simulatedVibration <= 512.0 - amplitude) {
directionUp = true;
}
}
// Store simulated vibration sample
vibrationSamples[sampleIndex] = (int)simulatedVibration;
sampleIndex++;
// When 20 samples are collected, calculate RMS
if (sampleIndex >= NUM_SAMPLES) {
float sumSquares = 0;
for (int i = 0; i < NUM_SAMPLES; i++) {
float centered =
vibrationSamples[i] - 512.0;
sumSquares += centered * centered;
}
vibrationRMS =
sqrt(sumSquares / NUM_SAMPLES);
sampleIndex = 0;
}
}
// -----------------------
// TEMPERATURE + STATUS
// -----------------------
if (tempReady) {
tempReady = false;
int tempAdc = analogRead(A0);
temperature = (tempAdc / 1023.0) * 100.0;
SystemStatus status =
checkStatus(temperature, vibrationRMS);
showStatus(status);
Serial.print(temperature);
Serial.print(",");
Serial.print(vibrationRMS);
Serial.print(",");
if (status == NORMAL) {
Serial.println("N");
}
else if (status == WARNING) {
Serial.println("W");
}
else {
Serial.println("F");
}
}
}
// CPU is free here to do something else