sábado, 23 de septiembre de 2017

Arduino Ejemplos: El modulo NRF2401 comunicación Bidireccional

Muy buenas a todos los Arduineros!!!

Como vimos en la entrada anterior: Arduino Ejemplos: El modulo NRF2401 comunicación Unidireccional se pueden enviar datos de un módulo nRF2401 a otro. Bien, esta comunicación puede realizarse en los dos sentidos, es decir, cada modulo tiene la capacidad de enviar y recibir datos.

Para ello necesitaremos dos canales, uno para enviar datos y otro para escuchar o recibir los datos.

Esta comunicación es de tipo Half-Duplex ya que no transmite ni recibe los datos por el mismo canal, si no que abre un canal para enviar y lo cierra para escuchar. Un buen ejemplo de este tipo de comunicación son las emisoras de radio de tipo civil, donde el operador pulsa un botón para hablar y tiene que soltarlo para escuchar.

Con este diagrama se entiende mucho mejor lo que quiero explicar:

La configuración en ambos Arduinos es prácticamente la misma, solo cambian algunas cosas como el canal donde recibimos y enviamos que tienen que estar al contrario en cada programa, eso lo configuramos en el void setup().

También tendremos que poner a la escucha en el setup el modulo receptor, si no, no funcionara.

Setup del emisor:


nRF.begin();

// Retardo y numero máximo de reintentos.
nRF.setRetries(15, 15);

// Abrimos el canal 0 para escribir.
nRF.openWritingPipe(pipes[0]); 

// Abrimos el canal 1 para leer.
nRF.openReadingPipe(1, pipes[1]); 

Setup del receptor:


nRF.begin();

// Retardo y numero máximo de reintentos.
nRF.setRetries(15, 15);

// Ponemos el modulo en escucha.
nRF.startListening();

// Abrimos el canal 1 para escribir.
nRF.openWritingPipe(pipes[1]); 

// Abrimos el canal 0 para leer.
nRF.openReadingPipe(1, pipes[0]); 

La parte resaltada en negrita es lo que hay que tener en cuenta a la hora de programar los Arduinos, el canal openWritingPipe del Arduino A es el openReadingPipe del Arduino B y viceversa.

El programa en si es muy parecido al anterior, cuando presionamos el pulsador en el Arduino A, mandamos al Arduino B encender el LED y el Arduino B contesta al Arduino A si el LED esta encendido o apagado.

Este es el código para el transmisor:


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

// Declaramos los pines CE y CSN
#define CE 9
#define CSN 10

// Creamos el objeto RF24 y le asignamos los pines de control.
RF24 nRF(CE, CSN);

// Dos direcciones para comunicar entre los 2 nodos.
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
const int pulsador = 4;
float datos[1];
int dato[1];

// Array para recibir el texto
char respuesta[16];

void setup(void)
{
  Serial.begin(115200);
  nRF.begin();
  
  // Retardo y numero máximo de reintentos.
  nRF.setRetries(15, 15);
  
  // Abrimos el canal 0 para escribir.
  nRF.openWritingPipe(pipes[0]); 
  
  // Abrimos el canal 1 para leer.
  nRF.openReadingPipe(1, pipes[1]); 
  
  
  pinMode(pulsador, INPUT);
}

// Inicia el programa principal
void loop(void)
{
  // Cerramos el canal de escucha para poder transmitir.
  nRF.stopListening(); 
  boolean estado = (digitalRead(pulsador));
  if (estado == true)
  { dato[0] = 1;
    nRF.write (&dato, sizeof (dato));
    Serial.print("Dato enviado: ");
    Serial.print(dato[0]);
  } else {
    dato[0] = 0;
    nRF.write(&dato, sizeof (dato));
    Serial.print("Dato enviado: ");
    Serial.print(dato[0]);
  }
  Serial.print(" , ");
  delay (20);
  
  // Abrimos el canal para escuchar la respuesta.
  nRF.startListening(); 
  delay(100);
  if (nRF.available()){
    int done = nRF.read( respuesta, 16);
    Serial.print ("Respuesta recibida: ");
    Serial.println(respuesta);
    delay (200);
    }
}

Y este es el código para el receptor, que encenderá el led cuando accionemos el pulsador


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

// Declaramos los pines CE y CSN
#define CE 9
#define CSN 10

// Creamos el objeto RF24 y le asignamos los pines de control.
RF24 nRF(CE, CSN);

// Dos direcciones para comunicar entre los 2 nodos.
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
const int led = 4;
float datos[1];
int dato[1];
boolean estado;

char encendido[16] = ("Led encendido\n"); //Texto a enviar al Emisor
char apagado  [16] = ("Led apagado\n");   //Texto a enviar al Emisor

void setup(void)
{
  Serial.begin(15200);
  nRF.begin();
  
  // Retardo y numero máximo de reintentos.
  nRF.setRetries(15, 15);
  
  // Ponemos el modulo en escucha.
  nRF.startListening();
  
  // Abrimos el canal 1 para escribir.
  nRF.openWritingPipe(pipes[1]); 
  
  // Abrimos el canal 0 para leer.
  nRF.openReadingPipe(1, pipes[0]);

  pinMode(led, OUTPUT);
  digitalWrite(led, HIGH);
  delay(500);
  digitalWrite(led, LOW);
}

// Inicia el programa principal
void loop() {

  if (nRF.available())
  {
    bool done = false;
    while (!done)
    {
      done = nRF.read(&dato, sizeof(dato));
      Serial.print("Estado del led:");
      Serial.print(dato[0]);
      Serial.print(" , ");
      delay(20);
    }
    // Cerramos el canal de escucha para poder transmitir.
    nRF.stopListening(); 

    if (dato[0] == 1)
    { digitalWrite(led, HIGH);
      estado = true;
    } else {
      digitalWrite(led, LOW);
      estado = false;
    }


    if (estado == true)
    {
      nRF.write (encendido, 16);
      Serial.println("Led encendido");
    } else {
      dato[0] = 0;
      nRF.write(apagado, 16);
      Serial.println("Led apagado");
    }
    // Abrimos el canal para escuchar la respuesta.
    nRF.startListening(); 
  }
}

Aquí tenéis una captura de los monitores seriales:

Los módulos nRF24L01 es una muy buena base para hacer proyectos más elaborados con este tipo de módulos, como por ejemplo un mando de Radio Control multifunción o receptores con funciones totalmente personalizadas.

Os dejo enlaces a proyectos realizados con el módulo de radiofrecuencia nRF24L01:

Mando Xbox RC24

Coche RC Maisto drift Xbox RC24

Vehículo oruga RC Xbox RC24

Espero les sirva, Saludos!!!

No hay comentarios :

Publicar un comentario