Antes de nada, dar las gracias a tod@s aquell@s que dediquen un rato a ayudarme.
El tema es que hace tiempo comencé a montarme un termostato con arduino partiendo de cero, y en unos meses lo conseguí, hay que decir que de programación ando mal, y de electrónica algo mejor, finalmente me conseguí fabricar mi PCB, subir todo el código a un NODEMCU y gestionar la caldera desde el teléfono móvil, todo un logro para mí.
Pero claro, me emocioné y aprovechando que nos hemos comprado un piso, pues con un par de huev….cableé toda la casa y ahora quiero gestionar la calefacción de forma zonificada. Creía que me iba a costar mucho menos el tema del programa, pero a cada paso que doy, más perdido voy.
Comento, pretendo controlar 3 relés con 2 sensores DHT22, uno por cada zona.
• Problema 1. No consigo averiguar cómo hacer para que cuando un radiador demande calor, estén como estén el resto de relés de los radiadores, el relé de la Caldera siga ON.
• Problema 2. Cuando hago un GET 192.168.30/tempDeseadaDespacho40 consigo que el NODEMCU lo vea, me activa el relé del radiador del Despacho, me activa el relé de la Caldera, pero cuando hago un GET 192.168.1.30/tempDeseadaDespacho00, consigo que el relé del radiador se desactive, pero no el de la Caldera. • Tampoco consigo que los GET se vean reflejados de forma correcta en el navegador web.
#include <FS.h> #include <ESP8266WiFi.h> #include "ThingSpeak.h" #include <DHT.h> #include <WiFiManager.h> #include <ArduinoJson.h> #include <ESP8266mDNS.h> #include <DNSServer.h> #include <ESP8266WebServer.h> #include <WiFiClient.h> #include <WiFiServer.h> #define DHTTYPE DHT11 #define DHTTYPE DHT22 #include <DoubleResetDetector.h> #include <LiquidCrystal_I2C.h> #include <Wire.h> #define DRD_TIMEOUT 10 #define DRD_ADDRESS 0 #define DHTPINDespacho 10 //_____________________________________________PONER PATILLA #define DHTPINSalon 4//_________________________________________________PONER PATILLA const int releCaldera = 2; //Pin al que está conectado el rele de salida (PINOUT) const int releDespacho = 12; //Pin al que está conectado el rele de salida del radiador del Despacho (PINOUT) const int releSalon = 15; //Pin al que está conectado el rele de salida del radiador del Salon (PINOUT) float histeresis = 1; static unsigned long last_loop; unsigned long int anteriorRefreshDatosDespacho = 0; unsigned long int anteriorRefreshDatosSalon = 0; float tempDespacho= 0; float tempSalon= 0; float tempDeseadaDespacho = 00; float tempDeseadaSalon = 00; int calderaHabilitada; int estadoRele = 0; int contconexion = 0; bool shouldSaveConfig = false; bool initialConfig = false; DoubleResetDetector drd(DRD_TIMEOUT, DRD_ADDRESS); //Función de doble reset para configurar NODEMCU LiquidCrystal_I2C lcd(0x27, 16, 2); DHT dhtDespacho(DHTPINDespacho, DHT22); DHT dhtSalon(DHTPINSalon, DHT22); WiFiClient client; WiFiServer server(80); //Parámetros de Thingspeak const char* serverThingspeak = "api.thingspeak.com"; char myWriteAPIKey[17] = "0WU6GVSSUPYI8EED"; char myChannelNumber[11] = "888615"; void saveConfigCallback () { Serial.println("Should save config"); shouldSaveConfig = true; } void setup() { dhtDespacho.begin(); dhtSalon.begin(); delay(10); Serial.begin(115200); Serial.println(); //Aqui decimos que el rele de la caldera este desconectado pinMode(releCaldera, OUTPUT); digitalWrite(releCaldera, LOW); pinMode(releDespacho, OUTPUT); pinMode(releSalon, OUTPUT); pinMode(DHTPINDespacho, INPUT); pinMode(DHTPINSalon, INPUT); Serial.println(); if (WiFi.SSID()==""){ Serial.println("We haven't got any access point credentials, so get them now"); initialConfig = true; } if (drd.detectDoubleReset()) { Serial.println("Doble reset detectado"); initialConfig = true; } if (initialConfig) { Serial.println("Starting configuration portal."); lcd.clear(); lcd.setCursor(0,0); lcd.print("INTRODUCIR"); lcd.setCursor(0,1); lcd.print("USUARIO Y PASS"); WiFiManager wifiManager; wifiManager.resetSettings(); } //Leer configuración de Json Serial.println("mounting FS..."); if (SPIFFS.begin()) { Serial.println("mounted file system"); if (SPIFFS.exists("/config.json")) { //file exists, reading and loading Serial.println("reading config file"); File configFile = SPIFFS.open("/config.json", "r"); if (configFile) { Serial.println("opened config file"); size_t size = configFile.size(); // Allocate a buffer to store contents of the file. std::unique_ptr<char[]> buf(new char[size]); configFile.readBytes(buf.get(), size); DynamicJsonBuffer jsonBuffer; JsonObject& json = jsonBuffer.parseObject(buf.get()); json.printTo(Serial); if (json.success()) { Serial.println("\nparsed json"); strcpy(myWriteAPIKey, json["myWriteAPIKey"]); } else { Serial.println("failed to load json config"); } } } } WiFiManagerParameter custom_myWriteAPIKey("API-Key", "myWriteAPIKey", myWriteAPIKey, 17); WiFiManager wifiManager; //Establecer configuración guardada wifiManager.setSaveConfigCallback(saveConfigCallback); IPAddress _ip = IPAddress(192, 168, 1, 30); IPAddress _gw = IPAddress(192, 168, 1, 1); IPAddress _sn = IPAddress(255, 255, 255, 0); wifiManager.setSTAStaticIPConfig(_ip, _gw, _sn); wifiManager.addParameter(&custom_myWriteAPIKey); if (!wifiManager.autoConnect()) { Serial.println("failed to connect and hit timeout"); delay(10); ESP.reset(); delay(10); } //Si has llegado aquí estás conectado a una WIFI Serial.println("Conectado a una Wifi"); lcd.clear(); lcd.setCursor(0,0); lcd.print("CONECTANDO..."); delay(20); //Leer parámetros actualizados strcpy(myWriteAPIKey, custom_myWriteAPIKey.getValue()); //Guardar los parámetros en FS if (shouldSaveConfig) { Serial.println("saving config"); DynamicJsonBuffer jsonBuffer; JsonObject& json = jsonBuffer.createObject(); json["myWriteAPIKey"] = myWriteAPIKey; File configFile = SPIFFS.open("/config.json", "w"); if (!configFile) { Serial.println("failed to open config file for writing"); } json.printTo(Serial); json.printTo(configFile); configFile.close(); //Guardado finalizado } Serial.println(); Serial.println("local ip"); Serial.println(WiFi.localIP()); delay(10);} void refreshDatosDespacho(){ if (millis() > anteriorRefreshDatosDespacho + 20000){ anteriorRefreshDatosDespacho = millis(); float tempDespacho = dhtDespacho.readTemperature(); float humiDespacho = dhtDespacho.readHumidity(); if (isnan(tempDespacho) || isnan(humiDespacho)){ Serial.println("Fallo en lectura de temperatura y humedad del Despacho"); return;} if (calderaHabilitada = 1){ if (tempDespacho + histeresis >= tempDeseadaDespacho && tempDespacho > 0) digitalWrite(releDespacho, LOW); else if (tempDespacho < tempDeseadaDespacho && tempDespacho > 0){ digitalWrite(releDespacho, HIGH); digitalWrite(releCaldera, HIGH);} else digitalWrite(releDespacho, LOW); } Serial.println(); Serial.println("Leyendo datos...."); Serial.print("Temperatura deseada: "); Serial.println(tempDeseadaDespacho); Serial.print("Temperatura Despacho: "); Serial.println(tempDespacho); Serial.print("Humedad Despacho: "); Serial.println(humiDespacho); lcd.clear(); lcd.setCursor(0,0); lcd.print("Temp Despacho: "); lcd.print(tempDespacho); lcd.print(" "); lcd.print((char)223); lcd.print("C"); lcd.setCursor(0,1); lcd.print("Hum Despacho: "); lcd.print(humiDespacho); lcd.print(" %"); int estadoRele = digitalRead(releCaldera); if (estadoRele == LOW){ Serial.print("Estado relé caldera: "); Serial.println("LOW"); lcd.setCursor(15,0); lcd.print(" "); } else { Serial.print("Estado relé caldera: "); Serial.println("HIGH"); lcd.setCursor(15,0); lcd.print("C"); } // Start the server ThingSpeak.begin(client); Serial.println("Cliente thingspeak iniciado"); server.begin(); Serial.println("Server iniciado"); Serial.println(myWriteAPIKey); Serial.println("local ip"); Serial.println(WiFi.localIP()); delay(10); ThingSpeak.setField(1, tempDespacho); //ThingSpeak.setField(2, humiPasillo); ThingSpeak.setField(6, estadoRele); //ThingSpeak.setField(4, tempDeseadaDespacho); ThingSpeak.writeFields(String(myChannelNumber).toInt(), myWriteAPIKey); delay(100); Serial.println("Enviando datos..."); Serial.println(); } } void refreshDatosSalon(){ if (millis() > anteriorRefreshDatosSalon + 20000){ anteriorRefreshDatosSalon = millis(); float tempSalon = dhtSalon.readTemperature(); float humiSalon = dhtSalon.readHumidity(); if (isnan(tempSalon) || isnan(humiSalon)){ Serial.println("Fallo en lectura de temperatura y humedad del Salon"); return;} if (calderaHabilitada = 1){ if (tempSalon + histeresis >= tempDeseadaSalon && tempSalon > 0) digitalWrite(releSalon, LOW); else if (tempSalon < tempDeseadaSalon && tempSalon > 0){ digitalWrite(releSalon, HIGH); digitalWrite(releCaldera, HIGH);} else digitalWrite(releSalon, LOW); } Serial.println(); Serial.println("Leyendo datos...."); Serial.print("Temperatura deseada: "); Serial.println(tempDeseadaSalon); Serial.print("Temperatura Salon: "); Serial.println(tempSalon); Serial.print("Humedad Salon: "); Serial.println(humiSalon); lcd.clear(); lcd.setCursor(0,0); lcd.print("Temp Salon: "); lcd.print(tempSalon); lcd.print(" "); lcd.print((char)223); lcd.print("C"); lcd.setCursor(0,1); lcd.print("Hum Salon: "); lcd.print(humiSalon); lcd.print(" %"); int estadoRele = digitalRead(releCaldera); if (estadoRele == LOW){ Serial.print("Estado relé caldera: "); Serial.println("LOW"); lcd.setCursor(15,0); lcd.print(" "); } else { Serial.print("Estado relé caldera: "); Serial.println("HIGH"); lcd.setCursor(15,0); lcd.print("C"); } // Start the server ThingSpeak.begin(client); Serial.println("Cliente thingspeak iniciado"); server.begin(); Serial.println("Server iniciado"); Serial.println(myWriteAPIKey); Serial.println("local ip"); Serial.println(WiFi.localIP()); delay(10); ThingSpeak.setField(3, tempSalon); //ThingSpeak.setField(2, humiSalon); //ThingSpeak.setField(3, estadoRele); //ThingSpeak.setField(4, tempDeseadaSalon); ThingSpeak.writeFields(String(myChannelNumber).toInt(), myWriteAPIKey); delay(100); Serial.println("Enviando datos..."); Serial.println(); } } void loop() { drd.loop(); refreshDatosDespacho(); refreshDatosSalon(); WiFiClient client = server.available(); if (!client) { return; } // Read the first line of the request String req = client.readStringUntil('\r'); Serial.println(req); client.flush(); int val; int valDespacho; if (req.indexOf("/tempDeseadaDespacho40") != -1){ tempDeseadaDespacho = 40; valDespacho = 1; } else if (req.indexOf("/tempDeseadaDespacho40") != -1){ tempDeseadaDespacho = 22; valDespacho = 1; } else if (req.indexOf("/tempDeseadaDespacho23") != -1){ tempDeseadaDespacho = 23; valDespacho = 1; } else if (req.indexOf("/tempDeseadaDespacho24") != -1){ tempDeseadaDespacho = 24; valDespacho = 1; } else if (req.indexOf("/tempDeseadaDespacho25") != -1){ tempDeseadaDespacho = 25; valDespacho = 1; } else if (req.indexOf("/tempDeseadaDespacho26") != -1){ tempDeseadaDespacho = 26; valDespacho = 1; } else if (req.indexOf("/tempDeseadaDespacho00") != -1){ tempDeseadaDespacho = 00; valDespacho = 0; } else { Serial.println("peticion invalida"); client.stop(); return; } int valSalon; if (req.indexOf("/tempDeseadaSalon40") != -1){ tempDeseadaSalon = 40; valSalon = 1; } else if (req.indexOf("/tempDeseadaSalon22") != -1){ tempDeseadaSalon = 22; valSalon = 1; } else if (req.indexOf("/tempDeseadaSalon23") != -1){ tempDeseadaSalon = 23; valSalon = 1; } else if (req.indexOf("/tempDeseadaSalon24") != -1){ tempDeseadaSalon = 24; valSalon = 1; } else if (req.indexOf("/tempDeseadaSalon25") != -1){ tempDeseadaSalon = 25; valSalon = 1; } else if (req.indexOf("/tempDeseadaSalon26") != -1){ tempDeseadaSalon = 26; valSalon = 1; } else if (req.indexOf("/tempDeseadaSalon00") != -1){ tempDeseadaSalon = 00; valSalon = 0; } else { Serial.println("peticion invalida"); client.stop(); return; } calderaHabilitada = val; client.flush(); // Prepara la respuesta web String sDespacho = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO is now "; sDespacho += (valDespacho)?"high":"low"; sDespacho += "</html>\n"; String sSalon = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO is now "; sSalon += (valSalon)?"high":"low"; sSalon += "</html>\n"; // Send the response to the client client.print(sDespacho); client.print(sSalon); delay(1); client.stop(); Serial.println("Client disonnected"); }