Instrucciones
Las instrucciones enfocadas en cada sensor o actividad se resumen en funciones, tratando de mantener la simplicidad del lazo principal.
Las instrucciones incorporan las siguientes características:
- el boton config_IR, una vez presionado espera hasta recibir una señal infraroja que se lee, y graba.
- el Envío de la señal se realiza con la instrucción MQTT o desde Home Assistant
- Usa el LED_LeeIR como indicador de estado de lectura o activación de control remoto.
- Se emite la señal de control mediante la variable senal_ONOFF
- Se controla el estado de lectura del sensor/decodificador infrarojo mediante MQTT, y la respuesta se emite a la conexión serial.
- La temperatura y humedad se actualizan con el parametro «intervalo» cuyo primer número es minutos
/* ESP8266 IRremoteESP8266: Receptor Infrarojo * edelros@espol.edu.ec * Debe usar un sensor detector/demodulador conectado al Receptor_Pin. * Based on Mark Szabo's Version 0.2 June, 2017 and * Ken Shirriff's IrsendDemo Version 0.1 July, 2009 * https://github.com/markszabo/IRremoteESP8266 * Para usar, actualice las secciones de: * - WIFI:Router, MQTT:Servidor, MQTT:Dispositivo * ESP-01 al usar GPIO1 y GPIO3,(Tx,Rx), NO USE Serial.print() */ #include <ESP8266WiFi.h> #include <PubSubClient.h> #include <IRremoteESP8266.h> #include <IRrecv.h> #include <IRutils.h> #include <IRsend.h> #include <EEPROM.h> #include <DHT.h> // WIFI: conexión a Router char* ssid = "giotirni20"; char* password = "Anera2020@"; // MQTT: Servidor char* MQTT_IP = "192.168.10.50"; uint16_t MQTT_puerto = 1883; char* MQTT_usuario = "usuarioprueba"; char* MQTT_contrasena = "usuarioclave"; // MQTT: Dispositivo Interruptor char* MQTT_ID = "oficina_CtrlIR01"; char* MQTT_TOPIC = "oficina/CtrlIR01/estado"; char* MQTT_COMMAND = "oficina/CtrlIR01/cambia"; char* MQTT_TOPIC_T = "oficina/CtrlIR01/temperatura"; char* MQTT_TOPIC_H = "oficina/CtrlIR01/humedad"; char* MQTT_COMMAND_DHT = "oficina/CtrlIR01/actualiza"; char* MQTT_TOPIC_LeeIR = "oficina/CtrlIR01/leer"; char* MQTT_COMMAND_LeeIR = "oficina/CtrlIR01/grabar"; char MQTT_SensorEstado[10] = "OFF"; char MQTT_ActuadorEstado[10] = "OFF"; char MQTT_DHT_T[6] = "25"; // inicializa char MQTT_DHT_H[6] = "50"; // inicializa char MQTT_LeeIR[6] = "0"; // inicializa volatile boolean mqtt_desconectado = true; char* sensor_ON = "ON"; char* sensor_OFF = "OFF"; // Actuador Control Remoto Emisor LED-IR en GPIO14 const uint8_t emisorIR_pin = 14; uint32_t senal_ONOFF = 0xFF5AA5; // código de control volatile boolean actuador_estado = false; volatile boolean actuador_bandera = false; // Sensor IR en GPIO05 const uint8_t receptorIR_pin = 5; volatile boolean LeerIR_estado = false; volatile boolean LeerIR_bandera = false; // Boton de lectura y emitir IR const uint8_t config_pin = 12; const uint8_t emitir_pin = 0; // LED monitor //interno: ESP01-pin=1, ESP07-pin=2 const uint8_t LED_pin=13; const uint8_t LED_LeerIR = 2; // Mensajes por Puerto Serial volatile boolean serial_msg = true; // Control de tiempo transcurrido entre lecturas temperatura unsigned long ahora = millis(); const long intervalo = 5*60*1000;//minutos*60s*1000ms unsigned long antes = ahora-intervalo-1; //leer al inicio // Clientes WiFi y MQTT WiFiClient wifiClient; PubSubClient mqttclient(wifiClient); // Receptor y Emisor Infrarojos IRrecv irrecv(receptorIR_pin); decode_results lecturaIR; IRsend irsend(emisorIR_pin); // Sensor de Temperatura&Humedad #define DHTPIN 4 #define DHTTYPE DHT11 DHT dht(DHTPIN, DHTTYPE); void setup() { Serial.begin(74880);//74880, 115200 while (!Serial){delay(50);} // SENSOR IR // inicia receptor IR irrecv.enableIRIn(); pinMode(LED_LeerIR, OUTPUT); Leer_Activaestado(); // ACTUADOR IR // inicia emisor IR pinMode(emisorIR_pin, OUTPUT); irsend.begin(); // SENSOR Temperatura&Humedad dht.begin(); // LED monitor, Enciende en LOW pinMode(LED_pin, OUTPUT); // Memoria lectura y escritura EEPROM.begin(64); //eeprom maximo 512 posiciones codigo_leermem(); // Boton de lectura de código IR pinMode(config_pin, INPUT); attachInterrupt(digitalPinToInterrupt(config_pin),LeerActivado,CHANGE); // Boton de Emisor de código IR pinMode(emitir_pin, INPUT); attachInterrupt(digitalPinToInterrupt(emitir_pin),IR_Activado,CHANGE); // conexión WIFI y MQTT inicia_wifi(); if (WiFi.status() == WL_CONNECTED){ inicia_mqtt(); } } void loop() { // enviar señal IR if (actuador_bandera){ irsend.sendNEC(senal_ONOFF ,32); // parpadeo digitalWrite(LED_LeerIR, LOW); delay(300); digitalWrite(LED_LeerIR, HIGH); delay(200); digitalWrite(LED_LeerIR, LOW); delay(300); digitalWrite(LED_LeerIR, HIGH); delay(200); // deja en estado anterior el LED Leer_IR Leer_Activaestado(); publica_estado(); actuador_bandera = false; if (serial_msg==true){ Serial.print("\n Señal IR enviada: "); serialPrintUint64(senal_ONOFF, HEX); Serial.println(""); } } yield(); // procesa wifi // Sensor IR, leer código if(LeerIR_bandera){ if (irrecv.decode(&lecturaIR)) { // conversión a texto uint64_t numero = lecturaIR.value; unsigned long parte1 = (unsigned long)((numero & 0xFFFF0000) >> 16 ); unsigned long parte2 = (unsigned long)((numero & 0x0000FFFF)); String texto = String(parte1, HEX) + String(parte2, HEX); texto.toUpperCase(); senal_ONOFF = lecturaIR.value; // Escribe a memoria EEPROM // escribe a eeprom texto = texto+";"; //marca fin de texto int n = texto.length(); int posicion = 0; int i = posicion; while(i<n){ EEPROM.write(i,texto[i]); i=i+1; } EEPROM.commit(); irrecv.resume(); LeerIR_bandera = false; LeerIR_estado = false; publica_estado(); Leer_Activaestado(); if (serial_msg==true){ Serial.print("\n lecturaIR: "); // print() & println() no maneja enteros largos(uint64_t) serialPrintUint64(lecturaIR.value, HEX); Serial.println(""); Serial.print(" grabado en memoria: "); Serial.println(texto); } } } yield(); // procesa wifi // lectura Temperatura,Humedad unsigned long ahora = millis(); unsigned long transcurre = ahora-antes; if (transcurre>=intervalo){ antes = ahora; delay(50); // calibrar con una referencia más precisa // modo simple: resta factor de corrección=5 float temperatura = dht.readTemperature(); float humedad = dht.readHumidity(); // convierte a texto mqtt; a 4 dígitos, 2 decimales dtostrf(temperatura, 4, 2, MQTT_DHT_T); dtostrf(humedad, 4, 2, MQTT_DHT_H); publica_estado(); if (serial_msg==true){ Serial.print("\n tiempo: "); Serial.println(transcurre); Serial.print(" Temperatura,Humedad: "); Serial.print(MQTT_DHT_T); Serial.print(" , "); Serial.println(MQTT_DHT_H); Serial.println(); } } yield(); // procesa wifi if (WiFi.status() != WL_CONNECTED){ inicia_wifi(); }else{ if (mqttclient.connected()==false){ mqtt_desconectado = true; inicia_mqtt(); // reintento } if (mqttclient.connected()==true){ if (mqtt_desconectado==true){ publica_estado(); mqtt_desconectado=false; } mqttclient.loop(); } } yield(); // procesa wifi } void codigo_leermem(){ // lectura desde eeprom, codigo on/off int posicion = 0; int n = posicion+10; String codigotxt = ""; char simbolo; int i = posicion; while(i<n){ simbolo = char(EEPROM.read(i)); if (simbolo!=';'){ codigotxt = codigotxt+String(simbolo); }else{ i=n; // terminar lectura antes } i=i+1; } // conversión de codigotxt a HEX char codigochar[64]; codigotxt.toCharArray(codigochar, n); uint32_t codigoIRhex = strtoul(codigochar, 0, 16); // actualiza variable senal_ONOFF = codigoIRhex; if (serial_msg==true){ Serial.print("texto leido: "); Serial.println(codigotxt); Serial.print("codigo IR eprom: "); // print() & println() no maneja enteros largos(uint64_t) serialPrintUint64(senal_ONOFF, HEX); Serial.println("\n"); } } // ISR interrupción activada ICACHE_RAM_ATTR void LeerActivado(){ // evita repeticiones por rebotes del botonera if (LeerIR_bandera==false){ LeerIR_bandera = true; LeerIR_estado = true; Leer_Activaestado(); publica_estado(); if (serial_msg){ Serial.println(" Leer IR activado..."); } } } ICACHE_RAM_ATTR void IR_Activado(){ // evita repeticionese por rebotes del botonera if (actuador_bandera ==false){ actuador_bandera = true; if (actuador_estado == true) { actuador_estado = false; }else{ actuador_estado = true; } publica_estado(); if (serial_msg){ Serial.println(" IR_envío activado..."); } } } // Actuador activar estado void Leer_Activaestado(){ if (LeerIR_estado){ // ACTUADOR ACTIVA EN LOW // LED actuador ilumina en apagado digitalWrite(LED_LeerIR, LOW); }else{ digitalWrite(LED_LeerIR, HIGH); } } // Publicar el estado del dispositivo void publica_estado() { if (actuador_estado){ snprintf (MQTT_ActuadorEstado,10, sensor_ON); }else{ snprintf (MQTT_ActuadorEstado,10, sensor_OFF); } if (LeerIR_estado){ snprintf (MQTT_LeeIR,10, sensor_ON); }else{ snprintf (MQTT_LeeIR,10, sensor_OFF); } if (mqttclient.connected()==true){ mqttclient.publish(MQTT_TOPIC,MQTT_ActuadorEstado,true); mqttclient.publish(MQTT_TOPIC_LeeIR,MQTT_LeeIR,true); mqttclient.publish(MQTT_TOPIC_T,MQTT_DHT_T,true); mqttclient.publish(MQTT_TOPIC_H,MQTT_DHT_H,true); }else{ mqtt_desconectado = true; } } void inicia_wifi(){ int intentos = 10; int cuenta = 0; if (serial_msg){ Serial.print(" WIFI Conectando a "); Serial.println(ssid); } WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while ((WiFi.status() != WL_CONNECTED) && (cuenta<intentos)){ if (serial_msg){ Serial.print("."); } cuenta = cuenta+1; // Parpadeo de Monitor enciende en LOW digitalWrite(LED_pin, LOW); delay(300); digitalWrite(LED_pin, HIGH); delay(200); } if (serial_msg){ //Fin de "..." Serial.println(); if (WiFi.status() == WL_CONNECTED){ Serial.print(" Estado: "); Serial.println(WiFi.status()); Serial.print(" MAC: "); Serial.println(WiFi.macAddress()); Serial.print(" IP: "); Serial.println(WiFi.localIP()); Serial.print(" RSSI: "); Serial.println(WiFi.RSSI()); Serial.println(); } if (WiFi.status() != WL_CONNECTED){ WiFi.printDiag(Serial); Serial.println(); } } } void inicia_mqtt(){ int intentos = 2; int cuenta = 0; if (serial_msg){ Serial.print(" MQTT Conectando a "); Serial.println(MQTT_IP); } mqttclient.setServer(MQTT_IP, MQTT_puerto); mqttclient.connect(MQTT_ID, MQTT_usuario, MQTT_contrasena); mqttclient.setCallback(callback); while (!mqttclient.connected() && (cuenta<intentos)) { if (serial_msg){ Serial.print("."); } cuenta = cuenta + 1; // Parpadeo de Monitor enciende en LOW digitalWrite(LED_pin, LOW); delay(200); digitalWrite(LED_pin, HIGH); delay(200); } publica_estado(); mqttclient.subscribe(MQTT_COMMAND); mqttclient.subscribe(MQTT_COMMAND_LeeIR); mqttclient.subscribe(MQTT_COMMAND_DHT); if (serial_msg){ //Fin de "..." Serial.println(); Serial.print(" MQTT Conectado: "); Serial.println(mqttclient.connected()); Serial.print(" MQTT Estado: "); Serial.println(mqttclient.state()); } } // llega mensaje MQTT void callback(char* p_topic, byte* p_payload, unsigned int p_length) { // convierte a texto String payload; for (uint8_t i = 0; i < p_length; i++) { payload.concat((char)p_payload[i]); } // revisa mensaje por topico if (String(MQTT_COMMAND).equals(p_topic)) { if (payload.equals(String(sensor_ON))) { if (actuador_estado != true) { actuador_estado = true; } } if (payload.equals(String(sensor_OFF))) { if (actuador_estado != false) { actuador_estado = false; } } Leer_Activaestado(); publica_estado(); actuador_bandera = true; } if (String(MQTT_COMMAND_LeeIR).equals(p_topic)) { if (payload.equals(String(sensor_ON))) { if (LeerIR_estado != true) { LeerIR_estado = true; } } if (payload.equals(String(sensor_OFF))) { if (LeerIR_estado != false) { LeerIR_estado = false; } } LeerIR_bandera = true; Leer_Activaestado(); publica_estado(); } if (String(MQTT_COMMAND_DHT).equals(p_topic)) { antes = antes-(intervalo+2); } }