#include <Wire.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <math.h>
// =====================================================
// PIN CONFIGURATION
// =====================================================
// I2C
#define SDA_PIN 21
#define SCL_PIN 22
// DS18B20
#define TEMP_PIN 4
// Status LEDs
#define GREEN_LED 25
#define YELLOW_LED 26
#define RED_LED 27
// Buzzer
#define BUZZER_PIN 14
// =====================================================
// OLED CONFIGURATION
// =====================================================
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_ADDRESS 0x3C
Adafruit_SSD1306 display(
SCREEN_WIDTH,
SCREEN_HEIGHT,
&Wire,
-1
);
// =====================================================
// MPU6050
// =====================================================
Adafruit_MPU6050 mpu;
// =====================================================
// DS18B20
// =====================================================
OneWire oneWire(TEMP_PIN);
DallasTemperature temperatureSensor(&oneWire);
// =====================================================
// MACHINE STATUS
// =====================================================
enum MachineStatus
{
NORMAL,
WARNING,
CRITICAL
};
MachineStatus machineStatus = NORMAL;
// =====================================================
// SENSOR VARIABLES
// =====================================================
float temperature = 0.0;
float accelX = 0.0;
float accelY = 0.0;
float accelZ = 0.0;
float accelerationMagnitude = 0.0;
float vibrationIndex = 0.0;
// =====================================================
// HEALTH VARIABLES
// =====================================================
float temperatureScore = 100.0;
float vibrationScore = 100.0;
float healthScore = 100.0;
// =====================================================
// SETUP
// =====================================================
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.println("========================================");
Serial.println(" IoT INDUSTRIAL MACHINE HEALTH SYSTEM");
Serial.println("========================================");
// -------------------------------------------------
// GPIO configuration
// -------------------------------------------------
pinMode(GREEN_LED, OUTPUT);
pinMode(YELLOW_LED, OUTPUT);
pinMode(RED_LED, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
// Initially turn everything OFF
digitalWrite(GREEN_LED, LOW);
digitalWrite(YELLOW_LED, LOW);
digitalWrite(RED_LED, LOW);
noTone(BUZZER_PIN);
// -------------------------------------------------
// I2C initialization
// -------------------------------------------------
Wire.begin(SDA_PIN, SCL_PIN);
Serial.println("I2C initialized");
// -------------------------------------------------
// OLED initialization
// -------------------------------------------------
if (!display.begin(
SSD1306_SWITCHCAPVCC,
OLED_ADDRESS))
{
Serial.println("ERROR: OLED not found!");
while (1)
{
delay(1000);
}
}
Serial.println("OLED initialized");
// -------------------------------------------------
// MPU6050 initialization
// -------------------------------------------------
if (!mpu.begin(0x68))
{
Serial.println("ERROR: MPU6050 not found!");
while (1)
{
delay(1000);
}
}
Serial.println("MPU6050 initialized");
// -------------------------------------------------
// MPU6050 configuration
// -------------------------------------------------
mpu.setAccelerometerRange(
MPU6050_RANGE_8_G
);
mpu.setGyroRange(
MPU6050_RANGE_500_DEG
);
mpu.setFilterBandwidth(
MPU6050_BAND_21_HZ
);
// -------------------------------------------------
// DS18B20 initialization
// -------------------------------------------------
temperatureSensor.begin();
Serial.println("DS18B20 initialized");
// -------------------------------------------------
// Starting message
// -------------------------------------------------
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.setTextSize(1);
display.setCursor(10, 5);
display.println("INDUSTRIAL MACHINE");
display.setCursor(25, 20);
display.println("HEALTH MONITOR");
display.setCursor(35, 40);
display.println("SYSTEM READY");
display.display();
delay(2000);
}
// =====================================================
// READ TEMPERATURE
// =====================================================
void readTemperature()
{
temperatureSensor.requestTemperatures();
temperature =
temperatureSensor.getTempCByIndex(0);
// Check for invalid sensor reading
if (temperature == DEVICE_DISCONNECTED_C)
{
Serial.println("WARNING: DS18B20 disconnected!");
temperature = 0;
}
}
// =====================================================
// READ MPU6050
// =====================================================
void readVibration()
{
sensors_event_t acceleration;
sensors_event_t gyro;
sensors_event_t sensorTemperature;
mpu.getEvent(
&acceleration,
&gyro,
&sensorTemperature
);
// Get acceleration
accelX = acceleration.acceleration.x;
accelY = acceleration.acceleration.y;
accelZ = acceleration.acceleration.z;
// -------------------------------------------------
// Calculate total acceleration magnitude
//
// A = sqrt(X² + Y² + Z²)
// -------------------------------------------------
accelerationMagnitude =
sqrt(
(accelX * accelX) +
(accelY * accelY) +
(accelZ * accelZ)
);
// Convert to g
float accelerationG =
accelerationMagnitude / 9.80665;
// -------------------------------------------------
// Remove approximately 1g gravity component
// -------------------------------------------------
vibrationIndex =
fabs(accelerationG - 1.0);
}
// =====================================================
// CALCULATE HEALTH SCORE
// =====================================================
void calculateHealth()
{
// ===================================================
// TEMPERATURE SCORE
// ===================================================
if (temperature < 45)
{
temperatureScore = 100;
}
else if (temperature < 60)
{
temperatureScore = 75;
}
else if (temperature < 75)
{
temperatureScore = 45;
}
else
{
temperatureScore = 20;
}
// ===================================================
// VIBRATION SCORE
// ===================================================
if (vibrationIndex < 0.10)
{
vibrationScore = 100;
}
else if (vibrationIndex < 0.25)
{
vibrationScore = 75;
}
else if (vibrationIndex < 0.50)
{
vibrationScore = 45;
}
else
{
vibrationScore = 20;
}
// ===================================================
// COMBINED HEALTH SCORE
// ===================================================
healthScore =
(temperatureScore * 0.50) +
(vibrationScore * 0.50);
// Keep score between 0 and 100
if (healthScore > 100)
healthScore = 100;
if (healthScore < 0)
healthScore = 0;
}
// =====================================================
// DETERMINE MACHINE STATUS
// =====================================================
void determineMachineStatus()
{
// -------------------------------------------------
// CRITICAL CONDITION
// -------------------------------------------------
if (
temperature >= 75 ||
vibrationIndex >= 0.50
)
{
machineStatus = CRITICAL;
}
// -------------------------------------------------
// WARNING CONDITION
// -------------------------------------------------
else if (
temperature >= 60 ||
vibrationIndex >= 0.25
)
{
machineStatus = WARNING;
}
// -------------------------------------------------
// NORMAL CONDITION
// -------------------------------------------------
else
{
machineStatus = NORMAL;
}
}
// =====================================================
// CONTROL LEDS + BUZZER
// =====================================================
void updateAlerts()
{
// Turn OFF all LEDs
digitalWrite(GREEN_LED, LOW);
digitalWrite(YELLOW_LED, LOW);
digitalWrite(RED_LED, LOW);
// Turn OFF buzzer
noTone(BUZZER_PIN);
// ===================================================
// NORMAL
// ===================================================
if (machineStatus == NORMAL)
{
digitalWrite(
GREEN_LED,
HIGH
);
}
// ===================================================
// WARNING
// ===================================================
else if (machineStatus == WARNING)
{
digitalWrite(
YELLOW_LED,
HIGH
);
}
// ===================================================
// CRITICAL
// ===================================================
else if (machineStatus == CRITICAL)
{
digitalWrite(
RED_LED,
HIGH
);
// 1 kHz alarm
tone(
BUZZER_PIN,
1000
);
}
}
// =====================================================
// DISPLAY STATUS
// =====================================================
void updateOLED()
{
display.clearDisplay();
display.setTextColor(
SSD1306_WHITE
);
// -------------------------------------------------
// TITLE
// -------------------------------------------------
display.setTextSize(1);
display.setCursor(0, 0);
display.println(
"INDUSTRIAL MONITOR"
);
// Divider
display.drawLine(
0,
10,
127,
10,
SSD1306_WHITE
);
// -------------------------------------------------
// TEMPERATURE
// -------------------------------------------------
display.setCursor(0, 15);
display.print("TEMP: ");
display.print(
temperature,
1
);
display.println(" C");
// -------------------------------------------------
// VIBRATION
// -------------------------------------------------
display.setCursor(0, 27);
display.print("VIB: ");
display.print(
vibrationIndex,
2
);
display.println(" g");
// -------------------------------------------------
// HEALTH
// -------------------------------------------------
display.setCursor(0, 39);
display.print("HEALTH: ");
display.print(
healthScore,
0
);
display.println("%");
// -------------------------------------------------
// STATUS
// -------------------------------------------------
display.setCursor(0, 51);
display.print("STATUS: ");
if (machineStatus == NORMAL)
{
display.print("NORMAL");
}
else if (machineStatus == WARNING)
{
display.print("WARNING");
}
else
{
display.print("CRITICAL");
}
display.display();
}
// =====================================================
// SERIAL MONITOR
// =====================================================
void printSerialData()
{
Serial.println();
Serial.println("----------------------------------------");
Serial.print("Temperature : ");
Serial.print(temperature);
Serial.println(" °C");
Serial.print("Acceleration X : ");
Serial.print(accelX);
Serial.println(" m/s²");
Serial.print("Acceleration Y : ");
Serial.print(accelY);
Serial.println(" m/s²");
Serial.print("Acceleration Z : ");
Serial.print(accelZ);
Serial.println(" m/s²");
Serial.print("Vibration Index : ");
Serial.print(vibrationIndex);
Serial.println(" g");
Serial.print("Temperature Score: ");
Serial.print(temperatureScore);
Serial.println("%");
Serial.print("Vibration Score : ");
Serial.print(vibrationScore);
Serial.println("%");
Serial.print("Machine Health : ");
Serial.print(healthScore);
Serial.println("%");
Serial.print("Machine Status : ");
if (machineStatus == NORMAL)
{
Serial.println("NORMAL");
}
else if (machineStatus == WARNING)
{
Serial.println("WARNING");
}
else
{
Serial.println("CRITICAL");
}
Serial.println("----------------------------------------");
}
// =====================================================
// MAIN LOOP
// =====================================================
void loop()
{
// 1. Read temperature
readTemperature();
// 2. Read vibration
readVibration();
// 3. Calculate health
calculateHealth();
// 4. Determine machine condition
determineMachineStatus();
// 5. Update LEDs and buzzer
updateAlerts();
// 6. Update OLED
updateOLED();
// 7. Print data to Serial Monitor
printSerialData();
// Update every 1 second
delay(1000);
}