Enchufes radiocontrolados (parte 2)
![]() |
||
Esquema del montaje para pruebas |
La librería que he usado en los ejemplos es la de Randy Simons, RemoteSwitch, que os podéis descargar desde aquí. Antes de poder usarla tendréis que cambiar las referencias a WProgram.h por Arduino.h en los ficheros RemoteReceiver.h y RemoteSwitch.h.
Vamos entrando en materia. ¿Cómo podemos saber los códigos que envía nuestro mando al pulsar uno de los botones? Pues dentro de la librería viene un ejemplo, show_received_code.pde que algo retocado y en castellano queda de la siguiente forma:
#include
/*
* Este programa lee los codigos recibidos por el modulo de RF
* y los muestra por pantalla.
* El pin de datos del receptor va al pin 2 de Arduino
* (este codigo esta basado en el original de Randy Simons show_received_code.pde)
*/
void setup()
{
Serial.begin(9600);
// Indicamos que cuando se active la interrupcion 0 (pin 2 de Arduino) se llame a la
//funcion de callback "mostrarCodigo" al recibir 3 veces el mismo codigo (que es lo
//mismo que pulsar una tecla en el mando por un instante)
// interrupcion
// | repeticiones
// | | funcion callback
// | | |
RemoteReceiver::init(0, 3, mostrarCodigo);
}
void loop()
{
// no se hace nada, ya que cada vez que se reciba un codigo se ejecutara la funcion
//mostrarCodigo
}
void mostrarCodigo(unsigned long receivedCode, unsigned int period)
{
//Note: interrupts are disabled. You can re-enable them if needed.
Serial.print("Codigo: ");
Serial.print(receivedCode);
Serial.print(", periodo: ");
Serial.print(period);
Serial.println("us.");
}
Al ejecutarlo nos da una salida como la siguiente:
Codigo: 334554, periodo: 150us.
Codigo: 334554, periodo: 153us.
Codigo: 334554, periodo: 152us.
Codigo: 334550, periodo: 150us.
Codigo: 334606, periodo: 153us.
Codigo: 334554, periodo: 150us.
Codigo: 334606, periodo: 152us.
Codigo: 334550, periodo: 150us.
Codigo: 334550, periodo: 153us.
Codigo: 334550, periodo: 150us.
Codigo: 334550, periodo: 152us.
Codigo: 334550, periodo: 152us.
Codigo: 334606, periodo: 152us.
Codigo: 334550, periodo: 150us.
Codigo: 334550, periodo: 153us.
Codigo: 334550, periodo: 150us.
Codigo: 334550, periodo: 152us.
El siguiente paso natural es sustituir nuestro mando por un Arduino. Imaginemos que queremos hacer que cuando con nuestro mando enviemos una señal D On, nuestro Arduino lo detecte y envíe una señal E On. No tiene mucho sentido pero puede servirnos de punto de partida para otras implementaciones mas complejas (en el ejemplo vemos como se puede recibir y enviar con el mismo programa).
Configuramos el enchufe como 10100 00001 (Aparato E) para que podamos comprobar que al pulsar el botón D ON el Arduino envía el código E ON y se activa el enchufe.
![]() |
Configuración 10100 aparato E. |
Cargamos el siguiente código en nuestro Arduino y lo probamos:
#include #include // Codigo de Casa: 10100 // Aparato A: XXXXX10000 // Aparato B: XXXXX01000 // Aparato C: XXXXX00100 // Aparato D: XXXXX00010 // Aparato E: XXXXX00001 unsigned long A_on = 333150; unsigned long A_off = 333146; unsigned long B_on = 334122; unsigned long B_off = 334118; unsigned long C_on = 334446; unsigned long C_off = 334442; unsigned long D_on = 334554; unsigned long D_off = 334550; unsigned long E_on = 334590; unsigned long E_off = 334586; int period=150; const int pinEMISOR=7; void setup() { Serial.begin(9600); RemoteReceiver::init(0, 3, procesaCodigoRecibido); } // -------------------------------------------------------------------- // Procesamiento de los codigos recibidos // -------------------------------------------------------------------- void procesaCodigoRecibido(unsigned long receivedCode, unsigned int period) { // Leemos el codigo recibido y ejecutamos la accion que corresponda Serial.print("Codigo: "); Serial.print(receivedCode); Serial.print(", periodo: "); Serial.print(period); Serial.println("us."); // Si recibimos un D-ON, enviamos un E-ON if(receivedCode==D_on) { Serial.println("Recibido D_ON"); cli(); sei();
delay(2*period);
Serial.println("Enviado E_ON"); RemoteTransmitter::sendCode(pinEMISOR,E_on,period,3); } delay(350); } void loop() { //el codigo se ejecuta cuando se activa la interrupcion }
Y a partir de ahí ya podéis adaptar el código para hacer lo que queráis.
Hola, me viene al pelo el tutorial tengo los mismos enchufes que tu y hay que ver la de pilas que consume el mando jejejeje
Podrías poner el esquema para poder montarlo, es que no se aprecia donde se conecta los cables, mil gracias por el Tutorial y felicidades por la web
Hola ante todo felicidades por el articulo es lo que buscaba, tengo una duda respecto al codigo, por que cuando recibes D-on envias un E-on?? se supone que corresponde a otro enchufe el E-on no??? no entiendo bien el funcionamiento, me podrias explicar un poco?
gracias y continua asi tus tutoriales son una fuente de inspiración
Exactamente, imagínate que tienes 15 enchufes radiocontrolados y los quieres controlar con un solo mando: podrías hacer que cuando recibas un D ON y luego un A OFF, por ejemplo (o cualquiera secuencia de pulsaciones), se activara uno de los enchufes o varios, que no tienen por que coincidir con el del código que realmente ha enviado el mando…
Incluso podrías hacer que al pulsar un D_ON en el mando, se envíe un E_ON, y a los 10 segundos un E_OFF y tendrías una emulación de un enchufe temporizado…
Por cierto, a ver si esta tarde tengo un hueco y hago el esquema que me pedía el comentario anterior con Fritzing para que quede mas claro todo…
Gracias por el comentario 🙂
Acuerdate del esquema por favor 🙂 que te espero como agua de mayo jejejejee, tengo todos los trastos listos para la operación 🙂
graciass
Mil gracias, espero tu esquema y muchísimas gracias por contestar, ya te contaré como me queda el proyecto cuando lo termine 🙂
Acabo de publicar los esquemas como una nueva entrada en el blog, espero que te sean de ayuda :),
un saludo!!
graciasss si lo he vistooo ahora si me voy a poner a montarlo a ver si me resulta bien la jugada k el mando consume demasiadas pilas jejejej
hola acabo de comprar todo lo necesario 🙂 pero tengo un problema, cuando intento cargar el emisor me da error en la siguiente linea
RemoteReceiver::init(0, 3, mostrarCodigo);
es la unica descomentada de la explicación, me puedes decir como hacerlo bien?? es que no se como cargar bien el programa soy novato en arduino
gracias y felicidades por el blog
¿Cual es exactamente el error que te da? ¿Has copiado los archivos de la libreria en la carpeta de librerias de arduino?
vale creo que va a ser eso, en la propia carpeta que descargue cree ahi el fichero pensando que lo cojeria de ahi.
Entonces no es asi no?
Perdona ya he resuelto ese problema, efectivamente no tenia la libreria metida dentro, ya puedo capturar los codigos pulsado con el mando, ahora tengo el siguiente problema es a la hora de mandar cuando compilo me lanza lo siguiente:
RemoteSwitch\RemoteReceiver.cpp.o: In function `RemoteReceiver::enable()’:
tambien he bajado en newremoteswich por que es el que tenia el transmitter.h que en el primer enlace no esta…
igual tiene que ver.
gracias y disculpa de nuevo
Hola Jose Maria, que tal perdona que te moleste pero has podido averiguar el error que me da a que es debido? es que por mucho que lo miro no encuentro donde he metido la pata…
mil gracias
Acabo de verlo, creo que el problema está en que los ejemplos los desarrollé con INO en lugar del entorno IDE Arduino y las librerías las pilla de un lugar distinto: en mi instalación con INO está usando la version 2.2.1 de RemoteSwitch. Prueba con la versión nueva y me cuentas.
Si parece ser que pueda ser eso, yo he hecho otro codigo basandome en el tuyo y pillando de todos sitios que he podido ver y al final me funciona con el ide con el siguiente codigo:
#include
#include
#define OUTLET_A_ON 265353
#define OUTLET_A_OFF 265349
#define OUTLET_B_ON 266325
#define OUTLET_B_OFF 266321
#define OUTLET_C_ON 266757
#define OUTLET_C_OFF 266753
#define OUTLET_D_ON 266757
#define OUTLET_D_OFF 266753
#define OUTLET_E_ON 266793
#define OUTLET_E_OFF 266789
#define PERIOD 150;
#define RF_TX_PIN 4
void setup() {
Serial.begin(9600);
}
void loop() {
unsigned char comando=0;
if(Serial.available()){
comando=Serial.read();
if (comando==’a’) transmit(OUTLET_A_ON);
//Serial.println(«Sending on»);
else if (comando==’b’) transmit(OUTLET_A_OFF);
else if (comando==’c’) transmit(OUTLET_B_ON);
else if (comando==’d’) transmit(OUTLET_B_OFF);
else if (comando==’e’) transmit(OUTLET_C_ON);
else if (comando==’f’) transmit(OUTLET_C_OFF);
else if (comando==’g’) transmit(OUTLET_D_ON);
else if (comando==’h’) transmit(OUTLET_D_OFF);
else if (comando==’i’) transmit(OUTLET_E_ON);
else if (comando==’j’) transmit(OUTLET_E_OFF);
delay(100);
}
}
void transmit(unsigned long rcode){
unsigned long code = rcode;
unsigned long period = PERIOD;
code |= (unsigned long)period << 23; code |= 3L << 20; RemoteSwitch::sendTelegram(code, RF_TX_PIN); // RF transmitter pin }
ahora ya seria perfecto quitar de enmedio arduino y que pueda emitir señales directamente desde la raspberry….
por cierto me puedes indicar como puedo conectarme desde la raspberry al arduino por serial para al menos enviarle las señales por consola??
mil gracias
Yo utilizo el picocom, que es lo que usa INO para comunicarse por serie a través del USB, con picocom /dev/ttyUSB0 (o lo que sea) te conectas y para salir pulsas Control A X (creo recordar, las tres juntas y cierra la conexión).
Por cierto, ¿a que distancia tienes el emisor del receptor para que te funcione correctamente? Yo no conseguí que funcionará de forma fiable a mas de tres metros (sin antena)…