#include <PubSubClient.h>
#include <WiFi.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <ESPAsyncWebServer.h>
#include <AsyncTCP.h>
#include <time.h>
//*********************
//*** GLOBALES **
//*********************
#define led1 21
#define led2 22
#define ONE_WIRE_BUS 19
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
const char* ssid = "GalaxySteven";
const char* password = "123456789";
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
AsyncWebServer server(80);
AsyncWebSocket ws("/ws");
unsigned int intervalo = 1000; //1 segundo
unsigned long valorActual = 0;
// Prototipos
void InitOutput();
void initSerial();
void initDisplay();
void initWiFi();
void EnviaTempOLED();
void notifyClients();
void handleWebSocketMessage(void *arg, uint8_t *data, size_t len);
void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len);
String processor(const String& var);
// HTML para la página web
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
<title>ESP32 Temperature Monitor</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script>
var gateway = `ws://${window.location.hostname}/ws`;
var websocket;
window.addEventListener('load', onLoad);
function onLoad(event) {
initWebSocket();
}
function initWebSocket() {
websocket = new WebSocket(gateway);
websocket.onopen = onOpen;
websocket.onclose = onClose;
websocket.onmessage = onMessage;
}
function onOpen(event) {
console.log('Connection opened');
websocket.send('getTemps');
}
function onClose(event) {
console.log('Connection closed');
setTimeout(initWebSocket, 2000);
}
function onMessage(event) {
var temps = event.data.split(',');
document.getElementById('temp1').innerHTML = 'Temp1: ' + temps[0] + ' C';
document.getElementById('temp2').innerHTML = 'Temp2: ' + temps[1] + ' C';
}
</script>
</head>
<body>
<h1>ESP32 Temperature Monitor</h1>
<div id="temp1">Temp1: --.- C</div>
<div id="temp2">Temp2: --.- C</div>
</body>
</html>
)rawliteral";
void setup() {
initSerial();
InitOutput();
initDisplay();
initWiFi();
sensors.begin();
// WebSocket
ws.onEvent(onEvent);
server.addHandler(&ws);
// Servidor web
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html, processor);
});
server.begin();
}
void loop() {
EnviaTempOLED();
ws.cleanupClients();
}
void InitOutput() {
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
}
void initSerial() {
Serial.begin(115200);
delay(10);
}
void initDisplay() {
Wire.begin(23, 18); // SDA = 23, SCL = 18
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Dirección I2C 0x3C
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.display();
delay(2000); // Pausa para que la pantalla se inicialice
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
}
void initWiFi() {
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi ..");
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print('.');
}
Serial.println("Connected to WiFi");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
}
void EnviaTempOLED() {
if (millis() - valorActual >= intervalo) {
valorActual = millis();
sensors.requestTemperatures();
display.clearDisplay();
// Título
display.setTextSize(2);
display.setCursor(0, 0);
display.println("Temp & LED");
// Línea separadora
display.drawLine(0, 16, SCREEN_WIDTH, 16, SSD1306_WHITE);
// Temperaturas y estado de LEDs
display.setTextSize(1);
for (int i = 0; i < 2; i++) {
float celsius = sensors.getTempCByIndex(i);
Serial.println(celsius, 1); //1 decimal
char tempstring[6];
dtostrf(celsius, 5, 1, tempstring); // Ajusta el tamaño para la temperatura y el null terminator
if (i == 0) {
display.setCursor(0, 20);
display.print("Temp1: ");
display.print(tempstring);
display.print(" C");
if (celsius > 25.0) { // Ejemplo: enciende el LED1 si la temperatura es mayor a 25 grados
digitalWrite(led1, HIGH);
display.fillCircle(110, 25, 5, SSD1306_WHITE); // LED1 ON
} else {
digitalWrite(led1, LOW);
display.drawCircle(110, 25, 5, SSD1306_WHITE); // LED1 OFF
}
} else {
display.setCursor(0, 40);
display.print("Temp2: ");
display.print(tempstring);
display.print(" C");
if (celsius > 25.0) { // Ejemplo: enciende el LED2 si la temperatura es mayor a 25 grados
digitalWrite(led2, HIGH);
display.fillCircle(110, 45, 5, SSD1306_WHITE); // LED2 ON
} else {
digitalWrite(led2, LOW);
display.drawCircle(110, 45, 5, SSD1306_WHITE); // LED2 OFF
}
}
}
display.display();
notifyClients();
}
}
void notifyClients() {
String message = "";
for (int i = 0; i < 2; i++) {
float celsius = sensors.getTempCByIndex(i);
message += String(celsius, 1);
if (i < 1) {
message += ",";
}
}
ws.textAll(message);
}
void handleWebSocketMessage(void *arg, uint8_t *data, size_t len) {
AwsFrameInfo *info = (AwsFrameInfo*)arg;
if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) {
data[len] = 0;
if (strcmp((char*)data, "getTemps") == 0) {
notifyClients();
}
}
}
void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) {
if (type == WS_EVT_CONNECT) {
Serial.println("WebSocket client connected");
client->text("Hello from ESP32");
} else if (type == WS_EVT_DISCONNECT) {
Serial.println("WebSocket client disconnected");
} else if (type == WS_EVT_DATA) {
handleWebSocketMessage(arg, data, len);
}
}
String processor(const String& var) {
if (var == "TEMPERATURES") {
String message = "";
for (int i = 0; i < 2; i++) {
float celsius = sensors.getTempCByIndex(i);
message += "Temp" + String(i + 1) + ": " + String(celsius, 1) + " C<br>";
}
return message;
}
return String();
}