Conexión inalámbrica entre dos Microcontroladores

Conexión inalámbrica entre dos microcontroladores PIC utilizando los transceptores nR24L01

MICROCONTROLADORES

Biblioman

10/17/20116 min read

En esta ocasión vamos a ver que establecer una comunicación inalámbrica entre dos (o más) Microcontroladores no es una tarea ni mucho menos difícil. El hardware que vamos a utilizar en esta Demo se compone de los siguientes elementos: dos transceptores basados en el integrado nRF24L01 de la empresa Nordic Semiconductor, dos Microcontroladores PIC de la familia PIC16FXXX y una fuente de alimentación con salidas de 5 y 3,3V.

Características transceptores nRF24L01

  • Rango de radiofrecuencia en la cual trabaja (2.4 – 2.5 GHz), antena integrada en la placa.

  • Comunicación SPI. (Max. Velocidad 8Mhz).

  • 128 canales de transmisión seleccionables por el bus SPI.

  • Implementación capas OSI por hardware.

  • Tensión de alimentación (1.9 a 3.6 V).

  • Máxima velocidad de transferencia en radiofrecuencia 2Mbps.

  • Pines de entrada con tolerancia a 5V (Niveles TTL).

Descripción de la demo

El ejemplo consiste en transmitir vía radio el estado del puerto D de un PIC (16F877) que hace las funciones de PIC transmisor, dicho puerto será configurado como entrada y en sus pines conectaremos unos micro-interruptores para poder variar manualmente el valor de la entrada, el estado del puerto será leído cada segundo y su valor será enviado al módulo transceptor conectado a él y configurado como transmisor a través del puerto SPI, los datos serán recibidos por otro transceptor el cual los enviará al PIC receptor (otro PIC 16F877) que mostrará su valor en el puerto D configurado esta vez como salida y conectado a un Array de leds para que se pueda ver visualmente su valor.

Esquema conexión transceptores:

Código fuente:

El ejemplo utiliza la librería lib_rf2gh4_10.h desarrollada por la empresa Bizintek. y utilizada en su proyecto del robot mOway es fácil de utilizar, está bien documentada y además es Open Source por lo que se puede distribuir y/o modificar bajo los términos de la licencia GNU.

Transmisor:

/////////////////////////////////////////////////////////////////////////////////////

// Ejemplo Módulos transceptores NRF24L01 basado en la //

// librería lib_rf2gh4_10.h //

// Modulo transmisor //

// Autor: Biblioman //

// Web: www.aquihayapuntes.com //

/////////////////////////////////////////////////////////////////////////////////////

#include <16F877.h>

#device ICD=TRUE

#FUSES NOWDT

#FUSES XT

#FUSES PUT

#FUSES NOPROTECT

#FUSES NODEBUG

#FUSES NOBROWNOUT

#FUSES NOLVP

#FUSES NOCPD

#FUSES NOWRT

#use delay(clock=4000000)

#include "lib_rf2gh4_10.h"

//Mapeado de registros

#BYTE PORTD=0X08

//Variables auxiliares para el programa principal

int8 ret;

//Programa principal

void main()

{

//Configurar módulos SPI del PIC

RF_CONFIG_SPI();

//Configurar módulo RF (canal y dirección)

RF_CONFIG(0x40,0x01);

//Activación módulo RF

RF_ON();

//------------------------------------------------------------------------------

while(true){

Delay_ms(1000);

//-------------------------[Rutina de envio de datos]---------------------------

//Preparación de la dirección del receptor y de los datos

RF_DIR=0x08;

RF_DATA[0]=PORTD;

//Envio de los datos

ret=RF_SEND();

//sentencias de chequeo

if(ret==0){

//Envio realizado y ACK recibido

}

else if(ret==1){

//Envio realizado y ACK no recibido

}

else{

//Envio no realizado

}

//------------------------------------------------------------------------------

}

}

Receptor:

/////////////////////////////////////////////////////////////////////////////////////

// Ejemplo Módulos transceptores NRF24L01 basado en la //

// librería lib_rf2gh4_10.h //

// Modulo Receptor //

// Autor: Biblioman //

// Web: www.aquihayapuntes.com //

/////////////////////////////////////////////////////////////////////////////////////

#include <16F877.h>

#device ICD=TRUE

#FUSES NOWDT

#FUSES XT

#FUSES PUT

#FUSES NOPROTECT

#FUSES NODEBUG

#FUSES NOBROWNOUT

#FUSES NOLVP

#FUSES NOCPD

#FUSES NOWRT

#use delay(clock=4000000)

#include "lib_rf2gh4_10.h"

//Mapeo de registros

#BYTE PORTD=0x08

//Variables auxiliares para el programa principal

int8 ret;

//--------------[Rutina de recepción con interrupcion]--------------------------

//Interrupción del módulo RF

#int_ext

void int_externo() {

//Recepcion de los datos

ret = RF_RECEIVE();

if (ret == 0) //recepción única

{

//tratar datos

PORTD=RF_DATA[0];

}

}

//Programa principal

void main()

{

//Configuración Puerto D

set_tris_d (0x00);

PORTD=0;

//-----------[Rutina de configuración y activación con interrupción]------------

//Habilitar interrupciones

RF_INT_EN();

//Configurar módulos SPI del PIC

RF_CONFIG_SPI();

//Configurar módulo RF (canal y dirección)

RF_CONFIG(0x40,0x08);

//Activar el módulo RF

RF_ON();

//------------------------------------------------------------------------------

//Bucle infinito. Espera hasta que se produce la interrupción

while(true);

}

Comentario:

Con respecto al circuito hay que tener muy en cuenta que aunque los pines de entrada de los transceptores son tolerantes a 5V su alimentación es de 3.3 V. Con respecto al software, lo que hace cada función está bastante bien explicado en la documentación que se adjunta con la librería. La comunicación entre el PIC y los módulos transceptores se hace a través del protocolo SPI por lo que el PIC que elijamos debe disponer de un puerto SPI dentro de sus recursos Hardware, hay un hilo en el foro con un ejemplo que trata sobre la comunicación SPI entre varios microcontroladores, podéis acceder a él desde aquí.

Con respecto a la comunicación de radiofrecuencia los transceptores disponen de 128 canales trabajando en el margen de frecuencia de 2.4 a 2.5GHz. Para participar en una misma comunicación los dispositivos deben de tener asignado el mismo canal y la dirección de cada dispositivo debe de ser única dentro del mismo. En el ejemplo se utiliza el canal 40, al transmisor se le asigna la dirección 0x01 y al receptor la 0x08. Cada vez que queramos enviar un dato hay que asignarle a la variable RF_DIR la dirección del dispositivo al que queremos enviarle los datos, los datos a enviar o recibir se guardan en el array RF_DATA[8] de 8 bytes, en el ejemplo solo se utilizará un byte para guardar el estado del puerto D por lo que solo utilizaremos el primer elemento del Array (RF_DATA[0]). El nRF24L01 dispone de un pin de interrupción activo a nivel bajo que podemos utilizar para comprobar la recepción de datos, para ello utilizaremos en el PIC la interrupción externa por RB0 previamente hay que incluir en la función principal del receptor la llamada a la función RF_INT_EN() que se encarga de configurar los registros de interrupción. Una vez recibido un dato (1 byte) o una trama formada por varios Bytes (max. 8) la función RF_RECEIVE() se encargará de guardar los datos en el array RF_DATA luego solo nos queda tratar esos datos, en el caso del ejemplo le asignamos el valor de esa variable al puerto D configurado previamente como salida y que tiene conectado en sus pines un array de leds para ver visualmente su valor. Otra cosa muy útil y que se me olvidaba comentar es que la función de envío de datos RF_SEND() admite ACK para el control de los datos enviados, con ello podemos saber si no nos funcionan los módulos si el problema lo tenemos en el transmisor o en el receptor. La función RF_SEND() devuelve tres valores distintos en función de cómo se ha realizado el envío:

  • Un 0 si el envío se ha realizado correctamente y se ha recibido el ACK.

  • Un 1 si los datos se han enviado pero no se ha recibido el ACK.

  • Un 2 si se ha producido algún error y no se ha podido realizar el envío.

De igual forma la función RF_RECEIVE() también devuelve tres valores:

  • Un 0 si solo se ha recibido un byte y no hay más datos en la pila de recepción.

  • Un 1 si se ha recibido una trama de datos. En este caso se debe de crear un bucle que llame a la función RF_RECEIVE() mientras queden datos en la pila de recepción.

  • Un 2 si los datos no se han recibido correctamente.


En el caso de nuestro ejemplo si se reciben datos serán solo de un byte por tanto solo se chequea la primera opción.

La librería también permite la recepción de datos sin el uso de interrupciones la explicación de cómo hacerlo viene incluida también en la documentación de la librería, así como las precauciones que hay que tener para evitar interferencias entre canales.

Aquí tenéis un vídeo de la Demo funcionando.

Descargas

Podéis descargar la librería lib_rf2gh4_10.h + Manual librería + ejemplos + versión del artículo en .pdf desde aquí.

Fuentes de información

http://www.moway-robot.com/index.php
http://blog.diyembedded.com/
http://www.ccsinfo.com/

El
hacer este artículo lleva su tiempo el comentarlo apenas unos minutos, si te ha sido de utilidad danos tú opinión. Nos vemos en el foro!!.

Un saludo y hasta la próxima...