bclose

Los módulos de radio NRF2401

Usando radios para comunicar nuestros Arduinos

Objetivos

.

 
    • Presentar los módulos de radio NRF2401.
    • Describir la forma de conectarlos a nuestros Arduinos o similares.
    • Presentar un par de programas sencillos que nos permitan usarlos en nuestros proyectos para enviar y recibir órdenes o datos.
    • En este primer ejemplo de programa la comunicación será unidireccional..
 

 

Material requerido.

 

Imagen de Arduino UNO  Arduino UNO o equivalente.
Transceptor de radio  Un par de módulos de radio NRF2401,
conexiones  Algunos cables de protoboard, preferiblemente Dupont macho/hembra más una protoboard
tienda online prometec

Las conexiones de radio

 

Hemos visto en anteriores sesiones, que poder usar conexiones inalámbricas nos ofrece unas posibilidades a las que resulta difícil renunciar cuando te acostumbras, y hemos hecho pruebas de conexiones tanto WIFI como Bluetooth.

Las WIFI nos permiten conectarnos a Internet con facilidad y podemos publicar páginas Web con valores de nuestros sensores y Arduinos o simplemente acceder a estos Duinos y pasarles parámetros u órdenes. EL BlueTooth es ideal si queremos controlar nuestros Arduinos sin más controlador que un móvil que ya llevamos habitualmente en el bolsillo.

Pero tanto el BT como el WIFI tienen unas limitaciones considerables en lo que se refiere a la distancia a la que podemos usarlo. No pasa más allá de 20 metros y eso en condiciones óptimas, pero no es raro que necesitemos más distancia, digamos 50 m, 0 200 m, y porque no un kilómetro.

Como siempre, cuando hay una necesidad en el mercado, surge alguien dispuesto a ofrecer una solución en forma de electrónica, y en esta ocasión vamos a presentar una solución magnifica para el tipo de problema que planteamos. Un medio de dar órdenes a un Arduino o similar, a una distancia que puede variar entre 50 metros y hasta digamos un kilómetro.

En esta sesión vamos a presentar y dar los primeros pasos con unos magníficos dispositivos de radio basados en el chip de Nordic semiconductor  NRF24, y que podemos encontrar en multitud de módulos de diferentes fabricantes, compatibles entre sí, por muy poco dinero, que es lo que nos gusta en esta casa.

Este dispositivo NRF2401, integra en un único chip, toda la electrónica y bloques funcionales precisos, para establecer comunicaciones RF (Radio Frecuencia) entre dos o más puntos a diferentes velocidades, (Hasta 2  Mb/seg) con corrección de errores y protocolo de reenvió cuando es necesario, sin intervención del control externo, lo que nos permite aislarnos de tobo el trabajo sucio y complicado relacionado con la transmisión física.

Las características más destacadas son:

 
  • Muy baratos, unos pocos dólares.
  • Operan en la banda de 2.4Ghz, que es de libre uso a nivel mundial.
  • Velocidad configurable de 250kb, 1 Mb o 2Mb por segundo.
  • Muy bajo consumo en Stand By (Cuando no se usan).
  • El alcance depende de si hay visión directa entre los nodos, o por el contrario hay obstáculos, pero nos ofrece un mínimo de unos 20 m hasta un máximo e 80m en óptimas circunstancias, en el modelo básico con la antena integrada.
  • Podemos encontrar modelos con antenas más eficaces por un coste un poco superior (no mucho no os asustéis) que aumentan de forma importante el alcance hasta casi un km.
  • Si no queremos complicarnos la vida son muy fáciles de usar y configurar y además son los enlaces más baratos que podemos encontrar para vincular nuestros Arduinos.
  • Compatibles con todo un rango de modelos de diferentes tipos y fabricantes.
 

 

Las ondas de radio

 

A finales del siglo XIX, James C. Maxwell estableció las leyes del electromagnetismo que describen la propagación de las ondas electromagnéticas y la relación que existe entre los campos magnéticos y la electricidad (de ahí el nombre) estableciendo una de las teorías básicas que regulan el funcionamiento del mundo moderno.

Todas la ubicuas emisiones de RF que nos rodean actualmente, fueron descritas por Maxwell y sus ecuaciones hace ya más de 100 años, y eso incluye las emisiones de radio en AM y FM, las de televisiones, tanto analógicas como digitales, la conexión de tu teléfono móvil y hasta las conexiones WIFI y Bluetooth de las que hemos hablado previamente.

Las primeras emisiones de radio viables se atribuyen  en 1901 Guillermo Marconi y son el precedente de toda la tecnología de radio actual apoyándose en los trabajos de Maxwell y Heinrich Hertz de quien deriva la unidad de medida de la frecuencia Hercios en español (Hertz en inglés)

 
  • La descripción de una onda de RF se realiza por su frecuencia, en Hercios, que indica el número de pulsos por segundo a los que bate la señal, y por su amplitud que indica la intensidad.
 

Ya hemos hablado antes del espectro de frecuencia y vamos a destacar que en la práctica llamamos RF a las señales de frecuencia inferior a los 300Ghz

Reparto por finalidad

Como podéis ver, el espectro de radiofrecuencias parece el camarote de los hermanos Marx, con los servicios de radio, TV, telefonía y demás por lo que es importante que los dispositivos que usemos emitan en el rango de frecuencias libres, es decir, en las que se permite que cualquiera emita y reciba, sin interferir con la operación normal de emisiones que operan los servicios sometidos a regulación.

Nuestros humildes módulos NRF2401 emiten a 2.4 GHz, lo que es banda libre y no requieren de ningún permiso para usarse en ninguna parte del mundo (Por mucho que os quieran meter miedo con esto). Pero a cambio, no tenemos garantía de que no haya alguien más emitiendo en esta banda en las cercanías, lo que puede producir interferencias con nuestra emisiones.

 
  • Cuando sintonizas tu emisora FM en el dial, digamos 103.4, es porque la emisora paga a la administración para ser la única que pueda emitir legalmente en esa frecuencia y de ese modo impida la interferencia de otros servicios comerciales.
  • Por eso el espectro de radiofrecuencias está sometido a un estricto control administrativo, en todos los países,  para evitar que señales en competencia interfieran entre si anulando la posibilidad de transmitir información valida.
 

 

Diagrama de conexión de un módulo NRF2401

 

Estos módulos usan el bus SPI para acelerar la conexión con el micro controlador por lo que vamos a ver la descripción de los pines necesarios para su conexión, en vista superior:

Descripcion de pines para el NRF2401

Hay dos librerías básicas para el manejo de los NRF2401s en Arduino, la NRF24 que es la que vamos a usar aquí (Porque me parece más sencilla) y la librería MIRF.

PIN NRF2401 Arduino UNO MEGA
GND 1 GND GND
VCC 2 3.3 3.3
CE 3 9  9
CSN 4 10  53
SCK 5 13 52
MOSI 6 11 51
MISO 7 12 50
IRQ 8 2  –
 
  • Es importante recalcar que estos módulos funcionan a 3.3V; EL fabricante previene contra conectarles a 5V so pena de achicharrarlos.
  • La librería MIRF espera que hagas unas conexiones de pines diferentes, así que no te conviene usar este diagrama de conexión si pretendes utilizarla.
  • Tenéis que comprender que los modelos UNO y MEGA usan diferentes pines para el control del bus SPI y luego para rematar la faena, según la librería cambian de nuevo.
 

Vamos con el esquema de conexión de protoboard:

Diagrama de protoboard

Para poder emitir y recibir con estos módulos vamos a necesitar dos Arduinos configurados con estas conexiones a los que llamaremos emisor y receptor, porque inicialmente los programas van a ser distintos.

Empezaremos haciendo la prueba más sencilla posible. Uno de ellos, el emisor, radia una serie de números y el otro, el receptor, los recibe y muestra en la consola serie.

 
  • Aunque estos módulos consumen muy poco en uso o en Stand by, pueden absorber en el arranque más de lo que la fuente de 3.3V de Arduino puede proporcionar, lo que impide que arranque correctamente o que tenga un funcionamiento errático, especialmente en el caso del emisor.
  • Si buceáis en Internet, veréis cantidad de páginas recomendándoos usar unos condensadores entre los pines tal y cual.
  • Aunque tomar precauciones nunca sobra, los vagos somos incapaces de hacer algo así, mientras no se demuestre que es imprescindible.
  • En mi caso he comprobado que la manera más sencilla de evitar problemas (Que los he tenido) ha sido asegurarme de que el emisor tiene una alimentación correcta y abundante, mediante un alimentador externo de los típicos. Esta sencilla precaución ha hecho que en mi caso los problemas se reduzcan hasta desaparecer.

Power supply 

 

Programando las radios

 

Vamos a montar un primer ejemplo en el que crearemos dos programas diferentes que corren en dos Arduino diferentes. El primero será el programa emisor, que radiará números en secuencia desde 0 hasta el 255, y el segundo el programa receptor, que nos permitirá comunicarnos en una única dirección inicialmente.

Vamos con el programa emisor y para ello necesitamos la librería RF24-master, cuya última versión siempre podéis encontrar en https://github.com/maniacbug/RF24. Empezamos con unos cuantos includes, necesarios para el NRF2401 y para el bus SPI:

#include <nRF24L01.h>
#include <RF24.h>
#include <RF24_config.h>
#include <SPI.h>

Después tenemos que crear una instancia de la radio, indicándole los pins de control, y la siguiente línea indica el pipe a utilizar, que podemos imaginar como uno de los diferentes canales en los que la radio puede operar.

RF24 radio(9,10);
const uint64_t pipe = 0xE8E8F0F0E1LL;
 
  • El pipe es un numero de 64 bits, lo que indicamos con el tipo uint64_t , entero sin signo de 64 bits, y por si no estuviera suficientemente claro, le indicamos al compilador que se trata de un LL al final del número, o sea LongLong = 64 bits.
 

Y ahora basta con inicializarla en el setup:

void setup(void)
   {   Serial.begin(9600);
       radio.begin();
       radio.openWritingPipe(pipe);
    }

En el programa principal, simplemente vamos incrementando una variable para luego transmitirla por la radio

int msg[1] ;

void loop(void)
  {  for (int x=0;x<2255;x++)
       {  msg[0] = x ;
          radio.write(msg, 1);
       }
   }

Aqui os dejo el programa completo Prog_79_1_Emisor

En cuanto al programa receptor Prog_79_1_Receptor, tenemos que empezar incluyendo las mismas librerías, y un array mínimo para el entero a recibir, e instanciamos la radio como radio

#include <nRF24L01.h>
#include <RF24.h>
#include <RF24_config.h>
#include <SPI.h>

RF24 radio(9,10);
const uint64_t pipe = 0xE8E8F0F0E1LL;
int msg[1];

El setup es casi el mismo.

void setup(void)
   {  Serial.begin(9600); 
      radio.begin();
      radio.openReadingPipe(1,pipe);
      radio.startListening();
   }

Pero en vez de usar radio radio.openWritingPipe(pipe) para escribir, usamos radio.openReadingPipe(1,pipe) para poder leer y después radio.startListening() nos permite comenzar la escucha. Y ya solo falta el setup con el programa que recibe:

void loop(void)
   {   if (radio.available())
          {   int done = radio.read(msg, 1);
              Serial.println(msg[0]);
          }
   }

Se nos ha vuelto a perder la parte difícil, porque no me digáis que no es sencillo y elegante. El tema no da para más.  Si corréis los programas en Arduinos diferentes, la salida del receptor debería ser algo así:

Listado de numeros

Programa por el que no ganaremos ningún premio, pero que ilustra a la perfección como emitir datos numéricos uno a uno entre emisor y receptor mediante radio frecuencia. Si habéis llegado hasta aquí, enhorabuena acabáis de emitir por radio, vuestro primer mensaje.

Bueno, está bien. Enviar un carácter esta chupado, pero ¿Que pasa si hay que enviar un String completo, seguro que la cosa se complica?

Pues sí. Para enviar un mensaje de texto tenemos que cambiar un par de cosas. Primero definir un array de char suficiente para que quepa el mensaje:

char msg[16]="Prometec.net.\n" ;

Y después cambiar el loop para que envié los 16 caracteres

void loop(void)
   {  
       radio.write(msg, 16);
   }

Y por supuesto hay que cambiar el programa del receptor

void loop(void)
   {   if (radio.available())
           {   int done = radio.read(msg, 16);
               Serial.println(msg);
           }
   }

Basta con llamar a radio.write o radio.read con el array como parámetro y pasarle el número de caracteres que queremos enviar o recibir. Aquí tenéis el emisor y el receptor modificados.

Emisor_String

Receptor_String

He visto en Internet un programa que me encantó, porque lo que hace es colocar un LED rojo y uno Verde en los pines 3 y 5 de Arduino y después emite números entre 0 y 255 en el emisor mientras en el receptor corre un programa que controla que los números se reciban en el orden adecuado.

Cuando es así, ilumina brevemente la luz verde, en caso contrario la roja. Lo bueno de esto es que os sirve como ejemplo de si tenéis una buena recepción o no, ya que según el baile de los LEDs tenéis una idea bastante aproximada de los errores de trasmisión que tenéis en vuestra zona.

Usad el programa Prog_79_1_Emisor para el emisor y este programa en el receptor Prog_79_4.

 

Resumen de la sesión

.

 
    • Presentamos las unidades de radio NRF2401, que son ideales para muchos proyectos, porque son buenas, bonitas y baratas.
    • Vimos como conectarlas a nuestros Arduinos con confianza usando el SPI y un par de pines.
    • Descargamos y usamos la librería RF24 para el manejo de las radios y vimos los comandos básicos para enviar y recibir.
    • Hicimos un montaje de prueba con una comunicación en una única dirección.
 

 

 

 

(195) Comments

  • Hola!
    Como siempre gracias por los tutoriales. Son de mucha ayuda. Aún así tengo un par de consultas de los sketch anteriores: en el primero de ellos se dice que vamos a radiar del 0 al 255; sin embargo el sketch indica 2255. Al principio creí que podía ser una errata, pero funciona enviando los números del 0 a 255?!?! alguien puede indicar por qué no va hasta el 2255?
    La segunda consulta es respecto del “receptor string”: qué función tiene el “int done”? por qué no tiene que ser un “char”? en qué momento se almacena el valor de “msg” para que pueda imprimirse por Serial?
    Un millón de gracias por vuestras respuestas. Saludos!

  • Hola. Tanto el arduino mega como el uno y el nano tienen puerto ICSP. Por que no conectar ahí el módulo nrf2401 ?? No es para esto?

    • Efectivamente puedes usar los pines de ahí que necesites.

  • Los #include son mismo del ejemplo, PROGRAMANDO LOS RADIOS.

  • Gracias por tu respuesta…. te enviare el programa y al compilar en la instruccion ” bool done = radio.read(datos, 3);”, presenta lo siguiente:

    if ( radio.available() )
    {
    //Leemos los datos y los guardamos en la variable datos[]
    bool done = radio.read(datos, 3);

    //reportamos por el puerto serial los datos recibidos
    Serial.print(“Dato0= ” );
    Serial.print(datos[0]);

    exit status 1
    void value not ignored as it ought to be

    envio programas >>>>>
    EMISOR

    // EMISOR

    #include
    #include
    #include
    #include

    RF24 radio(9, 10);
    const uint64_t pipe = 0xE8E8F0F0E1LL;

    //vector con los datos a enviar
    float datos[3];

    void setup()
    {
    //inicializamos el puerto serie
    Serial.begin(9600);

    //inicializamos el NRF24L01
    radio.begin();// Basically turn on communications with the device

    //Abrimos el canal de Lectura
    radio.openWritingPipe(pipe);//Set up the two way communications with the named device

    }
    void loop()
    {

    datos[0] = 1; //le puse valores fijos para asegurarme que funcionara
    datos[1] = 2;
    datos[2] = 3;

    //reportamos por el puerto serial los datos enviados
    radio.write(datos, 3);
    Serial.print(“Datos enviados: “);
    Serial.print(datos[0]);
    Serial.print(” , “);
    Serial.print(datos[1]);
    Serial.print(” , “);
    Serial.println(datos[2]);
    delay(1000);
    }
    —————————————
    RECEPTOR

    //RECEPTOR

    #include
    #include
    #include
    #include

    RF24 radio(9, 10);
    const uint64_t pipe = 0xE8E8F0F0E1LL;

    //vector para los datos recibidos
    float datos[3];

    void setup()
    {
    //inicializamos el puerto serie
    Serial.begin(9600);

    //inicializamos el NRF24L01
    radio.begin();

    //Abrimos el canal de Lectura
    radio.openReadingPipe(1, pipe);

    //empezamos a escuchar por el canal
    radio.startListening();//Give the module a kick
    }
    void loop()
    {
    uint64_t pipe;
    // if ( radio.available() )
    if ( radio.available() )
    {
    //Leemos los datos y los guardamos en la variable datos[]
    bool done = radio.read(datos, 3);

    //reportamos por el puerto serial los datos recibidos
    Serial.print(“Dato0= ” );
    Serial.print(datos[0]);
    Serial.print(” V, “);
    Serial.print(“Dato1= ” );
    Serial.print(datos[1]);
    Serial.print(” ms, “);
    Serial.print(“Dato2= ” );
    Serial.println(datos[2]);
    }
    else
    {
    Serial.println(“No hay datos de radio disponibles”);
    }
    delay(1000);
    }

    SALUDOS A TODOS …….CUALQUIER COMENTARIO SERA PROVECHOSO PARA TODA LA COMUNIDAD DE PERSONAS QUE USAN ARDUINO. GRACIAS.

Give a Reply

WordPress Anti-Spam by WP-SpamShield