#include "DHTesp.h"
#include <WiFi.h>
#include "PubSubClient.h"
#include <LiquidCrystal_I2C.h>
#include <HTTPClient.h>
#include "ThingSpeak.h"
//#include "MQ135.h"
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* mqttServer = "test.mosquitto.org";
const int port = 1883;
unsigned long channelNumber = 2374825;
const char* writeAPIkey = "URK76032EC1LDXG9";
const char* event_name = "myservice";
const char* apiKey = "kccIkomCDnX-ZI1HVZVOvSn1O010vF4C1SlBDB2E388";
const int motion = 2;
const int trig_pin = 23;
const int echo_pin = 5;
const int LED_PIN_1 = 4;
const int LED_PIN_2 = 15;
const int DHT22_PIN = 18;
const int BUZZER_PIN = 19;
const int mq135_simulator = 32;
int time1;
int time2;
int duration;
int on;
unsigned long lastMqttReconnectAttempt = 0;
const unsigned long mqttReconnectInterval = 10000;
String request_data = "true";
bool keep_sending_data = false;
bool allow_notification = true;
String state = "";
bool ledState = true;
bool warnState = true;
DHTesp dhtSensor;
WiFiClient espClient;
PubSubClient client(espClient);
LiquidCrystal_I2C LCD = LiquidCrystal_I2C(0x27, 20, 4);
// decorations while connecting to wifi.
void spinner()
{
static int8_t counter = 0;
const char* glyphs = "\xa1\xa5\xdb";
LCD.setCursor(15, 1);
LCD.print(glyphs[counter++]);
if (counter == strlen(glyphs)) {
counter = 0;
}
}
// connect to wifi.
void wifiConnect()
{
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
spinner();
Serial.print(".");
}
Serial.println(" Connected");
}
void LCD_init()
{
LCD.init();
LCD.backlight();
LCD.setCursor(0, 0);
LCD.print("Connecting to ");
LCD.setCursor(0, 1);
LCD.print("WiFi ");
}
// print local IP on LCD after connected.
void LCD_show_localIP()
{
LCD.clear();
LCD.setCursor(0, 0);
LCD.print("Online");
LCD.setCursor(0, 1);
LCD.print("Local IP: ");
LCD.print(WiFi.localIP());
LCD.setCursor(0, 2);
LCD.print("Getting data in ");
LCD.print("3");
delay(1000);
LCD.setCursor(16, 2);
LCD.print("2");
delay(1000);
LCD.setCursor(16, 2);
LCD.print("1");
delay(1000);
LCD.clear();
}
// Print data on LCD
void LCD_handle(int temperature, int humidity, int mq135_value,long distance)
{
// LCD.setCursor(0, 0);
// LCD.print("Current data: ");
LCD.setCursor(0, 0);
LCD.print("Temperature: ");
LCD.print(String(temperature) + "oC");
LCD.setCursor(0, 1);
LCD.print("Humidity: ");
LCD.print(String(humidity) + "%");
LCD.setCursor(0, 2);
LCD.print("MQ135: ");
LCD.print(String(mq135_value) + "PPM");
LCD.setCursor(0, 3);
LCD.print("Dis: ");
LCD.print(String(distance) + "CM");
}
void Turn_On_All_Led()
{
digitalWrite(LED_PIN_1, HIGH);
digitalWrite(LED_PIN_2, HIGH);
}
void Turn_Off_All_Led()
{
digitalWrite(LED_PIN_1, LOW);
digitalWrite(LED_PIN_2, LOW);
}
void Turn_On_Warning_Led()
{
digitalWrite(LED_PIN_1, LOW);
digitalWrite(LED_PIN_2, LOW);
}
float Read_ppm_data()
{
int value = analogRead(mq135_simulator);
int to_5V_value = map(value, 0, 4095, 0, 1023);
float to_ppm = to_5V_value * 1200 / 1023;
return to_ppm;
}
void Warning(float temp, float humidity, float ppm)
{
if (temp > 40 && temp <= 70 || ppm > 800 && ppm <= 1000) //cảnh báo cháy
{
if(warnState==true){
Turn_On_Warning_Led();
tone(BUZZER_PIN, 262, 250);
}
state = "Có Nguy cơ Cháy";
}
else if (temp > 70 || ppm > 1000 && ppm <= 1200) //phát sinh cháy
{
if(ledState==true){
Turn_On_All_Led();
tone(BUZZER_PIN, 523);
}
state = "Có Cháy!!!";
if(allow_notification)
{
sendIFTTTnotification(event_name, apiKey);
allow_notification = false;
}
}
else
{
allow_notification = true;
Turn_Off_All_Led();
noTone(BUZZER_PIN);
state = "Bình thường";
}
Serial.println("Temp: " + String(temp, 2) + "°C");
Serial.println("Humidity: " + String(humidity, 1) + "%");
Serial.println("PPM In Air: " + String(ppm, 2) + "ppm");
Serial.println("--------");
}
void mqttReconnect()
{
while (!client.connected())
{
Serial.println("Attempting MQTT reconnection...");
if (client.connect("21126058"))
{
Serial.println("Connected to your device!");
client.subscribe("21126058/Led");
client.subscribe("21126058/Warn");
}
else
{
Serial.println("Try again in 5 seconds...");
delay(5000);
}
}
}
void sendIFTTTnotification(const char* event_name, const char* apiKey)
{
HTTPClient http;
String url = "http://maker.ifttt.com/trigger/";
url += event_name;
url += "/with/key/";
url += apiKey;
Serial.println("Sending GET request to IFTTT URL: ");
Serial.println(url);
http.begin(url);
int httpResponseCode = http.GET();
if(httpResponseCode > 0)
Serial.printf("IFTTT request succeeded. Response code: %d", httpResponseCode);
else
Serial.printf("IFTTT request failed. Error code: %d", httpResponseCode);
http.end();
}
long getDistance(){
digitalWrite(trig_pin,LOW);
delayMicroseconds(2);
digitalWrite(trig_pin,HIGH);
delayMicroseconds(10);
digitalWrite(trig_pin,LOW);
long duration = pulseIn(echo_pin,HIGH);
long distanceCm = duration * 0.034/2;
return distanceCm;
}
void callback(char* topic, byte* payload, unsigned int length)
{
String request_data;
for (int i = 0; i < length; i++) {
request_data += (char)payload[i];
}
if (String(topic) == "21126058/Led") {
if(request_data == "on"){
ledState = true; // Đặt trạng thái LED thành HIGH
}
else if(request_data == "off"){
ledState = false; // Đặt trạng thái LED thành LOW
}
}else if(String(topic) == "21126058/Warn") {
if(request_data == "on"){
warnState = true; // Đặt trạng thái LED thành HIGH
}
else if(request_data == "off"){
warnState = false; // Đặt trạng thái LED thành LOW
}
}
// In ra chủ đề và thông điệp nhận được
Serial.print("Topic: ");
Serial.println(topic);
Serial.print("Message: ");
Serial.println(request_data);
}
void setup() {
Serial.begin(115200);
dhtSensor.setup(DHT22_PIN, DHTesp::DHT22);
pinMode(LED_PIN_1, OUTPUT);
pinMode(LED_PIN_2, OUTPUT);
pinMode(motion, INPUT);
pinMode(trig_pin,OUTPUT);
pinMode(echo_pin,INPUT);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(mq135_simulator, INPUT);
LCD_init();
WiFi.begin(ssid, password);
wifiConnect();
LCD_show_localIP();
ThingSpeak.begin(espClient);
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
client.setServer(mqttServer, port);
client.setCallback(callback);
}
void loop() {
if (!client.connected()) {
unsigned long currentMillis = millis();
if (currentMillis - lastMqttReconnectAttempt >= mqttReconnectInterval) {
lastMqttReconnectAttempt = currentMillis;
mqttReconnect();
}
}
client.loop();
client.subscribe("Request/data");
TempAndHumidity data = dhtSensor.getTempAndHumidity();
long distanceCm = getDistance();
float ppm = Read_ppm_data();
float temperature = data.temperature;
float humidity = data.humidity;
String none_state = " ";
LCD_handle(data.temperature, data.humidity, ppm,distanceCm);
Warning(data.temperature, data.humidity, ppm);
int m = digitalRead(motion);
if(m == HIGH){
m = 1;
}
else{
m = 0;
}
if(m == 1){
time1 = millis();
while(digitalRead(motion) == HIGH){
duration = millis() - time1;
if(duration > 3000){
delay(3000);
}
}
}
if(distanceCm < 50){
on = 1;
state = "Có người lạ đến gần";
if(ledState==true){
Turn_On_All_Led();
}
}
else{
if(on == 1){
time2 = millis();
while(on == 1){
if(millis() - time2 > 3000){
on = 0;
}
}
}
Turn_Off_All_Led();
}
//char buffer[50];
// sprintf(buffer, "{\"temperature\": %f, \"humidity\": %f, \"ppm\": %f}", temperature, humidity, ppm);
// client.publish("21127147_21127365_21127644/Data", buffer);
// sprintf(buffer, "%f", temperature);
// sprintf(buffer, "%f", humidity);
// sprintf(buffer, "%f", ppm);
if(request_data == "true")
keep_sending_data = true;
else if(request_data == "false")
{
client.publish("21126058/Temp", (String(0).c_str()));
client.publish("21126058/Humidity", (String(0).c_str()));
client.publish("21126058/PPM", (String(0).c_str()));
client.publish("21126058/Distance", (String(0).c_str()));
client.publish("21126058/state", (none_state.c_str()));
keep_sending_data = false;
}
if(keep_sending_data)
{
client.publish("21126058/Temp", (String(temperature, 2)).c_str());
client.publish("21126058/Humidity", (String(humidity, 2)).c_str());
client.publish("21126058/PPM", (String(ppm, 2)).c_str());
client.publish("21126058/Distance", (String(distanceCm, 2)).c_str());
client.publish("21126058/state", (state.c_str()));
ThingSpeak.setField(1, int(temperature));
ThingSpeak.setField(2, int(humidity));
ThingSpeak.setField(3, int(ppm));
int returncode = ThingSpeak.writeFields(channelNumber, writeAPIkey);
if(returncode == 200)
Serial.println("---Update successfully!---");
else
Serial.println("---Problem updating channel---");
}
delay(2000);
}