lunes, 26 de enero de 2015

Domos - Enviando el código IR

Ayer había conseguido encender y apagar un led en función del estado desdeado dirigido desde el servidor y lo había sincronizado con el dispositivo poniendolo en OFF al arrancar.

Por otro lado habíamos cocinado un sketch que nos leía los códigos IR del mando a distancia a manejar y ahora procede ponerlo todo junto, es decir, que cuando desde Internet el servidor quiera poner el dispositivo en ON, en vez de encender un led o un RELÉ, enviar una señal IR para encender y viceversa.

Para ello he utilizado la librería IRremote.h que permite enviar códigos IR (En este caso tipo NEC) de forma sencilla. OJO que el led infrarrojo siempre tiene que estar puesto en el pin 3.







/*  =============================================================================================
        CONFIGURACION PARTICULAR
    ============================================================================================= */
#define DEBUG_ON
#ifdef  DEBUG_ON
#define debug(x)  Serial.println(x)
#else
#define debug(x)
#endif
const long PERIODO_ACTUADOR =  5L * 1000L;  // Cada minuto pregunta por el estado del actuador.
const long PERIODO_TEMPERATURA =  10L * 60L * 1000L;    // Cada 10 minutos informa sobre la temperatura.
#define SW_TEMPERATURA          0  // Indica si queremos leer temperatura y enviarla al servidor
#define USAR_RELE   // Indica si queremos que el actuador funcione con un Relé
#define USAR_IR     // Indica si queremos usar códigos IR para
const int PIN_DISPOSITIVO = 8;
const int PIN_ERROR = 7;
const int ID_SENSOR_TEMPERATURA=1236;
const int ID_ACTUADOR=1235;
#define PIN_TERMOMETRO 2    // EL PIN DEL SENSOR DE TEMPERATURA

const long CODIGO_IR_OFF    = 0xFFE01F;      // El código para encender el aparato a controlar
const long CODIGO_IR_ON     = 0xFF609F;      // El código para apagar el aparato a controlar
#define PIN_IR       6
int estadoDispositivo = 0;
/* ============================================================================================= */

#ifdef USAR_IR
#include 
IRsend irsend;   // Parece ser que no se puede definir el PIN sino que es siempre el 5.
#endif

long milisActuador;
long milisTemperatura;


char server[]= "php-domos.rhcloud.com";
char query[]="GET /insert.php?sensor=%d&valor=%d HTTP/1.1";
char actuador[]="GET /actuador.php?id=%d HTTP/1.1";
char actuador_off[]="GET /set.php?actuador=%d&estado=OFF HTTP/1.1";
char host[]="Host: php-domos.rhcloud.com";


#define DHTTYPE DHT11

DHT dht(PIN_TERMOMETRO, DHTTYPE);

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,0,6);
EthernetClient clientTemperatura;
EthernetClient clientActuador;

void setup() {
  Serial.begin(9600);
  debug("Setup");
  pinMode(PIN_DISPOSITIVO, OUTPUT);
  pinMode(PIN_ERROR,OUTPUT);
  apagarDispositivo();
  
  
  if(SW_TEMPERATURA) {
    dht.begin();
  }
  
  debug("Inicializando Ethernet.");
  if(Ethernet.begin(mac)==0) {
    mostrarError("Error obteniendo la IP. La ponemos fija");
    Ethernet.begin(mac, ip);
  }
  debug(Ethernet.localIP());
  
  delay(1000);
  
  long time = millis();
  enviarTemperatura();
  milisTemperatura=time;
  ponerActuadorOff();
  estadoDispositivo=0;
  consultarActuador();
  milisActuador=time;
}

void mostrarError(char *Mensaje) {
  Serial.println(Mensaje);
  digitalWrite(PIN_ERROR, 1);
}

void limpiarError() {
  digitalWrite(PIN_ERROR, 0);
}

void enviarTemperatura() {
  if(!SW_TEMPERATURA) {
      return;
  }
    int t = (int)dht.readTemperature();
    if(!clientTemperatura.connect(server, 80)) {
      mostrarError("Error conectando a temperatura");
      return; 
    }  
    char aux[256];
    debug("Conectado para enviar temperatura");
    sprintf(aux, query, ID_SENSOR_TEMPERATURA, t);
    clientTemperatura.println(aux);
    clientTemperatura.println(host);
    clientTemperatura.println("Connection: close");
    clientTemperatura.println();
    clientTemperatura.stop();
}

void ponerActuadorOff() {
   debug("Poniendo el actuador en OFF");
   int ret=clientActuador.connect(server, 80);
    if(ret !=  1) {
      char aux[256];
      sprintf(aux, "Error %d connect", ret);
      mostrarError(aux);
      return;
    }
  
    char aux[256];
    debug("Conectado para leer actuador");
    sprintf(aux, actuador_off, ID_ACTUADOR);
    clientActuador.println(aux);
    clientActuador.println(host);
    clientActuador.println("Connection: close");
    clientActuador.println();
    delay(5000);
    clientActuador.stop(); // Me da lo mismo lo que responda...
}

void consultarActuador() {
    debug("Consultar actuador");
    int ret=clientActuador.connect(server, 80);
    if(ret !=  1) {
      char aux[256];
      sprintf(aux, "Error %d connect", ret);
      mostrarError(aux);
      return;
    }
  
    char aux[256];
    debug("Conectado para leer actuador");
    sprintf(aux, actuador, ID_ACTUADOR);
    clientActuador.println(aux);
    clientActuador.println(host);
    clientActuador.println("Connection: close");
    clientActuador.println();
    
    delay(100); // Esperamos un poco a ver si hay respuesta.
    if(clientActuador.connected()) {
      limpiarError();
      leerRespuesta();
      clientActuador.stop();
    } else {
      mostrarError("Error conectando");
    }
}

void apagarDispositivo() {
  #ifdef USAR_RELE
    digitalWrite(PIN_DISPOSITIVO, 0);
  #endif
  #ifdef USAR_IR
    if(estadoDispositivo==1) {
      debug("Enviando OFF");
      irsend.sendNEC(CODIGO_IR_ON, 32);
      estadoDispositivo=0;
    }
  #endif
}

void encenderDispositivo() {
  #ifdef USAR_RELE
    digitalWrite(PIN_DISPOSITIVO, 1);
  #endif
  #ifdef USAR_IR
    if(estadoDispositivo==0) {
      debug("Enviando ON");
      irsend.sendNEC(CODIGO_IR_OFF, 32);
      estadoDispositivo=1;
    }
  #endif
}

void leerLinea(EthernetClient &client, char aux[], int max) {
  int i=0; 
  while(client.available() && i < max) {
    char c=client.read();
    if(c=='\n') {
      break;
    } else {
      aux[i++]=c;
    }
  }
  aux[i]=0;
}

void leerRespuesta() {
    debug("Leyendo respuesta...");
    int intentos=0;
    // Esperando a datos disponibles, un maximo de 5 segundos
    for(intentos=0; intentos<500 && clientActuador.connected(); intentos++) {
      if(clientActuador.available()) {
        break;
      }
      delay(10);
    }
    // Leemos los datos disponibles...
    for(intentos=0; intentos<100 && clientActuador.connected(); intentos++) {
        if(clientActuador.available()) {
          char linea[256];
          leerLinea(clientActuador, linea,100);
          if(!strcmp(linea,"ON")) {
            debug("ON!!");
            encenderDispositivo();
            break;
          }
          if(!strcmp(linea,"OFF")) {
            debug("OFF!!");
            apagarDispositivo();
            break;
          }
        }  
        delay(10);
    }
}


void loop() {
  long time=millis();
  if(time > milisTemperatura + PERIODO_TEMPERATURA) {
    enviarTemperatura();
    milisTemperatura=time;
  }
  if(time > milisActuador + PERIODO_ACTUADOR) {
    consultarActuador();
    milisActuador=time;
  }
  delay(100);
}


No hay comentarios:

Publicar un comentario