#include <WiFi.h>
#include <WiFiClient.h>
#include <HTTPClient.h>
#include "ThingSpeak.h"
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
const char* WIFI_SSID = "Wokwi-GUEST";
const char* WIFI_PASS = "";
const char* BOT_TOKEN = "8482372067:AAFrGbpKLG_ERMPR1ooXBL0nBvvkvkBF-4M";
const char* CHAT_ID = "8258824435";
unsigned long myChannelNumber = 3038794;
const char* myApiKey = "JHLYLOV6NRF2RW0U";
#define Pin_Trig 25
#define Pin_Echo 26
#define Pin_Buzzer 4
WiFiClient client;
LiquidCrystal_I2C lcd(0x27, 16, 2);
const int LDR_DARK_TH = 2600;
const int LDR_BRIGHT_TH = 2000;
const unsigned long SENSOR_INTERVAL = 2000UL;
const unsigned long LCD_PAGE_INTERVAL = 4000UL;
const unsigned long THINGSPEAK_INTERVAL = 20000UL;
const unsigned long ALARM_SILENCE_TIME = 10UL * 60UL * 1000UL;
const unsigned long LED_AUTO_OFF_TIME = 5UL * 60UL * 1000UL;
const float TEMP_HIGH_TH = 30.0;
const int TEMP_HIGH_COUNT_REQUIRED = 3;
float tempC = NAN, hum = NAN;
int ldr = 0;
bool motion = false;
bool ledState = false;
bool buzzerState = false;
unsigned long tLastSensors = 0;
unsigned long tLastLCD = 0;
unsigned long tLastThingSpeak = 0;
unsigned long tNoMotionSince = 0;
unsigned long tSilencedUntil = 0;
int highTempCount = 0;
int lcdPage = 0;
void setLED(bool on) {
ledState = on;
digitalWrite(Pin_Led, on ? HIGH : LOW);
}
void setBuzzer(bool on) {
buzzerState = on;
digitalWrite(Pin_Buzzer, on ? HIGH : LOW);
}
void pushThingSpeak() {
if (WiFi.status() != WL_CONNECTED) return;
ThingSpeak.setField(1, tempC);
ThingSpeak.setField(2, hum);
ThingSpeak.setField(3, ldr);
ThingSpeak.setField(4, motion ? 1 : 0);
ThingSpeak.setField(5, ledState ? 1 : 0);
ThingSpeak.setField(6, WiFi.RSSI());
ThingSpeak.writeFields(myChannelNumber, myApiKey);
}
void readSensors() {
float t = dhtSensor.readTemperature();
float h = dhtSensor.readHumidity();
if (!isnan(t)) tempC = t;
if (!isnan(h)) hum = h;
ldr = analogRead(Sensor_LDR);
bool mv = digitalRead(Sensor_PIR);
if (mv) {
motion = true;
tNoMotionSince = millis();
} else {
motion = false;
if (tNoMotionSince == 0) tNoMotionSince = millis();
}
if (!isnan(tempC) && tempC > TEMP_HIGH_TH) highTempCount++;
else highTempCount = 0;
}
void updateLCD() {
lcd.clear();
if (lcdPage == 0) {
lcd.setCursor(0, 0);
lcd.print("T:"); lcd.print(isnan(tempC)?0:tempC,1); lcd.print("C H:"); lcd.print(isnan(hum)?0:hum,0);
lcd.setCursor(0, 1);
lcd.print("L:"); lcd.print(ldr); lcd.print(" M:"); lcd.print(motion?"1":"0");
} else {
lcd.setCursor(0, 0);
lcd.print("LED:"); lcd.print(ledState?"ON":"OFF");
lcd.setCursor(0, 1);
lcd.print("RSSI:"); lcd.print(WiFi.RSSI());
}
}
void handleButton() {
static bool lastState = HIGH;
bool st = digitalRead(Pin_Boton);
if (lastState == HIGH && st == LOW) {
tSilencedUntil = millis() + ALARM_SILENCE_TIME;
}
lastState = st;
}
void logicEngine() {
unsigned long now = millis();
bool bajaLuz = (ldr >= LDR_DARK_TH);
if (motion && bajaLuz) {
setLED(true);
if (now >= tSilencedUntil) {
setBuzzer(true);
sendTelegramMessage("Alerta: intruso detectado");
} else setBuzzer(false);
}
if (highTempCount >= TEMP_HIGH_COUNT_REQUIRED) {
Serial.println("Alerta: temperatura alta");
sendTelegramMessage("Alerta: temperatura alta");
highTempCount = 0;
}
bool luzSuficiente = (ldr <= LDR_BRIGHT_TH);
if (!motion && luzSuficiente && (now - tNoMotionSince >= LED_AUTO_OFF_TIME)) {
setLED(false);
setBuzzer(false);
}
if (!(motion && bajaLuz)) setBuzzer(false);
}
void sendTelegramMessage(String msg) {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
String url = "https://api.telegram.org/bot" + String(BOT_TOKEN) +
"/sendMessage?chat_id=" + String(CHAT_ID) +
"&text=" + msg;
http.begin(url);
int httpCode = http.GET();
if (httpCode > 0) {
Serial.println("Mensaje enviado a Telegram: " + msg);
} else {
Serial.println("Error enviando mensaje Telegram");
}
http.end();
}
}
void setup() {
Serial.begin(9600);
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) delay(500);
ThingSpeak.begin(client);
pinMode(Pin_Led, OUTPUT);
pinMode(Pin_Buzzer, OUTPUT);
pinMode(Sensor_PIR, INPUT);
pinMode(Pin_Boton, INPUT_PULLUP);
dhtSensor.begin();
lcd.init(); lcd.backlight();
tLastSensors = tLastLCD = tLastThingSpeak = millis();
tNoMotionSince = millis();
}
void loop() {
unsigned long now = millis();
if (now - tLastSensors >= SENSOR_INTERVAL) {
tLastSensors = now;
readSensors();
logicEngine();
}
if (now - tLastThingSpeak >= THINGSPEAK_INTERVAL) {
tLastThingSpeak = now;
pushThingSpeak();
}
if (now - tLastLCD >= LCD_PAGE_INTERVAL) {
tLastLCD = now;
lcdPage = 1 - lcdPage;
updateLCD();
}
handleButton();
}