lunes, 26 de enero de 2015

Arbol y Nieve



via Instagram http://ift.tt/1BgHu61

Oviedo y el Aramo



via Instagram http://ift.tt/1uTTD42

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);
}


domingo, 25 de enero de 2015

La térmica de Ribera a todo trapo - Asturias



via Instagram http://ift.tt/15xOd2m

Domos - Leyendo el mando a distancia

Recordemos mi objetivo inicial. Apagar y encender una estufa de Pellets a distancia. La maldita estufa está preparada para que, cuando recibe corriente, quedarse siempre en modo stand-by y olvidar la hora que es e incluso la programación. Por lo tanto, un Relé no sirve como sistema de encendido o apagado, así que pretendo "hackearla" utilizando su mando a distancia.

Véase la entrada anterior: http://luisetemiravalles.blogspot.com.es/2015/01/domos-apagando-y-encendiendo-cosas.html

Necesito conocer los códigos que envía su mando a distancia, para luego poder replicarlos desde mi proyecto Arduino.

Con un Arduino y un simple sensor de IR y el siguiente sketck han salido a relucir los códigos que envía el mando a distancia de la estufa:

/*
 * Detector de código infrarrojo con el estándar NEC
 */
#define PIN 7

NECIRrcv ir(PIN) ;
void setup() {
  Serial.begin(9600);
  Serial.println("Detector de IR");
  ir.begin();
}

void loop() {
   unsigned long codigo;
   while(ir.available()) {
     codigo=ir.read();
     Serial.print("Leido codigo 0x");
     Serial.println(codigo, HEX);   
   } 
}

Así que nuestros códigos IR son:

ON-OFF : 0xED12FE01
TURBO  : 0xEE11FE01
ECO    : 0xEF10FE01
PROG   : 0xE41BFE01
TEMP+  : 0xE51AFE01
TEMP-  : 0xEC13FE01
Ahora me encuentro con otro problema: El botón de ON es el mismo que el de OFF por lo que el circuito arduino debe conocer el estado para poder actuar correctamente. NO es suficiente con que el servidor sepa el estado deseado sino que hay que saber de verdad el estado real. Pero esto me complicaría la vida, necesitaría añadir un sensor que me dijera el estado de la estufa y no quiero añadir esa complejidad.

Por lo tanto, añadiré el siguiente convenio a mi proyecto Arduino:

  1. Cuando encienda el circuito (En el Setup) siempre tendré la estufa apagada 
  2. El sketch enviará una señal de apagado al servidor para que actualice el estado y de esta forma tendremos sincronizado el estado deseado del servidor con el estado real de la estufa.Por ejemplo, enviará la siguiente petición http:   http://....?set?id=xxx&estado=OFF

Con este convenio puedo sobrevivir, no en vano lo que pretendo hacer de forma remota es encender la estufa. Si de alguna forma se pierde el sincronismo entre el servidor y el arduino lo peor que puede pasar es que me quede encendida.

Para hacer el sistema más fiable podria combinar el encendido y apagado del mando a distancia con un Relé. La estufa necesita 20 minutos de proceso de apagado durante el cual deben estar funcionando los ventiladores. Así que podría hacer lo siguiente al enviar el apagado: Esperar 20 minutos y entonces apagar un Relé. Y viceversa, en el proceso de encendido podría encender un relé, esperar 2 minutos y luego enviar la señal con el mando a distancia. Eso ya veremos si lo hago,.,..

Ahora, el siguiente paso será incluir en el proyecto el envío de señales IR. 


jueves, 22 de enero de 2015

Domos - Apagando y encendiendo cosas desde Internet

Estoy lanzado. Ayer conseguí con Arduino enviar la temperatura cada cierto tiempo a mi servidor en Internet. El siguiente paso va a ser poder controlar también el encendido o apagado de algún dispositivo (Una calefacción, una lámpara, etc).

Veamos la infraestructura del servidor. En él tengo una tabla en MySql por cada "Actuador" remoto. Cada actuador tiene un id global que lo identifica. Por cada actuador tenemos un campo de estado que puede ser OFF ú ON, pero es importante saber que este es el estado deseado, es decir, con este estado vamos a poder decirle al dispositivo remoto que queremos que se encienda o que se apague pero no guarda el estado real. No vamos a tener retroinformación sobre si el dispositivo está realmente apagado o encendido.

Lo que va a hacer nuestro circuito Arduino será enviar una petición Http a nuestro servidor con la forma siguiente:

  http://php-domos.rhcloud.com/actuador.php?id=xxxx

El servidor retornará una única línea con el estado deseado para que el circuito Arduino actúe en consecuencia.

Por otra parte, en el servidor tenemos unos botones en la página query.php para establecer el estado OFF ú ON para cada actuador.

Actuador.php es tan sencillo como sigue:

<?php
require ("comun.php");
conectar();
$actuador=$_GET["id"];
$sql = <<<EOT
SELECT actuador.estado FROM actuador
 WHERE id=$actuador
EOT;
$result=mysql_query($sql);
if(!$result) {
 $error=mysql_error();
 echo "???";
}
while ($row = mysql_fetch_row($result)) {
 echo $row[0];
}
?>

Seguimos ahora con la programación del Arduino. La retomamos donde la dejamos el último día:

http://luisetemiravalles.blogspot.com.es/2015/01/domos-enviando-la-temperatura-con.html

Ahora, desde nuestro sketch Arduino, además de enviar la temperatura vamos a llamar a actuador para saber qué deseos tiene nuestro servior y encender o apagar según el resultado.

Nuestro sketch queda como sigue:





miércoles, 21 de enero de 2015

Domos - Enviando la temperatura con Arduino

Recapitulemos. Mi intención es crear un sistema domótico de andar por casa, o sea de bajísimo coste. Solo pretendo dos cosas: Ver la temperatura a distancia y encender una estufa de pellets que no está preparada para ello y de hecho me lo pone difícil porque no va a ser suficiente con darle corriente con un relé porque ella al recibir corriente se queda en off.

De momento tengo hecha una aplicación colgada en Internet que hace de puente. Esto podemos verlo en los capítulos anteriores. En el último capítulo vimos esta aplicación servidora.

  Capítulo anterior: http://luisetemiravalles.blogspot.com.es/2014/12/domos-segundo-paso-crear-la-aplicacion.html

Hacía mucho tiempo que no avanzaba en este proyecto porque estaba esperando que me llegara un chip Arduino. Por fin ha llegado.

Lo que he hecho en este paso es crear un circuito con un programa asociado que lea la temperatura y se la envie periódicamente a la aplicación que hace de puente (EL servidor).

El material necesario ha sido el siguiente:

  1. Chip Arduino:  10€
  2. Sensor de temperatura RHT11: 2€
  3. Shield Ethernet: 17€
  4. Cables: 1€
En el futuro necesitaré una fuente de alimentación

El programa que hace funcionar este circuito es el siguiente:

/*
*  Sensor de Temperatura que registra el valor en Internet llamando a la
*  aplicación con la URL
*      http://php-domos.rhcloud.com/insert.php?sensor=1236&valor=xx
*/
#include "DHT.h"
#include "SPI.h"
#include "Ethernet.h"

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

#define DHTPIN 2  
#define DHTTYPE DHT11

DHT dht(DHTPIN, DHTTYPE);

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

void setup() {
  Serial.begin(9600);
  dht.begin();
  if(Ethernet.begin(mac)==0) {
     Serial.println("Error inicializando!");
     Ethernet.begin(mac, ip);
  }
  delay(1000);
}

void loop() {

  int t = (int)dht.readTemperature();
  Serial.print("Leida la temperatura:");
  Serial.println(t);
  if(client.connect(server, 80)) {
    char aux[256];
    Serial.println("Conectado");
    sprintf(aux, query, t);
    client.println(aux);
    client.println(host);
    client.println("Connection: close");
    client.println();
    client.stop();
  } else {
    Serial.println("Error conectando");
  }
    delay(60 * 1000);
  
}

El esquema del circuito es sencillísimo. La shield Ethernet se enchufa directamente, y el sensor de temperatura DHT.11 es muy fácil de conectar. Hay que bajarse una librería para controlarlo. Busca en Google "Arduino DHT11" y encontrarás multitud de esquemas, enlaces a la librerías necesarias, videos, etc.

Al poner este circuito en marcha enviará la temperatura al servidor cada minuto y podré consultarla en cualquier momento desde la URL ya conocida; http://php-domos.rhcloud.com/query.php.

Como además guardo todos los datos que recibo podré también crear un gráfico de la tendencia de la temperatura, con el tiempo en el eje X y la temperatura en el Eje Y.

Siguientes pasos:


  1. Copiar los códigos del mando a distancia de la estufa y hacer un circuito que haga lo mismo que el mando a distancia de la estufa para así poder automatizar su encendido.
  2. Conseguir un Router y un pincho con tarjeta 3G para poder disponer de Internet en la casa del pueblo (Allí no llega el internet por cable). En Simyo tenemos una tarifa baratísima:300MB por 2,15€ al mes. Con eso será suficiente. En Amazon tenemos un Router por 25€ que tiene conexiones Ethernet necesarias y permite enchufarle un pincho 3G que tendré también que conseguir.





Domos - Jugando a automatizar envíos a través del móvil

La idea de Domos es utilizar un teléfono móvil como forma de comunicación entre el Arduino y el servidor ya sea para enviar los datos de los sensores como de trabajar con los accionadores.

Automatizar tareas en Android en segundo plano parece que es complicado: Aqui se habla de ello.

http://stackoverflow.com/questions/2775628/android-how-to-periodically-send-location-to-a-server

http://android.stackexchange.com/questions/79532/how-to-watch-a-periodically-shot-image-on-other-pc-smartphone-via-internet-no-l

A raíz de estas páginas encontré .la aplicación IP Web Cam que es una maravilla. Te crea un servidor web en el movil, así que cada vez que te conectes a él podrás tomar una foto y ver el resultado en el navegador.

https://play.google.com/store/apps/details?id=com.pas.webcam&hl=es

Este planteamiento implicaría la necesidad de que el teléfono enviara su IP a algún servidor centralizado para que podamos conocerla. No sabemos tampoco si la IP va a andar cambiando ya que estamos conectados con una tarjeta 3G a un proveedor móvil. Vete tí a saber cómo gestiona él las IPS.

Prefiero por tanto que sea el móvil quien se conecte periódicamente para realizar las acciones e incluso para esperar por ellas. Para eso necesito un temporizador. Voy a intentarlo con una aplicación normal (Es decir, sin jugar con Services de Android) asumiendo que el movil está dedicado a su labor y no voy a necesitar trabajar en segundo plano.


miércoles, 7 de enero de 2015

Jugando con Bach

Lo de Bach no tiene desperdicio. ´

Como sé tocar malamente la Invention 13 de Bach, y a una velocidad más bien lentilla, decidí ver qué pasaba si me grababa y luego multiplicaba por dos la velocidad. Pero para que la música no quedase demasiado desvirtuada lo que hice fue grabarlo en Midi y duplicar el tempo, por otro lado la grabación de video duplicarle la velocidad y finalmente mezclarlo todo.

Este fue el resultado:




Luego pensé, ¿Cómo sonará Bach al revés? Asi que le di la vuelta al Midi. De nuevo, no valía darle la vuelta al Audio porque quedaría mal. El resultado me sorprendió porque sale otro tema igual de bello que el original pero muy diferente. Por el precio de una, Bach compuso dos invenciones.

Este es el resultado: Para mí, sorprendente. Lo curioso es que no sé tocarlo.



Bach ya debió pensar en su día en darle la vuelta a las partituras y compuso este Canon Palíndromo:




Puestos a jugar con Bach, Jacques Loussier lo hace fenomenal con esta Invention:



Parece ser que esta composición de Bach está inspirada en otra de Haedel, la Suite 7. Podemos comprobarlo en el minuto 5 de este video.






Enlaces interesantes sobre esta Invention 13: