// Proyecto final PSER - Iron Man - Grupo C
// Salvador Ortega Munoz y Esther Salazar Saura
#include <WiFi.h> // Librería para WiFi. Para enviar con MQTT
#include <PubSubClient.h>
#include <ArduinoJson.hpp>
#include <ArduinoJson.h>
#include <LiquidCrystal_I2C.h>
#include "DHTesp.h"
#include "Ultrasonic.h"
#define MQTT_PORT 1883
#define MQTT_BROKER "broker.mqttdashboard.com"
#define TOPIC_DATA "topicPSER/IRONMAN_GRUPOC_DATA"
#define TOPIC_ALERT "topicPSER/IRONMAN_GRUPOC_ALERT"
#define WIFI_SSID "Wokwi-GUEST"
#define WIFI_PASSWORD ""
char clientId[50];
#define led1 13
#define led2 12
#define buzzer 25
#define button 19
#define DHT_PIN 15
// Para los estados de las alertas -> 0: normal, 1: temperatura, 2: humedad, 3: misil
int estado = 0;
// Inicializacion del sonar
Ultrasonic sonar(26, 27);
// Pantalla LCD
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 20, 4); // La comunicacion serial del LCD es 0x27. Cada dispositivo tiene una dirección diferente segun el fabricante.
// Sensor DHT22
DHTesp dhtSensor;
// Conexion WiFi
WiFiClient espClient;
PubSubClient client(espClient);
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
randomSeed(analogRead(0));
delay(10);
Serial.println();
Serial.print("[*] Connecting to ");
Serial.println(WIFI_SSID);
wifiConnect();
Serial.println("");
Serial.println("[+] WiFi connected");
Serial.println("[+] IP address: ");
Serial.println(WiFi.localIP());
Serial.println(WiFi.macAddress());
String stMac = WiFi.macAddress();
stMac.replace(":", "_");
Serial.println(stMac);
client.setServer(MQTT_BROKER, MQTT_PORT);
client.setCallback(callback);
lcd.init();
lcd.backlight();
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(buzzer, OUTPUT);
pinMode(button, INPUT_PULLUP);
dhtSensor.setup(DHT_PIN, DHTesp::DHT22);
}
void wifiConnect() {
Serial.print("[*] Conectando al WiFi...");
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("[+] Conectado a HiveMQ");
}
void mqttReconnect() {
while (!client.connected()) {
Serial.print("[*] Intentando conectar a MQTT...");
long r = random(1000);
sprintf(clientId, "clientId-%ld", r);
if (client.connect(clientId)) {
Serial.print(clientId);
Serial.println("[+] Conectado a MQTT");
client.subscribe(TOPIC_ALERT);
} else {
Serial.print("[!] Fallo, rc=");
Serial.print(client.state());
Serial.println("[!] Reconectando en 5 segundos");
delay(5000);
}
}
}
void eventTemperatureHumidity() {
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
estado = 0;
}
void eventMissile() {
estado = 0;
}
// Esta funcion habra que tocarla cuando hagamos las alertas porque ahora mismo esta con el on/off para que actúen los leds, falta el buzzer
void callback(char* topic, byte* message, unsigned int length) {
Serial.print("Message arrived on topic: ");
Serial.print(topic);
Serial.print(". Message: ");
String stMessage;
for (int i = 0; i < length; i++) {
Serial.print((char)message[i]);
stMessage += (char)message[i];
}
Serial.println();
// Led
if (String(topic) == TOPIC_ALERT) {
if (stMessage == "alert_temperature") {
estado = 1;
while (estado == 1) {
Serial.println("Alert: ");
Serial.println("[!] alert_temperature");
digitalWrite(led1, HIGH);
digitalWrite(led2, HIGH);
lcd.clear();
lcd.setCursor(1, 1);
lcd.print("SOBRECALENTAMIENTO");
delay(750);
// Si se pulsa el botón se termina la alerta
attachInterrupt(digitalPinToInterrupt(button), eventTemperatureHumidity, FALLING);
}
}
else if (stMessage == "alert_humidity") {
estado = 2;
while (estado == 2) {
Serial.println("Alert: ");
Serial.println("[!] alert_humidity");
digitalWrite(led1, HIGH);
digitalWrite(led2, HIGH);
lcd.clear();
lcd.setCursor(4, 1);
lcd.print("HUMEDAD ALTA");
delay(750);
// Si se pulsa el botón se termina la alerta
attachInterrupt(digitalPinToInterrupt(button), eventTemperatureHumidity, FALLING);
}
}
else if (stMessage == "alert_missile") {
estado = 3;
while (estado == 3) {
Serial.println("Alert: ");
Serial.println("[!] alert_missile");
tone(buzzer, 698, 100);
lcd.clear();
lcd.setCursor(4, 1);
lcd.print("ALERTA MISIL");
delay(200);
// Si se pulsa el botón se termina la alerta
attachInterrupt(digitalPinToInterrupt(button), eventMissile, FALLING);
}
}
}
}
String serializeJSON(float temp, float hum, float dist) {
String json;
StaticJsonDocument<300> doc;
doc["temperature"] = String(temp, 2);
doc["humidity"] = hum;
doc["distance"] = dist;
serializeJson(doc, json);
return json;
}
void deserializeJSON(String json) {
StaticJsonDocument<300> doc;
DeserializationError error = deserializeJson(doc, json);
if (error) { return; }
String temp = doc["temperature"];
float hum = doc["humidity"];
float dist = doc["distance"];
Serial.println(temp);
Serial.println(hum);
Serial.println(dist);
}
void loop() {
if (!client.connected()) {
mqttReconnect();
}
client.loop();
// Sensores (DHT22 y HC-SR04)
digitalWrite(button, HIGH);
TempAndHumidity data = dhtSensor.getTempAndHumidity();
// Se imprime por CONSOLA
Serial.println("---");
Serial.println("Temperatura: " + String(data.temperature, 2) + "°C");
Serial.println("Humedad: " + String(data.humidity) + "%");
Serial.println("Distancia: " + String(sonar.read(CM)) + "cm");
Serial.println("---");
// Se imprime en la PANTALLA LCD
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("[+] DATOS ");
lcd.setCursor(0, 1);
lcd.print("Temp: ");
lcd.print(String(data.temperature, 2));
lcd.print(" C");
lcd.setCursor(0, 2);
lcd.print("Humedad: ");
lcd.print(String(data.humidity));
lcd.print(" %");
lcd.setCursor(0, 3);
lcd.print("Misil a: ");
lcd.print(sonar.read(CM));
lcd.print(" cm");
// Se codifica el JSON
Serial.println("JSON serializado: ");
String json = serializeJSON(data.temperature, data.humidity, sonar.read(CM));
Serial.println(json);
Serial.println();
Serial.println("JSON deserializado: ");
deserializeJSON(json);
Serial.println();
// Se publica el JSON en el topic
client.publish(TOPIC_DATA, json.c_str());
delay(5000);
}