Guía NRF24L01+ (Librería)

Luego de llevar varios días luchando con este módulo, he decido hacer una guía para poder entender mejor el funcionamiento de las librerías disponibles, y hablo en plural, porque la mayoría de ellas funcionan de la misma manera, en este caso yo estoy trabajando con Arduino y Raspberry, pero en ambos casos son las mismas funciones.

CONEXIÓN

Los pines de conexión de este módulo, en su versión con antena y sin antena, son los mismos.
Imagen con el nombre de cada pin:

Para conectarlo a un dispositivo se debe conocer los pines SPI, aquí usaré los del Arduino UNO:

Debería quedar algo así

LIBRERÍAS

Gracias a la mención de surbyte de la librería TMRh20 decidí probarla como me gustaron sus prestaciones y su facilidad, utilizaré esta librería, que en verdad son 3.

Se deben instalar las 3 para usar la librería "mesh"

1. GitHub - nRF24/RF24: OSI Layer 2 driver for nRF24L01 on Arduino & Raspberry Pi/Linux Devices
Con las funciones básica del módulo

2. GitHub - nRF24/RF24Network: OSI Layer 3 Networking for nRF24L01(+) Radios on Arduino and Raspberry Pi
Permite crear un red utilizando el protocolo TCP/IP

3. GitHub - nRF24/RF24Mesh: OSI Layer 7 Mesh Networking for RF24Network & nrf24L01+ devices (Usaremos los ejemplos de esta librería)
Permite realizar una red de una manera más amigable

Es necesario descargar e instalar las 3 librerías anteriores para seguir los ejemplos.

USO

Una vez instaladas, explicaré rápidamente el funcionamiento de los tres ejemplos principales de la librería MESH que usaremos en esta ocasión (Archivo->Ejemplos->RF24Mesh)

- RF24Mesh_Example_Master.ino
Este archivo permite dejar un dispositivo con el módulo NRF24L01 como máster o servidor.

Lo único que se debe configurar son los pines CE y SCN si es que los tienes algún pin diferente al 7 y 8

RF24 radio(7,8);

setNodeID debe ser "0" para que el módulo sea el máster

mesh.setNodeID(0);

[Opcional] Existe una opción llamada setStaticAddress permite definir una dirección estática a un ID específico, como cuando configuras una IP específica en tu router con la MAC de la tarjeta de red.

  mesh.setStaticAddress(23, 02);
  mesh.setStaticAddress(24, 03);

RF24Mesh_Example.ino
Este código será utilizado por los nodos que se conecten al máster

Se verifica nuevamente los pines de conexión

RF24 radio(7,8);

Y ahora habrá que definir el ID que quieres designar a ese nodo especifico.

#define nodeID 1

Como los ejemplos son fáciles de seguir, sólo daré una explicación básica del resto de los ejemplos
RF24Mesh_Example_Master_to_Nodes.ino
Envía información desde el módulo máster a un nodo específico

RF24Mesh_Example_Node2Node.ino
Envía información desde un nodo a otro nodo (sin un master)

Una vez que configuras un Arduino como máster y uno como nodo automáticamente comienzan a comunicarse.
Cualquier información extra la iré agregando.

si te agradeceria que explicaras mejor, y con ejemplos, estuve viendo en youtube y usan la libreria Mirf y a mi parecer es mucho mas sencilla que esta libreria que usas, o no se cuando usar cada una, he visto q la q estas usando es la RF24-master, hay otra que es la Mirf, si pudieras hacer un ejemplo de un led que se prenda y apage con un pulsador, obvio con los 2 nodos, gracias por la info

Este fin de semana o comenzando la otra corregiré el post, aunque yo estoy trabajando con la RF24, no he usado Mirf.

Haré un ejemplo simple y otro con un Led.

gepd:
Este fin de semana o comenzando la otra corregiré el post, aunque yo estoy trabajando con la RF24, no he usado Mirf.

Haré un ejemplo simple y otro con un Led.

Vale, y si sabes las diferencias entre las 2 librerias, esa q usas y la Mirf o cual es la ventaja de cada una, es que quiero construir una red de sensores, y no se de tantas librerías que hay, cual es la que mas me sirve.

Yo uso la misma libreria, no e usado nunca Mirf, y no es tan compleja como parece, hay una pagina en ingles donde pone el ejemplo de un joystick va enlace https://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo

Personalmente la librería de Tmrh20 supera la de maniac, de hecho es una mejora de esta.

Recomiendo su uso, yo comencé con maniac y luego descubrí esta librería y para mi es la mejor.
Aunque todo lo expuesto por Maxid se aplica ya que es una evolución de Maniac, existen algunas diferencias menores.

nikolandia_3d:
Yo uso la misma libreria, no e usado nunca Mirf, y no es tan compleja como parece, hay una pagina en ingles donde pone el ejemplo de un joystick va enlace https://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo

si eso me di cuenta, tambien me habia fijado de esa pagina, explican todo muy bien, entendi todos los pasos a la perfeccion.

stazlad:
si te agradeceria que explicaras mejor, y con ejemplos, estuve viendo en youtube y usan la libreria Mirf y a mi parecer es mucho mas sencilla que esta libreria que usas, o no se cuando usar cada una, he visto q la q estas usando es la RF24-master, hay otra que es la Mirf, si pudieras hacer un ejemplo de un led que se prenda y apage con un pulsador, obvio con los 2 nodos, gracias por la info

en la misma libreria hay un ejemplo de lo que pedis:

/*
 Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 version 2 as published by the Free Software Foundation.
 */

/**
 * Example LED Remote
 *
 * This is an example of how to use the RF24 class to control a remote
 * bank of LED's using buttons on a remote control.
 *
 * On the 'remote', connect any number of buttons or switches from
 * an arduino pin to ground.  Update 'button_pins' to reflect the
 * pins used.
 *
 * On the 'led' board, connect the same number of LED's from an
 * arduino pin to a resistor to ground.  Update 'led_pins' to reflect
 * the pins used.  Also connect a separate pin to ground and change
 * the 'role_pin'.  This tells the sketch it's running on the LED board.
 *
 * Every time the buttons change on the remote, the entire state of
 * buttons is send to the led board, which displays the state.
 */

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"

//
// Hardware configuration
//

// Set up nRF24L01 radio on SPI bus plus pins 9 & 10

RF24 radio(9,10);

// sets the role of this unit in hardware.  Connect to GND to be the 'led' board receiver
// Leave open to be the 'remote' transmitter
const int role_pin = A4;

// Pins on the remote for buttons
const uint8_t button_pins[] = { 2,3,4,5,6,7 };
const uint8_t num_button_pins = sizeof(button_pins);

// Pins on the LED board for LED's
const uint8_t led_pins[] = { 2,3,4,5,6,7 };
const uint8_t num_led_pins = sizeof(led_pins);

//
// Topology
//

// Single radio pipe address for the 2 nodes to communicate.
const uint64_t pipe = 0xE8E8F0F0E1LL;

//
// Role management
//
// Set up role.  This sketch uses the same software for all the nodes in this
// system.  Doing so greatly simplifies testing.  The hardware itself specifies
// which node it is.
//
// This is done through the role_pin
//

// The various roles supported by this sketch
typedef enum { role_remote = 1, role_led } role_e;

// The debug-friendly names of those roles
const char* role_friendly_name[] = { "invalid", "Remote", "LED Board"};

// The role of the current running sketch
role_e role;

//
// Payload
//

uint8_t button_states[num_button_pins];
uint8_t led_states[num_led_pins];

//
// Setup
//

void setup(void)
{
  //
  // Role
  //

  // set up the role pin
  pinMode(role_pin, INPUT);
  digitalWrite(role_pin,HIGH);
  delay(20); // Just to get a solid reading on the role pin

  // read the address pin, establish our role
  if ( digitalRead(role_pin) )
    role = role_remote;
  else
    role = role_led;

  //
  // Print preamble
  //

  Serial.begin(57600);
  printf_begin();
  printf("\n\rRF24/examples/led_remote/\n\r");
  printf("ROLE: %s\n\r",role_friendly_name[role]);

  //
  // Setup and configure rf radio
  //

  radio.begin();

  //
  // Open pipes to other nodes for communication
  //

  // This simple sketch opens a single pipes for these two nodes to communicate
  // back and forth.  One listens on it, the other talks to it.

  if ( role == role_remote )
  {
    radio.openWritingPipe(pipe);
  }
  else
  {
    radio.openReadingPipe(1,pipe);
  }

  //
  // Start listening
  //

  if ( role == role_led )
    radio.startListening();

  //
  // Dump the configuration of the rf unit for debugging
  //

  radio.printDetails();

  //
  // Set up buttons / LED's
  //

  // Set pull-up resistors for all buttons
  if ( role == role_remote )
  {
    int i = num_button_pins;
    while(i--)
    {
      pinMode(button_pins[i],INPUT);
      digitalWrite(button_pins[i],HIGH);
    }
  }

  // Turn LED's ON until we start getting keys
  if ( role == role_led )
  {
    int i = num_led_pins;
    while(i--)
    {
      pinMode(led_pins[i],OUTPUT);
      led_states[i] = HIGH;
      digitalWrite(led_pins[i],led_states[i]);
    }
  }

}

//
// Loop
//

void loop(void)
{
  //
  // Remote role.  If the state of any button has changed, send the whole state of
  // all buttons.
  //

  if ( role == role_remote )
  {
    // Get the current state of buttons, and
    // Test if the current state is different from the last state we sent
    int i = num_button_pins;
    bool different = false;
    while(i--)
    {
      uint8_t state = ! digitalRead(button_pins[i]);
      if ( state != button_states[i] )
      {
        different = true;
        button_states[i] = state;
      }
    }

    // Send the state of the buttons to the LED board
    if ( different )
    {
      printf("Now sending...");
      bool ok = radio.write( button_states, num_button_pins );
      if (ok)
        printf("ok\n\r");
      else
        printf("failed\n\r");
    }

    // Try again in a short while
    delay(20);
  }

  //
  // LED role.  Receive the state of all buttons, and reflect that in the LEDs
  //

  if ( role == role_led )
  {
    // if there is data ready
    if ( radio.available() )
    {
      // Dump the payloads until we've gotten everything
      bool done = false;
      while (!done)
      {
        // Fetch the payload, and see if this was the last one.
        done = radio.read( button_states, num_button_pins );

        // Spew it
        printf("Got buttons\n\r");

        // For each button, if the button now on, then toggle the LED
        int i = num_led_pins;
        while(i--)
        {
          if ( button_states[i] )
          {
            led_states[i] ^= HIGH;
            digitalWrite(led_pins[i],led_states[i]);
          }
        }
      }
    }
  }
}

2,3,4,5,6,7 son los pines en lo que pones leds/botones segun el rol

el rol lo cambias con la entrada A4 si la pones a GND es el de los led, si la dejas abierta es el transmisor con los botones

en la carpeta de la librería hay ejemplos mas complejos, si hay algo que no entiendas pregunta!!

surbyte:
Personalmente la librería de Tmrh20 supera la de maniac, de hecho es una mejora de esta.

Recomiendo su uso, yo comencé con maniac y luego descubrí esta librería y para mi es la mejor.
Aunque todo lo expuesto por Maxid se aplica ya que es una evolución de Maniac, existen algunas diferencias menores.

Voy a probarla a ver que tal

saludos!!

nikolandia_3d:
en la misma libreria hay un ejemplo de lo que pedis:

/*

Copyright (C) 2011 J. Coliz maniacbug@ymail.com

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
*/

/**

  • Example LED Remote
  • This is an example of how to use the RF24 class to control a remote
  • bank of LED's using buttons on a remote control.
  • On the 'remote', connect any number of buttons or switches from
  • an arduino pin to ground.  Update 'button_pins' to reflect the
  • pins used.
  • On the 'led' board, connect the same number of LED's from an
  • arduino pin to a resistor to ground.  Update 'led_pins' to reflect
  • the pins used.  Also connect a separate pin to ground and change
  • the 'role_pin'.  This tells the sketch it's running on the LED board.
  • Every time the buttons change on the remote, the entire state of
  • buttons is send to the led board, which displays the state.
    */

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"

//
// Hardware configuration
//

// Set up nRF24L01 radio on SPI bus plus pins 9 & 10

RF24 radio(9,10);

// sets the role of this unit in hardware.  Connect to GND to be the 'led' board receiver
// Leave open to be the 'remote' transmitter
const int role_pin = A4;

// Pins on the remote for buttons
const uint8_t button_pins[] = { 2,3,4,5,6,7 };
const uint8_t num_button_pins = sizeof(button_pins);

// Pins on the LED board for LED's
const uint8_t led_pins[] = { 2,3,4,5,6,7 };
const uint8_t num_led_pins = sizeof(led_pins);

//
// Topology
//

// Single radio pipe address for the 2 nodes to communicate.
const uint64_t pipe = 0xE8E8F0F0E1LL;

//
// Role management
//
// Set up role.  This sketch uses the same software for all the nodes in this
// system.  Doing so greatly simplifies testing.  The hardware itself specifies
// which node it is.
//
// This is done through the role_pin
//

// The various roles supported by this sketch
typedef enum { role_remote = 1, role_led } role_e;

// The debug-friendly names of those roles
const char* role_friendly_name[] = { "invalid", "Remote", "LED Board"};

// The role of the current running sketch
role_e role;

//
// Payload
//

uint8_t button_states[num_button_pins];
uint8_t led_states[num_led_pins];

//
// Setup
//

void setup(void)
{
  //
  // Role
  //

// set up the role pin
  pinMode(role_pin, INPUT);
  digitalWrite(role_pin,HIGH);
  delay(20); // Just to get a solid reading on the role pin

// read the address pin, establish our role
  if ( digitalRead(role_pin) )
    role = role_remote;
  else
    role = role_led;

//
  // Print preamble
  //

Serial.begin(57600);
  printf_begin();
  printf("\n\rRF24/examples/led_remote/\n\r");
  printf("ROLE: %s\n\r",role_friendly_name[role]);

//
  // Setup and configure rf radio
  //

radio.begin();

//
  // Open pipes to other nodes for communication
  //

// This simple sketch opens a single pipes for these two nodes to communicate
  // back and forth.  One listens on it, the other talks to it.

if ( role == role_remote )
  {
    radio.openWritingPipe(pipe);
  }
  else
  {
    radio.openReadingPipe(1,pipe);
  }

//
  // Start listening
  //

if ( role == role_led )
    radio.startListening();

//
  // Dump the configuration of the rf unit for debugging
  //

radio.printDetails();

//
  // Set up buttons / LED's
  //

// Set pull-up resistors for all buttons
  if ( role == role_remote )
  {
    int i = num_button_pins;
    while(i--)
    {
      pinMode(button_pins[i],INPUT);
      digitalWrite(button_pins[i],HIGH);
    }
  }

// Turn LED's ON until we start getting keys
  if ( role == role_led )
  {
    int i = num_led_pins;
    while(i--)
    {
      pinMode(led_pins[i],OUTPUT);
      led_states[i] = HIGH;
      digitalWrite(led_pins[i],led_states[i]);
    }
  }

}

//
// Loop
//

void loop(void)
{
  //
  // Remote role.  If the state of any button has changed, send the whole state of
  // all buttons.
  //

if ( role == role_remote )
  {
    // Get the current state of buttons, and
    // Test if the current state is different from the last state we sent
    int i = num_button_pins;
    bool different = false;
    while(i--)
    {
      uint8_t state = ! digitalRead(button_pins[i]);
      if ( state != button_states[i] )
      {
        different = true;
        button_states[i] = state;
      }
    }

// Send the state of the buttons to the LED board
    if ( different )
    {
      printf("Now sending...");
      bool ok = radio.write( button_states, num_button_pins );
      if (ok)
        printf("ok\n\r");
      else
        printf("failed\n\r");
    }

// Try again in a short while
    delay(20);
  }

//
  // LED role.  Receive the state of all buttons, and reflect that in the LEDs
  //

if ( role == role_led )
  {
    // if there is data ready
    if ( radio.available() )
    {
      // Dump the payloads until we've gotten everything
      bool done = false;
      while (!done)
      {
        // Fetch the payload, and see if this was the last one.
        done = radio.read( button_states, num_button_pins );

// Spew it
        printf("Got buttons\n\r");

// For each button, if the button now on, then toggle the LED
        int i = num_led_pins;
        while(i--)
        {
          if ( button_states[i] )
          {
            led_states[i] ^= HIGH;
            digitalWrite(led_pins[i],led_states[i]);
          }
        }
      }
    }
  }
}





2,3,4,5,6,7 son los pines en lo que pones leds/botones segun el rol

el rol lo cambias con la entrada A4 si la pones a GND es el de los led, si la dejas abierta es el transmisor con los botones

en la carpeta de la librería hay ejemplos mas complejos, si hay algo que no entiendas pregunta!!

Voy a probarla a ver que tal

saludos!!

pero una pregunta: el mismo codigo va en ambos arduinos?, se supone q debo tener un codigo para el transmisor y otro para el receptor, respecto a la libreria que postula Surbyte la verdad no la entiendo, por eso primero voy a hacer ejemplos con la RF24 y la Mirf.

Si, en ambos el mismo código, según conectes el pin analógico 4 a GND o lo dejes abierto, el arduino interpreta el rol de receptor o de transmisor según el caso.

stazlad:
pero una pregunta: el mismo codigo va en ambos arduinos?, se supone q debo tener un codigo para el transmisor y otro para el receptor, respecto a la libreria que postula Surbyte la verdad no la entiendo, por eso primero voy a hacer ejemplos con la RF24 y la Mirf.

El ejemplo es de la RF24.

Un saludo!

He estado viendo la librería de tmrh20 la RF24Network y me parece que es muy sencilla es verdad lo que dice surbyte, pero no la gateway sino la RF24Network hay q actualizar este post estos módulos tienen mucho potencial.

a que velocidad lo utilizáis? estoy intentando hacer un link de larga distancia, con un lna de 2w y un receptor con antena, y con las pruebas que hice no note que fuese mas fiable a 250kbps que a 1mbs

Hola a todos yo recién me estoy metiendo en este tema hoy comprare un par de estos equipos y los probare, ya he hecho varios proyectos con la librería virtualwire para módulos RF, hay equipos my confiables y con buenos alcances, pero creo que es hora de emigrar a la nueva tecnología que es mucho mas confiable y con mas potencialidades, probare lo que aparece acá y les comento, saludos

hasta hoy me llegaron los modulos, pero los nrf24l01+pa+lna mi pregunta es q si los pines son los mismo que el normal?

es decir si estos:

tienen los mismos pines en las mismas posiciones? que el generico?

Si, en ambas versiones los pines se ubican en la misma posición:

Gracias :slight_smile:

Modifiqué las instrucciones para hacerlas más claras, además utilicé las librerías de TMRh20

Muchas gracias x la actualización, pero creo q es mucho para un principiante, osea q solo quiere empezar con estos módulos.

¿Mucho? es casi lo mismo que la librería por si sola, solo es instalar las 3 librerías y luego ejecutar dos ejemplos. Está en ti como la usas, si solo quieres usar la librería NRF24 tienes que ejecutar el ejemplo GettingStarted.ino pero finalmente la dinámica es casi la misma. (Y hasta casi un poco más complicado cuando quieres configurar otros nodos)

Haz la prueba y te vas a dar cuenta que es muy fácil.

jajajja si brother acabo de probar la libreria RF24Network, funciona a la perfeccion , ya por primera vez logro hacer q envie datos de uno y lo reciba en otro, quisiera ponerme en contacto contigo por privado. necesito ayuda con unas cosillas, ojala puedas ayudarme, nose si puedas darme tu correo y te comento bn