Công nghệ

ESP8266 NodeMCU Home Automation and Safety Monitor

null
Written by lbtmicr06

(((() you can copy the code from here)))

/*
ESP8266 NodeMCU Home Automation and Safety Monitor

Blynk datastreams:
V0 – PIR alarm enable switch
V1 – Gas percentage
V2 – Temperature
V3 – Humidity
V4 – Distance/water level
V5 – Relay 1 switch
V6 – Relay 2 switch

Blynk events:
gas_leak
fire_detected
security_alert
*/

#define BLYNK_TEMPLATE_ID “YOUR_TEMPLATE_ID”
#define BLYNK_TEMPLATE_NAME “Home Automation”
#define BLYNK_AUTH_TOKEN “YOUR_AUTH_TOKEN”

#define BLYNK_PRINT Serial

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>

// —————————————————————————–
// Network credentials
// —————————————————————————–

char ssid[] = “YOUR_WIFI_NAME”;
char pass[] = “YOUR_WIFI_PASSWORD”;

// —————————————————————————–
// Pin configuration
// —————————————————————————–

#define DHT_PIN D4
#define MQ2_PIN A0
#define FLAME_PIN D0
#define PIR_PIN D3
#define TRIG_PIN D5
#define ECHO_PIN D6
#define RELAY1_PIN D7
#define RELAY2_PIN D8

// GPIO3 is the NodeMCU RX pin.
// Do not connect the buzzer directly if it draws significant current.
// Use a transistor and flyback protection where applicable.
#define BUZZER_PIN 3

#define DHT_TYPE DHT11

// Change these values after calibrating the sensors.
const int GAS_ALARM_PERCENT = 35;
const long MAX_DISTANCE_CM = 400;

// Most two-channel relay boards are active-low.
const uint8_t RELAY_ON = LOW;
const uint8_t RELAY_OFF = HIGH;

// Change this if your buzzer module is active-low.
const uint8_t BUZZER_ON = HIGH;
const uint8_t BUZZER_OFF = LOW;

// —————————————————————————–
// Objects
// —————————————————————————–

LiquidCrystal_I2C lcd(0x27, 16, 2);
DHT dht(DHT_PIN, DHT_TYPE);
BlynkTimer timer;

// —————————————————————————–
// System state
// —————————————————————————–

bool pirEnabled = false;

bool gasAlarm = false;
bool fireAlarm = false;
bool motionAlarm = false;

bool previousGasAlarm = false;
bool previousFireAlarm = false;
bool previousMotionAlarm = false;

float temperatureC = NAN;
float humidityPercent = NAN;
int gasPercent = 0;
long distanceCm = -1;

// —————————————————————————–
// Blynk input handlers
// —————————————————————————–

BLYNK_WRITE(V0)
{
pirEnabled = param.asInt();

if (!pirEnabled) {
motionAlarm = false;
}

updateBuzzer();
}

BLYNK_WRITE(V5)
{
bool requestedState = param.asInt();
digitalWrite(RELAY1_PIN, requestedState ? RELAY_ON : RELAY_OFF);
}

BLYNK_WRITE(V6)
{
bool requestedState = param.asInt();
digitalWrite(RELAY2_PIN, requestedState ? RELAY_ON : RELAY_OFF);
}

BLYNK_CONNECTED()
{
// Restore application switch and relay states after reconnecting.
Blynk.syncVirtual(V0, V5, V6);
}

// —————————————————————————–
// Alarm control
// —————————————————————————–

void updateBuzzer()
{
bool anyAlarm = gasAlarm || fireAlarm || motionAlarm;
digitalWrite(BUZZER_PIN, anyAlarm ? BUZZER_ON : BUZZER_OFF);
}

void sendAlarmEvents()
{
// Send only when an alarm changes from inactive to active.
if (gasAlarm && !previousGasAlarm) {
Blynk.logEvent(“gas_leak”, “Warning: gas level exceeded the configured limit.”);
}

if (fireAlarm && !previousFireAlarm) {
Blynk.logEvent(“fire_detected”, “Warning: the flame sensor detected a possible fire.”);
}

if (motionAlarm && !previousMotionAlarm) {
Blynk.logEvent(
“security_alert”,
“Warning: motion was detected while security monitoring was enabled.”
);
}

previousGasAlarm = gasAlarm;
previousFireAlarm = fireAlarm;
previousMotionAlarm = motionAlarm;
}

// —————————————————————————–
// Sensor functions
// —————————————————————————–

void readGasSensor()
{
int rawValue = analogRead(MQ2_PIN);

// ESP8266 analogRead normally returns 0–1023.
gasPercent = map(rawValue, 0, 1023, 0, 100);
gasPercent = constrain(gasPercent, 0, 100);

gasAlarm = gasPercent >= GAS_ALARM_PERCENT;

Blynk.virtualWrite(V1, gasPercent);

Serial.print(“MQ-2 raw: “);
Serial.print(rawValue);
Serial.print(” calculated: “);
Serial.print(gasPercent);
Serial.println(“%”);

updateBuzzer();
sendAlarmEvents();
}

void readDhtSensor()
{
float newHumidity = dht.readHumidity();
float newTemperature = dht.readTemperature();

if (isnan(newHumidity) || isnan(newTemperature)) {
Serial.println(“DHT11 reading failed.”);
return;
}

humidityPercent = newHumidity;
temperatureC = newTemperature;

Blynk.virtualWrite(V2, temperatureC);
Blynk.virtualWrite(V3, humidityPercent);
}

void readFlameSensor()
{
// Common flame modules produce LOW when flame is detected.
fireAlarm = digitalRead(FLAME_PIN) == LOW;

updateBuzzer();
sendAlarmEvents();
}

void readPirSensor()
{
bool motionDetected = digitalRead(PIR_PIN) == HIGH;
motionAlarm = pirEnabled && motionDetected;

updateBuzzer();
sendAlarmEvents();
}

long measureDistanceCm()
{
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(3);

digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);

digitalWrite(TRIG_PIN, LOW);

// Approximately 30 ms supports distances beyond the useful HC-SR04 range.
unsigned long duration = pulseIn(ECHO_PIN, HIGH, 30000UL);

if (duration == 0) {
return -1;
}

long measuredDistance = duration / 58L;

if (measuredDistance < 2 || measuredDistance > MAX_DISTANCE_CM) {
return -1;
}

return measuredDistance;
}

void readUltrasonicSensor()
{
distanceCm = measureDistanceCm();

if (distanceCm >= 0) {
Blynk.virtualWrite(V4, distanceCm);
}
}

// —————————————————————————–
// LCD
// —————————————————————————–

void updateDisplay()
{
char line1[17];
char line2[17];

if (isnan(temperatureC) || isnan(humidityPercent)) {
snprintf(line1, sizeof(line1), “T:–.- H:–.-“);
} else {
snprintf(
line1,
sizeof(line1),
“T:%4.1f H:%4.1f”,
temperatureC,
humidityPercent
);
}

if (distanceCm < 0) {
snprintf(line2, sizeof(line2), “G:%3d D:—“, gasPercent);
} else {
snprintf(line2, sizeof(line2), “G:%3d D:%3ld”, gasPercent, distanceCm);
}

lcd.setCursor(0, 0);
lcd.print(line1);
lcd.print(” “);
lcd.setCursor(0, 0);
lcd.print(line1);

lcd.setCursor(0, 1);
lcd.print(line2);
lcd.print(” “);
lcd.setCursor(0, 1);
lcd.print(line2);
}

// —————————————————————————–
// Setup and loop
// —————————————————————————–

void setup()
{
Serial.begin(115200);

pinMode(BUZZER_PIN, OUTPUT);
pinMode(FLAME_PIN, INPUT);
pinMode(PIR_PIN, INPUT);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(RELAY1_PIN, OUTPUT);
pinMode(RELAY2_PIN, OUTPUT);

digitalWrite(BUZZER_PIN, BUZZER_OFF);
digitalWrite(TRIG_PIN, LOW);
digitalWrite(RELAY1_PIN, RELAY_OFF);
digitalWrite(RELAY2_PIN, RELAY_OFF);

Wire.begin(D2, D1);

lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(“System starting”);
lcd.setCursor(0, 1);
lcd.print(“Connecting…”);

dht.begin();

Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);

lcd.clear();
lcd.setCursor(0, 0);
lcd.print(“System online”);

// Fast digital safety sensors.
timer.setInterval(250L, readFlameSensor);
timer.setInterval(250L, readPirSensor);

// MQ-2 and ultrasonic readings.
timer.setInterval(1000L, readGasSensor);
timer.setInterval(1000L, readUltrasonicSensor);

// DHT11 should be read slowly.
timer.setInterval(2000L, readDhtSensor);

// LCD does not need to be rewritten every 100 ms.
timer.setInterval(1000L, updateDisplay);
}

void loop()
{
Blynk.run();
timer.run();
}

Ẩn bớt

About the author

lbtmicr06

Leave a Comment