// --- Include Necessary Libraries ---
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include "BluetoothSerial.h" // Bluetooth library for local communication
// --- Bluetooth Configuration ---
BluetoothSerial SerialBT; // Create a Bluetooth Serial object
// --- Hardware Pin Definitions ---
#define BUZZER_PIN 15
#define DHT_PIN 27
#define RELAY_PIN 26
#define DHT_TYPE DHT22
// --- Alarm Configuration ---
const float ALARM_TEMPERATURE = 30.0;
// --- Hardware Object Initialization ---
LiquidCrystal_I2C lcd(0x27, 20, 4);
DHT dht(DHT_PIN, DHT_TYPE);
Adafruit_MPU6050 mpu;
// --- State Management Variables ---
bool blinkState = false;
unsigned long lastBlinkTime = 0;
bool alarmState = false; // To track if the alarm is currently active
// =================================================================
// SETUP FUNCTION
// =================================================================
void setup() {
Serial.begin(115200);
// --- Initialize Bluetooth ---
SerialBT.begin("ESP32_System_Monitor"); // Set the Bluetooth device name
Serial.println("Bluetooth device is ready to pair.");
SerialBT.println("Welcome to the ESP32 System Monitor!");
SerialBT.println("------------------------------------");
lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Full System Monitor");
lcd.setCursor(0, 1);
lcd.print("Bluetooth Mode");
delay(2000);
dht.begin();
if (!mpu.begin()) {
Serial.println("Failed to find MPU6050 chip");
lcd.clear();
lcd.setCursor(0, 2);
lcd.print("MPU6050 Error!");
while (1) {
delay(10);
}
}
Serial.println("MPU6050 Found!");
mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
mpu.setGyroRange(MPU6050_RANGE_500_DEG);
mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW);
lcd.clear();
}
// =================================================================
// LOOP FUNCTION
// =================================================================
void loop() {
float humidity = dht.readHumidity();
float currentTemp = dht.readTemperature();
if (isnan(humidity) || isnan(currentTemp)) {
Serial.println("Failed to read from DHT sensor!");
lcd.setCursor(0, 3);
lcd.print("STATUS: DHT ERROR ");
return;
}
sensors_event_t a, g, temp;
mpu.getEvent(&a, &g, &temp);
// --- Send Data to Bluetooth Serial ---
String btData = "Temp: " + String(currentTemp, 1) + "C, ";
btData += "Humi: " + String(humidity, 1) + "%, ";
btData += "Accel X: " + String(a.acceleration.x, 1) + ", ";
btData += "Y: " + String(a.acceleration.y, 1) + ", ";
btData += "Z: " + String(a.acceleration.z, 1);
SerialBT.println(btData);
// --- Update LCD Display ---
lcd.setCursor(0, 0);
lcd.print("Temp: ");
lcd.print(currentTemp, 1);
lcd.print((char)223);
lcd.print("C ");
lcd.setCursor(0, 1);
lcd.print("Humi: ");
lcd.print(humidity, 1);
lcd.print("% ");
lcd.setCursor(0, 2);
lcd.print("X:");
lcd.print(a.acceleration.x, 1);
lcd.print(" Y:");
lcd.print(a.acceleration.y, 1);
lcd.print(" m/s2 ");
// --- Main Alarm Logic ---
if (currentTemp > ALARM_TEMPERATURE) {
digitalWrite(RELAY_PIN, HIGH);
tone(BUZZER_PIN, 1500, 500);
if (!alarmState) { // Send alarm message only once when the state changes
SerialBT.println("!!! ALARM: HIGH TEMPERATURE !!!");
alarmState = true;
}
if (millis() - lastBlinkTime > 500) {
lastBlinkTime = millis();
blinkState = !blinkState;
lcd.setCursor(0, 3);
if (blinkState) {
lcd.print("ALARM! HIGH TEMP! ");
} else {
lcd.print(" ");
}
}
} else {
digitalWrite(RELAY_PIN, LOW);
noTone(BUZZER_PIN);
if (alarmState) { // Send "back to normal" message only once
SerialBT.println("STATUS: Temperature is back to normal.");
alarmState = false;
}
lcd.setCursor(0, 3);
lcd.print("Z:");
lcd.print(a.acceleration.z, 1);
lcd.print(" Status:NORMAL ");
}
delay(1000);
}