viernes, 23 de agosto de 2013

Comunicacion por RF a 433Mhz desde Arduino hasta RaspberryPi

... esto ya es otro nivel ...

Muy buenos y prósperos días, amigos. Hace tanto tiempo que ya ni recuerdo, me compré un kit emisor-receptor de radiofrecuencia en la banda de 433Mhz (standard inalámbrico en banda libre en España), para unos proyectitos con Arduino. No conseguí mucho con ellos, hasta que hace un par de días conecté el receptor al RaspberryPi, te cuento como hacerlo.

Los módulos en cuestión son:

que los tienes en cualquier tienda de electrónica y webs como dealextreme a precio de risa. El de la izquierda es el receptor y el de la derecha el emisor. Y a tu primera pregunta: NO, no son bidireccionales.
Te recomiendo que antes de nada, pruebes que funcionan correctamente, para ello usa dos de tus Arduinos (¿no tienes más de uno?) y guíate por este manual, usan el de 315Mhz, pero las instrucciones son exactas para los de 433Mhz.

En el Arduino

Como hacer solo la parte de la comunicación no tiene mucho misterio (aunque me ha costado casi una semana), voy a conectarle un sensor analógico de temperatura LM35. La idea es transmitir esa temperatura desde el Arduino hasta el Raspberry. La conexión quedaría así:
fácil fácil, lleva más tiempo hacer el esquema. Necesitamos una librería nueva, la descargamos de este enlace y la descomprimimos en el directorio de librerias de nuestro Arduino. Creamos el siguiente código en el Arduino:
#include 
RCSwitch mySwitch = RCSwitch();
long envio = 0;

// Declaracion de variables
float tempC;
int tempPin = 0; // Definimos la entrada en pin A0
void setup()
{
    // Abre puerto serial y lo configura a 9600 bps
    Serial.begin(9600);
    mySwitch.enableTransmit(10);
}
void loop()
{
    // Lee el valor desde el sensor
    tempC = analogRead(tempPin);

    mySwitch.send(tempC, 8);
    
    // Espera cinco segundo para repetir el loop
    delay(5000);
}
Con este hardware y esta librería, podemos enviar número de hasta 32 bits. La cadena:
mySwitch.send(tempC, 8);
indica que esta enviando un número de 8 bits, lo que viene a ser entre -128 y +127, teniendo en cuenta que el sensor de temperatura trabaja entre -55ºC y +150ºC, nos sobra. Cargamos el código y lo dejamos en marcha.

En el RaspberryPi

Tenemos que proveer de alimentación suficiente al receptor, además de leer de uno de los pins DATA. El esquema es el siguiente:

También es bastante simple. El receptor tiene 4 pines, pero en realidad los dos centrales están puenteados, así que puedes conectarlo donde más te guste. Antes de nada hay que tener compilado WiringPi, pásate por este post. Ahora tenemos que:
mkdir -p /usr/src/rasp433/
cd /usr/src/rasp433/
wget https://www.dropbox.com/s/faw6y1lzguhgxvx/rpi.zip
unzip rpi.zip
gcc rfreceive.cpp RCSwitch.cpp -o rfreceive -lwiringPi
gcc rftester.cpp RCSwitch.cpp -o rfreceive -lwiringPi
Ahora mismo vamos a preocuparnos sólo de recibir, en los siguientes post afinaremos el código. Ejecutamos:
./rfreceive 0
Received: 60
Received: 60
Received: 60
Received: 61
Eso significa que hace (60x500/1024)ºC o lo que es lo mismo, 29.3ºC en Sevilla 23 de Agosto a las 08:00 (vaya caló cabesa).

Problemas

¿problemas? Muchos, la información para hacer todo esto esta repartida en unos 100 post del foro de Raspberry, en 200 webs y en mucho dolor de cabeza. Agradezco eternamente la ayuda de @Rémi_Sarrailh por su ayuda, eres un crá.
Bueno y ahora el problema físico de todo esto, la antena. Si te fijas bien, cada módulo tiene una antenita ridícula y un agujerito donde poner tu propia antena. Si no pones antena, la distancia entre emisor y receptor no puede ser mayor de ... 50 centímetros. Yo ahora mismo les he puesto a cada uno, un hilo de un cable de red muy rígido. Unos 20 centímetros cada una, con lo que consigo distancias de 10 metros. Tengo que mejorar aun mucho la cobertura, pero por ahora me vale para las pruebas.

y todo esto ¿para qué?

Buena pregunta, con esto conseguimos tener sensores SUPERBARATOS e INALAMBRICOS de todo tipo, en distintas partes de la casa. En los próximos días voy a estar haciendo pruebas de sustitución del Arduino por un attiny85 ... hagan sus apuestas.

Post dedicado a Jorge Sandín, a ver si te animas de una vez!!

29 comentarios:

  1. Es una caña la verdad, se podría usar para clonar un mando a distancia y así poder encender la tele o cualquier aparato desde internet, eso si que seria la repera, seguro que ya le has dado algún uso asi verdad?

    ResponderEliminar
    Respuestas
    1. hombre ... si tu tele funciona por radiofrecuencia si, si va por infrarojos no. Para eso que quieres es fácil con los minimandos universales que tienen en los chinos a 3€, conmutas con los GPIOs y listo ;)

      Eliminar
  2. Y que alcance tienen esos emisores/receptores?

    ResponderEliminar
    Respuestas
    1. poco, tienes que darles toda la alimentacion posible y ponerles una antena en condiciones (estoy en ello). Con suerte puedes conseguir unos 40m.

      Eliminar
  3. Ehh!! creo que es la primera vez que me dedican un post tan friki! :'D gracias apañero, volveré... volveré para dominar el mundo! muahaha... ;)

    ResponderEliminar
  4. Conseguiste aumentar la distancia con una antena mejor??? Eres un crack me interesa muchííííísimo este tema de sensores inalámbricos.

    ResponderEliminar
    Respuestas
    1. yes! he puesto en el emisor y receptor 33cm de cobre "gordo", lo he sacado de un cable de antena de tv, solo el core. Es mas con un cable asi, en el emisor puedes poner una antena mas cortita.

      Eliminar
    2. Y a cuanto te ha aumentado la distancia??? si pudieras mandarme una foto de como tienes montada la antena te lo agradecería, yo estoy intentando salvar unos 15 metros de distancia, desde el cuadro general de mi casa, para medir los consumos..., eres un fenómeno, te seguiré de cerca

      Eliminar
    3. porqué 33 cm? yo he leido que se aconseja 1/4 de la longitud de onda, que para 433 MHz me saldrían unos 17 cm. ¿Has hecho pruebas con diferentes medidas?

      Eliminar
  5. Buenas noches amigo, como hago para que me tome los datos directamente al LabView?

    ResponderEliminar
  6. Muy buena introducción. Quiero probar cosillas de estas y este post es un buen trampolín!!!

    Gracias!

    ResponderEliminar
  7. Sabes si con un solo transmisor conectado en la raspberry pi se puede enviar la señal a multiples receptores distribuidos por casa y así controlar diversos aparatos?

    ResponderEliminar
  8. hola

    sabeis porque mi raspi no escucha constantemente y solo lo hace una sola vez ?

    gracias

    ResponderEliminar
    Respuestas
    1. yo la llevaria a un otorrino ,,,,

      Eliminar
  9. Si conectas dos emisores a un mismo receptor, ¿el receptor sabe identificar cada emisor?

    Saludos.

    ResponderEliminar
    Respuestas
    1. No, esto no tiene ip ni una mac, tienes que currarte la comunicación, puedes enviar algo así como:
      Soy_emisor_01_orden_32
      Que puede ser algo como:
      01032
      Mas o menos, en elncodigobdel receptor filtras por los dos primeros dígitos y ya sabes quien le habla.

      Eliminar
    2. Gracias por contestar. No había trabajado nunca con RC, no sabía como iba eso de los mensajes, pero si me dices que puedo hacer eso entonces imagino que con eso ya se puede hacer una pequeña red de sensores que comuniquen a un único receptor pero, si llegan 2 señales a la vez a un mismo receptor, ¿sabes si una de esas dos la descarta, encola... que hace?

      Eliminar
    3. Hola ... Anónimo ... Ponte un nick porfa. La simultaneidad no existe, son los padres. Tienes que currarte un poco mas los mensajes, tienes que hacer que el receptor tenga cierta inteligencia y descartar mensajes repetidos, mientras que en el emisor envías lo mismo 5 ó mas veces. Pero currate cada mensaje repetido para que el receptor solo le preste atención la primera vez. En fin hay miles de formas de hacerlo y a cada cual mas creativa que la anterior.

      Eliminar
  10. hola,
    tengo 2 arduino que comunican con estos modulos usando manchester. Acabo de comprar una pi 2 para intentar capturar estos datos y poder hacer mas cosas que xon el arduino. Con tu codigo recibo una ristra de 1 y 0s cada vez que lo ejecuto. Ando un poco perdido, estoy mirando python, pero igual deberia usar C. Podria usar en C la libreria manchester del arduino?, me puedes orientar un poco? Gracias

    ResponderEliminar
  11. hola amigo

    este proyecto no funciona para mi...nose si hay algun problema de versiones de libreria ?

    gracias

    ResponderEliminar
  12. Me estoy volviendo loooco para adaptar esto a un sensor de presencia pir, serías tan amable de ayudarme para cambiar el sensor de temperatura a uno de presencia???

    ResponderEliminar
    Respuestas
    1. en esencia es lo mismo, pero me tienes que dar más datos ¿es un sensor por a pelo? viene con un integrado y unos potenciometros? ¿te llega algun dato?

      Eliminar
    2. Estoy usando el sensor de abajo y con la raspberry ya he conseguido ver cuando detecta movimiento, pero en arduino aún no, no se como decirle que lo que recoja del sensor se lo mande a la raspberry con el código que ya hay ;S

      http://www.ventor.co.in/images/categories/infrared-pir-motion-sensor-module.jpg

      Eliminar
  13. Respuestas
    1. Otra pregunta, ¿por qué compilas dos archivos con el mismo nombre en la rasp? el rfreceive y el rftester, los compilas como rfreceive...

      Eliminar
    2. Es un error, la segunda compilación debería ser:
      gcc rftester.cpp RCSwitch.cpp -o rftester -lwiringPi
      Por lo demás, gracias Juan. Lo he hecho como has dicho y funciona perfectamente.

      Eliminar
  14. Hola saludos. Excelente espacio. Tengo inquietud. Tengo 1raspberry y el módulo fs1000a la pregunta es: en el emisor puedo cambiar el arduino por ht12e y el sensor de temperatura por un pulsador? Sin cambiar nada en el resto. Agradeciendo tu valiosa ayuda desde colombia.

    ResponderEliminar