MCRF-VW

28
MCRF-VW Manual Comunicación RF con Virtual Wire Versión 1.5 Para Arduino Duemilanove y compatibles

Transcript of MCRF-VW

Page 1: MCRF-VW

MCRF-VW

Manual Comunicación RF con Virtual Wire Versión 1.5Para Arduino Duemilanove y compatibles

Page 2: MCRF-VW

Salvador García Bernal

M.C. en Electrónica y Sistemas DigitalesLic. en Ing. Electrónica y Computadoras

Primera Revisión: Marzo 2010Segunda Revisión: Abril 2010

Todas las marcas son propiedad de sus respectivos dueños.

Attribution Non-Commercial Share Alike

This license lets others remix, tweak, and build upon your work non-commercially, as long as they credit you and license their new creations under the identical terms. Others can download and redistribute your work just like the by-nc-nd license, but they can also translate, make remixes, and produce new stories based on your work. All new work based on yours will carry the same license, so any derivatives will also be non-commercial in nature.

Page 3: MCRF-VW
Page 4: MCRF-VW

Contenido

1 – Comunicación RF con Virtual Wire

1.1 – Acerca de Virtual Wire ........................................................1.2 – Instalando Virtual Wire 1.5 ..................................................1.3 - Hardware soportado por Virtual Wire .................................1.4 – Configuración básica Transmisor-Receptor ........................

2 - Ejemplos Prácticos

2.1 – Control remoto de un Relé ..................................................2.2 - Sensado de temperatura remoto .......................................2.3 - Diseño de un algoritmo de cifrado - descifrado básico .......

Anexo ...........................................................................................

10101112

151922

25

Page 5: MCRF-VW
Page 6: MCRF-VW
Page 7: MCRF-VW

1 – Comunicación RF con Virutal Wire

1.1 - Acerca de VirtualWire

VirtualWire es una librería desarrollada por Mike McCauley. Esta es usada con la mayoría de las tarjetas compatibles con Arduino. Es posible enviar mensajes cortos, sin direccionamiento, retransmisión o reconocimiento; se define como un UDP inalámbrico usando ASK (Amplitud Shifting Keying). La librería soporta un gran número de transmisores - receptores inalámbricos de bajo costo.

No se usa el UART del microcontrolador, esto debido a que los mensajes son enviados con preámbulo, la longitud del mensaje contiene checksum. Estos mensajes son enviados con codificación de 4 a 6 bits para un buen balance de DC, y checksum CRC para su integridad.

1.2 – Instalando Virtual Wire 1.5

La librería puede descargarse del sitio oficial, actualmente en su versión 1.5 del siguiente enlace:

http://www.open.com.au/mikem/arduino/VirtualWire-1.5.zip

Existe un manual oficial en Ingles también descargable de la siguiente dirección:

http://www.open.com.au/mikem/arduino/VirtualWire.pdf

Una vez descargado el archivo: VirtualWire-1.5.zip, se descomprime y copia en el sub-directorio de Arduino bajo: libraries.

Si se encuentra en MacOSX, acceda a la carpeta donde se ubica la aplicación Arduino, de ctrl + clic sobre el icono. Seleccione: Mostrar Contenido del paquete. Entre a las siguientes carpetas hasta encontrar: libraries bajo la ruta:

/Arduino.app/Contents/Resources/Java/hardware/

Copie la carpeta: VirtualWire.

Para GNU/Linux, puede acceder directamente a la carpeta que contiene la aplicación: /arduino-0017/Java/hardware/ , hasta encontrar: libraries . Dentro de esa carpeta copiamos: VirtualWire.

1 – Comunicación RF con Virtual Wire 10

Page 8: MCRF-VW

Para Windows se requiere entrar al directorio principal de Arduino:

ARDUINO\lib\targets\libraries.

Otra manera de instalar la libreria es: bajo MacOSX: ~/Documents/Arduino/libraries/. En Windows, se encontrará en: My Documents\Arduino\libraries\ . Este procedimiento es válido para la versión de Arduino 0018. Para versiones anteriores (inclusive la 0018) el procedimiento descrito anteriormente será funcional.

Una vez instalado, inicie el IDE de Arduino, para incluirla en el scketch de clic en el menu: Sketch - Import Library, seleccionar VirtualWire. Automáticamente incluirá el código requerido para poder usarse la librería tal como:

#include <VirtualWire.h>

1.3 - Hardware soportado por VirtualWire

Existe una gran cantidad de hardware soportado por Virtual Wire. Todos en diferentes gamas, frecuencias, tamaños, etc. Los módulos más recomendables se enlistan a continuación.

Módulo TxRx-315Mhz

• Frecuencia: 315Mhz• Modulación: ASK• Transmitter input voltage: 3-12V• Alcance máximo: 100 mts

Módulo TxRx 433/315 Mhz

• Frecuencia: 433/315Mhz• Modulación: ASK• Transmitter input voltage: 3-12V• Alcance máximo: 150 mts

1 – Comunicación RF con Virtual Wire 11

Page 9: MCRF-VW

Módulo TxRx HS On-Shine 433Mhz

• Frecuencia: 433Mhz• Modulación: Compatible con ASK• Transmitter input voltage: 3-12V• Alcance máximo: 150 mts

Módulo TxRx 315 Mhz Con Encoder/Decoder

• Frecuencia: 315Mhz• Modulación: Compatible con ASK• Transmitter input voltage: 3-12V• Alcance máximo: 100 mts

1.3 - Configuración básica Transmisor - Receptor

La configuración básica para usar el módulo, es considerar un voltaje constante de: 3.3 V ó 5 V (según se requiera) en las terminales de voltaje de cada módulo de recepción y transmisión.

En la figura 1.3.1 puede observarse el módulo con frecuencia selectible de 433 Mhz ó 315 Mhz. Tiene que considerar los pines de TxRx del microcontrolador (MCUx) usados para configurar correctamente la librería. Es recomendable usar una antena, puede usarse un cable ó un tubo pequeño de aluminio, que no excedan las longitudes indicadas en ambos lados de los módulos.

12 1 – Comunicación RF con Virtual Wire

Page 10: MCRF-VW

Figura 1.3.1 - Configuración básica para los módulos TxRx 315/433 Mhz.

Figura 1.3.2 - Configuración básica para los módulos TxRx 315 Mhz.

1 – Comunicación RF con Virtual Wire 13

Page 11: MCRF-VW
Page 12: MCRF-VW
Page 13: MCRF-VW

2 - Ejemplos con Virtual Wire

A continuación para el lector, se proponen en está sección algunos ejemplos prácticos aplicados a diferentes experimentos, que pueden realizarse con la librería VirtualWire.

2.1 - Control remoto de un relé

En este ejemplo, se requiere controlar un relé remotamente. Para ello se diseña un sistema Transmisor - Receptor. El cual de manera general puede verse en la figura 2.1

Figura 2.1 - Diagrama general del ejemplo propuesto.

El primer bloque contiene una conexión USB a la estación de trabajo (Computadora, Laptop, etc) en dónde se indicará la acción básica de abrir o cerrar el relé. Esta palabra se envía inalambricamente usando el Módulo Tx. Cuando el receptor (Módulo Rx) obtiene la palabra de control, ésta será descodificada para realizar la acción programada usando el relé conectado al microcontrolador.

Para el segundo bloque, usa un relé, que es un switch que puede controlar cargas mayores. Estos se pueden usar para activar algún dispositivo grande, como pudiera ser un motor, el encendido de una fuente, entre otras aplicaciones. Existen diversos tipos de relé, aquí se expone uno de ellos, el cual se activa con 5 volts, como el Reed D1A0500.

2 - Ejemplos con Virtual Wire 15

Page 14: MCRF-VW

Es recomendable usar una resistencia de entre 10 – 15 k, un transistor NPN como el 2N3904, finalmente entre las terminales un diodo 1N4007. En la figura 2.2 se propone un circuito que funciona para controlar el abierto – cerrado del relé.

Figura 2.2 - Diagrama para un relé de 5 V.

Cada módulo Tx - Rx, por regla general, se recomienda usar un capacitor de 100 nF (entre 5 - Gnd, cerca de los módulos), conocido como capacitor decoplador; esto es debido a que existen señales parásitas no deseadas que pueden afectar la transmisión - recepción en un circuito, en este caso inalámbrico.

Para el transmisor, analizaremos una transmisión sin codificación (en un ejemplo posterior se diseñara un algoritmo de cifrado - descifrado). Lo primero que se requiere es obtener una palabra corta para cerrar el relé, en este caso: P. Para abrir, usaremos: A.

Consideremos que la función VW_MAX_PAYLOAD (), envía un mensaje de la siguiente manera:

• 36 bit, preparación de preámbulo de pares bit (0-1) • 12 bit, símbolo de inicio (0xb38) • 1 byte de mensaje, longitud de byte (4 a 30), esto incluye: byte de cuenta y bytes de FCS • n mensajes en bytes • 2 bytes de FCS, enviado como: low byte, hi byte Todo lo demás se codifica de 4 a 6 bits. En la transmisión se envía primero los bits menos significativos.

Para el Arduino Duemilanove con una frecuencia de reloj de 16MHz equivalente a 62.5ns/ciclo. Podemos considerar una tasa de transferencia de 2000 bps, si consideramos una palabra máxima de 30 bits (VW_MAX_MESSAGE_LEN) tenemos:

!6"1"VW_MAX_MESSAGE_LEN #$6=222bits ...(1)

16 2 - Ejemplos con Virtual Wire

Page 15: MCRF-VW

Dónde el bitrate se calcula como:

t=2n

Rbps ...(2)

Así el tiempo dado de 2n bits, calculado anteriormente será a 2000 bps:

t = 0.11 segs

Así para el transmisor, podemos tener el siguiente código 2.1.(Para este ejemplo se usan los pines de conección default de la librería VirtualWire)

#include <VirtualWire.h>

void setup() { Serial.begin (4800); // bps para USB vw_setup(2000); // bps para transmisor } int Data;char DataTx[10];

void loop() {

if (Serial.available() > 0) {

Data = Serial.read(); itoa (Data,DataTx,10);

vw_send( (uint8_t *)DataTx, strlen(DataTx)); vw_wait_tx(); // Espera hasta que termine de enviar la palabra

delay (5);

}

}

Código 2.1 - Código usado para el transmisor.

Observe que se usa la función itoa(), la cual convierte un valor tipo int a su representación ASCII, este recibe el valor entero (Data), la representación (DataTx) la cuál será enviada, así como un radio. Considere, sí el radio es mayor a 10, el siguiente dígito después de '9' será la letra 'a'. De igual manera para la recepción (se usan los pines por default de la librería), consideremos que el relé se conecta en el Pin 7, para ello observe el código 2.2:

2 - Ejemplos con Virtual Wire 17

Page 16: MCRF-VW

#include <VirtualWire.h>

int rele = 7; //puerto para el rele

void setup() { vw_setup(2000); // Bps para receptor vw_rx_start(); //iniciamos el receptor pinMode (rele,OUTPUT);

} void loop() {

int i, DataRx; uint8_t buf[VW_MAX_MESSAGE_LEN]; uint8_t buflen = VW_MAX_MESSAGE_LEN; if (vw_get_message(buf, &buflen)){

char tmp[buflen]; memset(tmp,'\0', sizeof(tmp)); strncpy(tmp, (char*)buf,buflen); DataRx = atoi(tmp);

//Reviso Acción

if (DataRx == 80) {

digitalWrite(rele,1);

}else if (DataRx == 65) {

digitalWrite(rele,0);}

delay (1000); }

}

Código 2.2 - Código usado para el receptor.

Observe que se usa la función strncpy(), dónde se copia la cadena del vector buf a tmp de longitud buflen. También se puede notar el uso de la función atoi(), que contiene la conversión de ASCII a un valor tipo int. Con esto podremos usarlo para manejar alguna acción determinada.

18 2 - Ejemplos con Virtual Wire

Page 17: MCRF-VW

2.2 - Sensado de temperatura remoto

Para este ejemplo se usará un sensor de temperatura tal como el LM35 ó TMP36. Existen diversas formas de conectar el sensor, la más simple se muestra en la figura 2.2.1, como puede ver solo requiere una resistencia R1 de 330.

Considerando, que la curva de respuesta lineal para este sensor se observa en la figura 2.2.2, podemos deducir las siguientes dos ecuaciones para el LM35 ó TMP36.

Figura 2.2.1 - Diagrama básico para usar un LM35 ó TMP36.

Figura 2.2.2 - Gráfica de Voltaje - Temperatura para los sensores LM35 ó TMP36.

2 - Ejemplos con Virtual Wire 19

Page 18: MCRF-VW

Para TMP36:

V=5VADC

1024

T=!V%0.5#

100

... (2.2.1)

Para LM35:

V=5VADC

1024

T=V

100

... (2.2.2)

De manera general el sistema de transmisión - recepción se observa en la figura 2.2.3, como puede verse el transmisor se encuentra junto al sensor (S1).

Considerando los códigos anteriores (2.1, 2.2), es posible diseñar los siguientes códigos 2.3 y 2.4.

Figura 2.2.3 - Diagrama general para el monitoreo remoto de temperatura.

void loop() {

Vadc = analogRead(Tin); //Variable de tipo Int V = map(Vadc,0,5,0,1024); itoa (V,DataTx,10); vw_send( (uint8_t *)DataTx, strlen(DataTx)); vw_wait_tx(); // Espera hasta que termine de enviar la palabra

delay(1500);

}

Código 2.3 - Código principal para el Transmisor.

20 2 - Ejemplos con Virtual Wire

Page 19: MCRF-VW

Considere, que el dato a enviar (V) debe ser entero, el cual previamente se convierte a una cadena de caracteres (DataTx) para enviarlos de manera inalámbrica. Es posible realizar todo el procesamiento en el transmisor, pero se recomienda enviar los datos simples.

void loop() {

uint8_t buf[VW_MAX_MESSAGE_LEN]; uint8_t buflen = VW_MAX_MESSAGE_LEN; if (vw_get_message(buf, &buflen)){ Ndata = obtenData (buf, buflen); //Variable de tipo int

tempC = (Ndata - 0.5) * 100 ; //Variable de tipo flotante tempF = (tempC * 9 / 5) + 32; //Variable de tipo flotante

Serial.print(tempC); Serial.println(" C "); Serial.print(tempF); Serial.println(" F "); delay(1500);

}

Código 2.4 - Código principal para el Receptor.

Una vez que la palabra llega al receptor, ésta se convierte a flotante para poderla procesar y así convertirla a grados centígrados y Fahrenheit. Observe que se usa una función llamada obtenData(), que contiene parte del código 2.2 para recuperar los datos. En la terminal del receptor podrá observar los datos recibidos como lo que se muestra en la figura 2.2.4.

Figura 2.2.3 – Datos visualizados en la terminal de recepción de Arduino.

2 - Ejemplos con Virtual Wire 21

Page 20: MCRF-VW

2.3 - Diseño de un algoritmo de cifrado - descifrado básico

Existen una diversidad de algoritmos denominados de dominio público que se estudian en diversas universidades del mundo. Este tema es tratado con delicadeza por tener cierta seguridad. Los algoritmos de cifrado pueden ser de sustitución, en dónde se toman ciertos datos para ser sustituidos por otros. También, se usa la transpocisión, que consiste en ordenar de forma diferente los datos. A este proceso se le conoce como cifrado. El proceso contrario es el descifrado, que consiste en aplicar una técnica similar (inversa) a la que se uso para cifrar el mensaje original. Esto se muestra en el ejemplo 2.3.1, dónde se aprecia este proceso.

G A T O N O V I V E

Vocales se sustituye:

A = EO = I

G E T I N I V O V A

G A T O N O V I V E

Vocales se transponen:

A 1 posición Izquierda O 2 posiciones izquierdaE 3 posiciones izquierda

A O G O T N E V I V

Ejemplo 2.3.1 – Cifrado básico. (Izquierda) – Manejo de cifrado por sustitución(Derecha) – Manejo de cifrado por transposición

Existen dos vertientes importantes, una es la simétrica y otra la asimétrica. En la primera de ellas, se usa una misma clave para cifrar y descifrar mensajes. Las dos partes que se comunican han de ponerse de acuerdo sobre la clave a usar. Una vez que ambos tienen acceso a esta clave, el remitente cifra un mensaje usándola, lo envía al destinatario, y éste lo descifra con la misma clave.

En la segunda se usan dos claves que pertenecen a la misma persona a la que se ha enviado el mensaje. Una clave es pública y se puede entregar a cualquier persona, la otra clave es privada y el propietario debe guardarla de modo que nadie tenga acceso a ella. Este método criptográfico garantiza que esa pareja de claves sólo se puede generar una vez, el remitente cifra un mensaje usando la clave publica , lo envía al destinatario, y éste lo descifra con la clave privada.

Estos temas son muy extensos, aquí se presenta un ejemplo práctico que puede funcionar, el cual tiene algunos inconvenientes. La clave está en el algoritmo lo cual lo pone como un inconveniente. Una ventaja es que se pueden crear dos versiones diferentes; una para el cifrador y otra para el descifrador. En este ejemplo, el remitente envía palabras cifradas, el destinatario descifra estas palabras.

22 2 - Ejemplos con Virtual Wire

Page 21: MCRF-VW

Para esto usamos un algoritmo de transposición no inversa, el cifrado se define como:

{ k=n , c=!k"1#

2

|i=0

c%1

! !P2i !c%i # , P2i"1!k%i ##} ... (2.3.1)

Para el descifrado, podemos tener:

{ k=n , c=!k"1#

2

|i=0

c%1

! ! |n=!c%1#%i

Pi!2n # , Pi"c !2n"i ##} ... (2.3.2)

Este proceso lo realizamos bajo bits. Si suponemos el carácter “J”, valor ASCII 74. Al aplicar la ecuación 2.3.1 tendremos:

J – ASCII 74

0 1 0 0 1 0 1 0

ec. 2.3.1

1 1 1 0 0 1 1 0

µ - ASCII 230

Al aplicar el descifrador de la ecuación 2.3.2 podremos recuperar “J”

Para ello podemos crear una función para el cifrador como se muestra en el código 2.5

void enc (int Din[], int k){

int i; int C = (k + 1) / 2; for (i = 0; i <= C; i ++){ tmp[2*i] = fnot (Din[C - i]); tmp[2*i+1] = fnot (Din[k - i]); } return tmp;}

Código 2.5 – Función para el cifrador basados en la ecuación 2.1.

2 - Ejemplos con Virtual Wire 23

Page 22: MCRF-VW

Para el descifrador, se recomienda que el usuario desarrolle su propia función basadose en la ecuación 2.3.2. Para la función: fnot(), podemos usar el código 2.6.

int fnot(int nD) {

int fn;

if ( nD == 1) { fn = 0; }else{ fn = 1; } return fn; }

Código 2.6 – Función para el fnot().

Considere que se requiere usar una función que convierta este vector binario a una palabra de tipo char. o int Para ello también el usuario deberá crear una función que convierta el vector a una palabra binaria usando:

27

26

25

24

23

22

21

20

128 64 32 16 8 4 2 0

Tabla 2.1 – Conversión binaria.

Con esto, es posible enviar palabras cifradas al receptor usando las funciones que se han visto de Virtual Wire. Para mayor referencia puede consultar el anexo.

24 2 - Ejemplos con Virtual Wire

Page 23: MCRF-VW

Anexo.

A.1 – Funciones de Virtual Wire

A continuación se explica brevemente cada función soportada por la librería Virtual Wire.

vw_set_tx_pin extern void vw_set_tx_pin(uint8_t pin); Función para manejo de puerto Entrada/Salida (IO), que se usa para transmitir datos. Por default es 12.

vw_set_rx_pin extern void vw_set_rx_pin(uint8_t pin); Función para manejo de puerto Entrada/Salida (IO), que se usa para recibir datos. Por default es 11.

vw_set_ptt_pin extern void vw_set_ptt_pin(uint8_t pin); Pone el puerto digital Entrada/Salida para habilitar la transmisión. Por default es 10. No todos los transmisores requieren PTT. Esto es requerido por el DR3100, pero no el TX-B1.

vw_set_ptt_inverted extern void vw_set_ptt_inverted(uint8_t inverted); Por default el ping PTT se pone en alto cuando el transmisor se habilita. Esta bandera permite forzar cuando el transmisor es habilitado. Esto se requiere para el DR3100.

vw_setup extern void vw_setup(uint16_t speed); Función para inicializar VirtualWire, esta función requiere velocidad de bits por segundo. Se debe configurar en el setup() después de cualquier llamada vw_set_* . Debe llamarse después a la función: vw_rx_start(), antes de recibir cualquier mensaje. No se recomienda trabajar a más de 10000 bps.

vw_rx_start extern void vw_rx_start(); Función para iniciar el receptor. Debe hacerce esto antes de recibir un mensaje. Cuando un mensaje esta disponible (tenga o no un buen checksum), la función: vw_have_message() regresa un valor verdadero (true).

Anexo 25

Page 24: MCRF-VW

vw_rx_stop extern void vw_rx_stop(); Esta función detiene el receptor. No se reciben mensajes hasta que la función: vw_rx_start() se llame de nuevo. Se almacena la interrupción en ciclos de procesamiento cuando se sabe que no habrá mensajes.

vx_tx_active extern uint8_t vx_tx_active();La función regresa un valor verdadero (true), cuando el transmisor esta activo.

vw_wait_tx extern void vw_wait_tx(); La función se usa para bloquear y esperar, hasta que el transmisor este en espera.

vw_wait_rx xtern void vw_wait_rx(); La función se usa para bloquear y esperar, hasta que el mensaje este disponible del receptor.

vw_wait_rx_max extern uint8_t vw_wait_rx_max(unsigned long milliseconds); Esta función espera en mili-segundos (ms) por un mensaje a ser recibido. Regresa estado de verdadero (true) si el mensaje está disponible.

vw_send extern uint8_t vw_send(uint8_t* buf, uint8_t len); Con esta función se envía un mensaje de determinada longitud. Regresa casi inmediatamente, y el mensaje será enviado con tiempo correcto por la interrupción. Regresa estado verdadero (true) si el mensaje fue aceptado para transmitir. Regresa estado falso (false), si el mensaje es demasiado largo. ( > VW_MAX_PAYLOAD).

vw_have_message extern uint8_t vw_have_message(); Se regresa estado de verdadero (true), si un mensaje no se a leído desde el receptor.

vw_get_message extern uint8_t vw_get_message(uint8_t* buf, uint8_t* len);Si un mensaje está disponible (tenga o no buen checksum), se copia a: *len los octetos al buf. Regresa estado de verdadero (true), si hubo mensaje y el checksum es correcto.

26 Anexo

Page 25: MCRF-VW

Bibliografía

Banzi, Massimo, Getting Started with Arduino. 2008, O !Reilly, USA.

García, Bernal. S. Arduino Diseño y Aplicaciones. 2009, México.

Internet: Arduino Reference, http://arduino.cc/en/Reference/Extended

Internet: Processing Reference, http://processing.org/reference/

Page 26: MCRF-VW
Page 27: MCRF-VW
Page 28: MCRF-VW

Salvador García Bernal© 2009