lunes, 18 de septiembre de 2017

Proyecto #2 ESP8266 – Control Remoto Universal - Versión 1

En este proyecto de IOT (internet de las cosas), explico cómo en realizar un control remoto infrarrojo (IR) universal utilizando un ESP8266. Primero se capturan los datos enviados por diversos controles remotos, utilizando un receptor de 38Khz (VS1838B), para luego ser transmitidos mediante un LED infrarrojo. El dispositivo es controlado desde un servidor web que está alojado dentro del ESP8266, lo que posibilita acceder desde cualquier dispositivo (PC, Smartphone, Tablet, etc.) que estén conectados en la red LAN.






Lista de Materiales:

1) NodeMCU (ESP8266)
1) VS1838B
1) LED Infrarrojo
1) Transistor BC337
1) Resistencia de 100
1) Resistencia de 1K

lecturaCRemoto:

uint16_t datos[50];

void setup() {
  Serial.begin(115200);
  Serial.println("");
  Serial.println("");
  pinMode(5, INPUT);  // D1
}

void loop() {
  if (digitalRead(5) == 0) {
    for (int i=0; i <= 48; i = i + 2){
      uint16_t old = micros();
      while (digitalRead(5) == 0 and datos[i] < 32000) { //lee los valores bajos (caundo llega señal) - 32000 indica que desbordó
         datos[i] = micros() - old;
      }
      old = micros();
      while (digitalRead(5) == 1 and datos[i+1] < 32000) { //lee los valores altos (caundo NO llega señal) - 32000 indica que desbordó
        datos[i+1] = micros() - old;
      }
    }
    Serial.println("");
    
    int j = 0;
    while (datos[j] < 20000) { // buscar el último bit, es decir que desbordó o el control remoto envió un bit de parada (21000uSec aprox.)
      j = j + 1;
    }
    
    Serial.print("int datosEnviar[" + String(j) + "] = {"); //imprimo el array hasta el último valor
    for (int i=0; i < j; i++){
      Serial.print(datos[i]);
      if (i != j-1) {
        Serial.print(","); //coloca la coma en todos los valores menos el último
      }
    }
    Serial.println("};");
    
    for (int i=0; i <= 50; i++){ // limpio el array
      datos[i] = 0;
    }
    delay(500);
  }
}


controlRemoto:

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

const char* ssid = "____";
const char* password = "____";
int contconexion = 0;

int datos[50];
boolean bandera = true;

ESP8266WebServer server(80);

//----------------------------------------------------------------------------------
String principal = "<!DOCTYPE html>"
"<html>"
"<head>"
"<title>Control Remoto</title>"
"<meta charset='UTF-8'>"
"<style type='text/css'>"
"*{margin: 5px; padding: 5px;}"
"span {float: left; width: 150px;}"
".boton {width: 800px; height:250px; font-family: sans-serif; font-size: 50px;}"
"</style>"
"</head>"
"<body>"
"<a href='tv'><button class='boton'>TV</button></a><br><br>"
"<a href='pc'><button class='boton'>PC</button></a><br>"
"</body>"
"</html>";

String tv = "<!DOCTYPE html>"
"<html>"
"<head>"
"<title>Control Remoto - TV</title>"
"<meta charset='UTF-8'>"
"<style type='text/css'>"
"*{margin: 5px; padding: 5px;}"
"span {float: left; width: 150px;}"
".boton {width: 250px; height:250px; font-family: sans-serif; font-size: 50px;}"
"</style>"
"</head>"
"<body>"
"<table>"
"<tr>"
"<td><a href='power'><button class='boton'>POWER</button></td>"
"<td></td>"
"<td><a href='mute'><button class='boton'>MUTE</button></td>"
"</tr>"
"<tr>"
"<td></td>"
"<td><a href='masCh'><button class='boton'>+CH</button></td>"
"<td></td>"
"</tr>"
"<tr>"
"<td><a href='menosVol'><button class='boton'>-VOL</button></td>"
"<td><a href='/'><button class='boton'>HOME</td>"
"<td><a href='masVol'><button class='boton'>+VOL</button></td>"
"</tr>"
"<tr>"
"<td></td>"
"<td><a href='menosCh'><button class='boton'>-CH</button></td>"
"<td></td>"
"</tr>"
"</table>"
"</body>"
"</html>";

String pc = "<!DOCTYPE html>"
"<html>"
"<head>"
"<title>Control Remoto - TV</title>"
"<meta charset='UTF-8'>"
"<style type='text/css'>"
"*{margin: 5px; padding: 5px;}"
"span {float: left; width: 150px;}"
".boton {width: 250px; height:250px; font-family: sans-serif; font-size: 50px;}"
"</style>"
"</head>"
"<body>"
"<table>"
"<tr>"
"<td><a href='clicL'><button class='boton'>L</button></td>"
"<td></td>"
"<td><a href='clicR'><button class='boton'>R</button></td>"
"</tr>"
"<tr>"
"<td></td>"
"<td><a href='subir'><button class='boton'>^</button></td>"
"<td></td>"
"</tr>"
"<tr>"
"<td><a href='izq'><button class='boton'><</button></td>"
"<td><a href='/'><button class='boton'>HOME</td>"
"<td><a href='der'><button class='boton'>></button></td>"
"</tr>"
"<tr>"
"<td></td>"
"<td><a href='bajar'><button class='boton'>v</button></td>"
"<td></td>"
"</tr>"
"</table>"
"</body>"
"</html>";

//----------------------------------------------------------------------------------
void paginaPrincipal() {
  server.send(200, "text/html", principal); 
}
void paginaPc() {
  server.send(200, "text/html", pc); 
}
void paginaTv() {
  server.send(200, "text/html", tv); 
}

//----------------------------------------------------------------------------------
void teclaPower() {
  Serial.println("Power");
  int datosEnviar[23] = {844,961,1701,921,855,920,853,920,854,919,857,961,812,961,812,947,828,1807,855,947,1716,946,828};
  int datosEnviar2[23] = {844,948,827,947,1714,949,827,947,827,947,828,948,828,945,828,946,827,1836,826,949,1716,946,827};
  if (bandera) {
    for (int i=0; i <= sizeof(datosEnviar)/sizeof(datosEnviar[0]); i++){ // sizeof(datosEnviar)/sizeof(datosEnviar[0] es la cantidad de elementos en el array
      datos[i] = datosEnviar[i];
    }
    bandera = false;
  }
  else {
    for (int i=0; i <= sizeof(datosEnviar2)/sizeof(datosEnviar2[0]); i++){ 
      datos[i] = datosEnviar2[i];
    }
    bandera = true;
  }
  enviar();
  server.send(200, "text/html", tv); 
}
void teclaMute() {
  Serial.println("Mute");
  int datosEnviar[23] = {882,951,1712,951,823,925,849,951,824,951,823,951,821,926,850,925,850,1814,849,951,1710,1813,850};
  int datosEnviar2[23] = {840,925,850,926,1737,952,821,926,850,923,850,927,848,924,850,926,849,1814,849,924,1740,1812,848};
  if (bandera) {
    for (int i=0; i <= sizeof(datosEnviar)/sizeof(datosEnviar[0]); i++){ 
      datos[i] = datosEnviar[i];
    }
    bandera = false;
  }
  else {
    for (int i=0; i <= sizeof(datosEnviar2)/sizeof(datosEnviar2[0]); i++){ 
      datos[i] = datosEnviar2[i];
    }
    bandera = true;
  }
  enviar();
  server.send(200, "text/html", tv); 
}
void teclaMasCh() {
  Serial.println("MasCh");
  int datosEnviar[23] = {847,961,1701,947,826,962,814,962,811,949,828,961,812,1849,1701,961,813,919,855,960,814,960,813};
  int datosEnviar2[23] = {848,963,813,947,1716,947,828,947,827,961,811,950,827,1850,1700,947,828,962,812,960,813,963,812};
  if (bandera) {
    for (int i=0; i <= sizeof(datosEnviar)/sizeof(datosEnviar[0]); i++){ 
      datos[i] = datosEnviar[i];
    }
    bandera = false;
  }
  else {
    for (int i=0; i <= sizeof(datosEnviar2)/sizeof(datosEnviar2[0]); i++){ 
      datos[i] = datosEnviar2[i];
    }
    bandera = true;
  }
  enviar();
  server.send(200, "text/html", tv); 
}
void teclaMenosCh() {
  Serial.println("MenosCh"); 
  int datosEnviar[23] = {844,947,1740,923,825,949,827,947,827,948,825,948,827,1836,1740,922,827,947,827,948,825,1835,828};
  int datosEnviar2[23] = {845,947,828,947,1739,925,827,947,827,947,827,949,825,1837,1739,922,828,947,826,946,828,1835,827};
  if (bandera) {
    for (int i=0; i <= sizeof(datosEnviar)/sizeof(datosEnviar[0]); i++){ 
      datos[i] = datosEnviar[i];
    }
    bandera = false;
  }
  else {
    for (int i=0; i <= sizeof(datosEnviar2)/sizeof(datosEnviar2[0]); i++){ 
      datos[i] = datosEnviar2[i];
    }
    bandera = true;
  }
  enviar();
  server.send(200, "text/html", tv); 
}
void teclaMasVol() {
  Serial.println("MasVol");
  int datosEnviar[23] = {869,923,1741,921,851,923,852,923,826,948,845,931,841,931,851,1812,1741,922,851,922,829,945,853};
  int datosEnviar2[23] = {882,921,830,944,1742,923,851,921,827,949,827,947,852,923,851,1809,1740,923,832,943,851,923,827};
  if (bandera) {
    for (int i=0; i <= sizeof(datosEnviar)/sizeof(datosEnviar[0]); i++){ 
      datos[i] = datosEnviar[i];
    }
    bandera = false;
  }
  else {
    for (int i=0; i <= sizeof(datosEnviar2)/sizeof(datosEnviar2[0]); i++){ 
      datos[i] = datosEnviar2[i];
    }
    bandera = true;
  }
  enviar();
  server.send(200, "text/html", tv); 
}
void teclaMenosVol() {
  Serial.println("MenosVol");
  int datosEnviar[23] = {846,947,1742,922,850,924,827,947,827,949,833,941,851,922,827,1836,1741,922,828,947,850,1811,828};
  int datosEnviar2[23] = {858,931,850,924,1740,923,828,947,850,923,852,924,826,948,851,1811,1740,922,852,922,828,1835,827};
  if (bandera) {
    for (int i=0; i <= sizeof(datosEnviar)/sizeof(datosEnviar[0]); i++){ 
      datos[i] = datosEnviar[i];
    }
    bandera = false;
  }
  else {
    for (int i=0; i <= sizeof(datosEnviar2)/sizeof(datosEnviar2[0]); i++){ 
      datos[i] = datosEnviar2[i];
    }
    bandera = true;
  }
  enviar();
  server.send(200, "text/html", tv); 
}

//----------------------------------------------------------------------------------
void teclaClicL() {
  Serial.println("ClicL");
  int datosEnviar[33] = {238,1875,262,1851,263,1851,232,822,261,793,262,794,261,1849,264,793,259,1849,264,794,260,793,263,1849,262,791,262,794,259,793,263,789,234};
  for (int i=0; i <= sizeof(datosEnviar)/sizeof(datosEnviar[0]); i++){ 
    datos[i] = datosEnviar[i];
  }
  enviar();
  server.send(200, "text/html", pc); 
}
void teclaClicR() {
  Serial.println("ClicR");
  int datosEnviar[33] = {216,1886,226,1888,224,1889,222,831,222,860,194,832,223,1916,195,830,222,835,221,860,194,1888,222,832,222,861,193,834,219,833,224,859,195};
  for (int i=0; i <= sizeof(datosEnviar)/sizeof(datosEnviar[0]); i++){ 
    datos[i] = datosEnviar[i];
  }
  enviar();
  server.send(200, "text/html", pc); 
}
void teclaSubir() {
  Serial.println("Subir");
  int datosEnviar[33] = {223,1880,231,1881,231,1880,232,824,230,824,230,851,206,1879,231,836,218,1881,230,824,232,825,230,824,231,823,231,851,203,824,231,824,230};
  for (int i=0; i <= sizeof(datosEnviar)/sizeof(datosEnviar[0]); i++){ 
    datos[i] = datosEnviar[i];
  }
  enviar();
  server.send(200, "text/html", pc); 
}
void teclaBajar() {
  Serial.println("Bajar");
  int datosEnviar[33] = {219,1880,232,1880,231,1881,231,824,231,824,231,826,229,1882,229,825,230,824,230,1882,230,825,230,822,232,825,230,824,230,825,231,823,230};
  for (int i=0; i <= sizeof(datosEnviar)/sizeof(datosEnviar[0]); i++){ 
    datos[i] = datosEnviar[i];
  }
  enviar();
  server.send(200, "text/html", pc); 
}
void teclaIzq() {
  Serial.println("Izq");
  int datosEnviar[33] = {217,1882,230,1880,232,1882,230,852,203,850,204,827,229,1862,250,836,218,1881,232,849,205,1865,247,1881,230,851,204,851,204,850,205,850,202};
  for (int i=0; i <= sizeof(datosEnviar)/sizeof(datosEnviar[0]); i++){ 
    datos[i] = datosEnviar[i];
  }
  enviar();
  server.send(200, "text/html", pc); 
}
void teclaDer() {
  Serial.println("Der");
  int datosEnviar[33] = {243,1858,253,1856,230,1882,230,826,255,799,231,826,230,1881,230,826,230,835,220,833,223,1891,219,1891,222,832,221,834,223,830,223,832,219};
  for (int i=0; i <= sizeof(datosEnviar)/sizeof(datosEnviar[0]); i++){ 
    datos[i] = datosEnviar[i];
  }
  enviar();
  server.send(200, "text/html", pc); 
}

//----------------------------------------------------------------------------------
void enviar() {
  for (int i=0; i <= 48; i = i + 2){
    int old = micros();
    while (micros() - old < datos[i]){ //envia los valores altos modulados a 38khz
      digitalWrite(4, 1);
      delayMicroseconds(9); // 1/38000 = 26 uSec... 26/2 = 13 uSec - 4uSec(para otros procesos)= 9 uSec
      digitalWrite(4, 0);
      delayMicroseconds(9);
    };
    old = micros();
    while (micros() - old < datos[i+1]){ //envío los valores bajos
      digitalWrite(4, 0);
      delayMicroseconds(9);
      digitalWrite(4, 0);
      delayMicroseconds(9);
    };
  }
  
  for (int i=0; i <= 50; i++){ //limpio el array
    datos[i] = 0;
  };
}

//----------------------------------------------------------------------------------
void setup() {
  Serial.begin(115200);
  Serial.println("");
  Serial.println("");
  pinMode(5, INPUT);  // D1 Receptor
  pinMode(4, OUTPUT); // D2 Emisor
  
  digitalWrite(4, 0);
  
  WiFi.mode(WIFI_STA); //para que no inicie solamente en modo estación
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED and contconexion <50) { //Cuenta hasta 50 si no se puede conectar lo cancela
    ++contconexion;
    Serial.print(".");
    delay(500);
  }
  if (contconexion <50) {
      //para usar con ip fija
      IPAddress Ip(192,168,1,180); 
      IPAddress Gateway(192,168,1,1); 
      IPAddress Subnet(255,255,255,0); 
      WiFi.config(Ip, Gateway, Subnet); 
      
      Serial.println("");
      Serial.println("WiFi conectado");
      Serial.println(WiFi.localIP());
          
      Serial.println("WebServer iniciado...");

      server.on("/", paginaPrincipal);
      server.on("/pc", paginaPc);
      server.on("/tv", paginaTv); 

      server.on("/power", teclaPower);
      server.on("/mute", teclaMute); 
      server.on("/masCh", teclaMasCh); 
      server.on("/menosCh", teclaMenosCh); 
      server.on("/masVol", teclaMasVol); 
      server.on("/menosVol", teclaMenosVol); 

      server.on("/clicL", teclaClicL);
      server.on("/clicR", teclaClicR); 
      server.on("/subir", teclaSubir); 
      server.on("/bajar", teclaBajar); 
      server.on("/izq", teclaIzq); 
      server.on("/der", teclaDer);    
      
      server.begin(); //incia el webserver
      
  }
  else { 
      Serial.println("");
      Serial.println("Error de conexion");
  }
}

//----------------------------------------------------------------------------------
void loop() {
  server.handleClient();   
}

https://www.eevblog.com
https://www.youtube.com/user/EEVblog
https://github.com/markszabo/IRremoteESP8266