Enviar sinais via nRF24L01+

Boa noite senhores,

Venho aqui para pedir a ajuda de vocês em uma pequena tarefa que preciso executar com dois arduinos.

Comprei 10 módulos nRF24L01+ (AliExpress)

E com isso, gostaria de enviar um sinal de um arduino à outro para que o mesmo possa ser usado em uma condicional para acionar uma saída digital do arduino

Exemplo:

if (msg = 1){ digitalWrite(6)==HIGH}

Porém, estou com dificuldades em como proceder. Encontrei neste post, uma alternativa, que usa de forma inteligente (acho eu) de identificar o master e o slave (principal e secundário) com o uso do resistor.

Até aí OK. Porém, falta-me agora, saber como enviar os comandos, para que o master ou slave receba e atribua em uma condicional

Por exemplo:

  • No master, pressionei um botão, que equivale ao envio de um sinal/variável
  • O slave irá receber este sinal e acender um led
  • Logo depois, o slave irá retornar o sinal
  • O master recebe esse sinal e confirma que a ação foi executada
  • Caso o sinal não seja retornado, um led vermelho do master acende e depois apaga.

Se alguém souber como posso fazer esses procedimentos acima usando o nRF24L01+ eu agradeço.

Att,

Yago

Pesquisa por uma biblioteca do Greg Copeland para usar os nRF... depois é só programar.

Achei a biblioteca, no entanto, não consigo compreendê-la. Procurei executar o exemplo led_remote, porém, está um pouco confuso.

Em anexo, possui a foto do esquema de ligação que tentei realizar, mas não consegui seguir adiante.
Existe um exemplo mais simples, que possa servir de "arranque inicial" para a minha aplicação descrita na primeira pergunta?

Att,

Yago Cypriano

Qual é a ideia com esta montagem? À primeira vista, não me parece que isso esteja bem montado.

Boa noite Luis.

Essa montagem é para executar o código de exemplo da biblioteca do Greg Copeland:

/*
 Copyright (C) 2011 James Coliz, Jr. <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 "RF24.h"
#include "printf.h"

//
// Hardware configuration
//

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

RF24 radio(8,9);

// 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(button_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]);
          }
        }
      }
    }
  }
}
// vim:ai:cin:sts=2 sw=2 ft=cpp

No início, possui as instruções de montagem em inglês, que compreendi da seguinte forma:

"Conecte qualquer número de botões ou chaves dos pinos arduinos (2,3,4,5,6,7) ligados ao terra" (Fiz isso)
"Conecte o mesmo número de leds dos pinos arduinos (2,3,4,5,6,7) à um resistor, ao GND"

Isso é o que confere na foto, montando próximo para minimizar fios de ligação.

Porém, desisti no meio, pois acredito (ainda pesquisando), ter um exemplo já pronto, ou mais simples, para a minha aplicação:

  • No master, pressionei um botão, que equivale ao envio de um sinal/variável
  • O slave irá receber este sinal e acender um led
  • Logo depois, o slave irá retornar o sinal
  • O master recebe esse sinal e confirma que a ação foi executada
  • Caso o sinal não seja retornado, um led vermelho do master acende e depois apaga.

Att,

Yago

Boa tarde.

Após muita pesquisa, achei o primeiro exemplo que funcionou comigo, e estarei compartilhando o material aqui:

A biblioteca foi a do maniacbug

E os código seguem abaixo

Transmissor:

/*              êîä ¹1 äëÿ ïåðåäàò÷èêà transmitter
 ****************************
 óðîê îò Äìèòðèÿ Îñèïîâà. http://www.youtube.com/user/d36073?feature=watch
 v.01 NRF24L01 if Arduino1 button press-Arduino2 LED on
 Version 0.1 2013/07/14
 
 ïîäðîáíóþ âèäåî èíñòðóêöèþ âûëîæó çäåñü
https://www.youtube.com/watch?v=aJVSrGwZs2s
 
 êîä ¹2 äëÿ ïðè¸ìíèêà 
v.01 receiver NRF24L01 if Arduino ¹1 button press-Arduino ¹2 LED on
http://yadi.sk/d/ZDAQhQFB6pHM8



 êîä ¹1 äëÿ ïåðåäàò÷èêà 
 
 
 
 íà Arduino ¹1 íàæèìàåì êíîïêó, ÏÎÊÀ óäåðæèâàåì êíîïêó íàæàòîé, 
 íà Arduino ¹2 âÊëþ÷àåòñÿ (ãîðèò) ñâåòîäèîä, 
 
 NRF24L01+ 2.4GHz Antenna Wireless Transceiver Module For Microcontr
 
 Arduino1 NRF24L01 Serial send. - Arduino2 led. LOW HIGH
 https://www.youtube.com/watch?v=aHgxXXRwtOE&noredirect=1
 
 Arduino Ðàäèîìîäóëü nRF24L01 -2.4GHz RF24 Libraries. test
 https://www.youtube.com/watch?v=B6LHfwisgUQ
 
 http://forum.arduino.cc/index.php?topic=138663.0
 */

// ýòî ñêà÷àííàÿ áèáëèîòåêà
//https://github.com/maniacbug/RF24
//https://github.com/maniacbug/RF24/archive/master.zip
//http://yadi.sk/d/ZvMq19fB6lgPs

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


int msg[1];

// Set up nRF24L01 radio on SPI bus plus pins 9 & 10 
//Êîíòàêòû îò ðàäèîìîäóëÿ NRF24L01 ïîäêëþ÷àåì ê ïèíàìíàì -> Arduino

//SCK  -> 13
//MISO -> 12
//MOSI -> 11
//CSN  -> 10
//CE   -> 9

RF24 radio(9,10);


const uint64_t pipe = 0xE8E8F0F0E1LL; // àäðåñ êàíàëà  ïåðåäà÷è

//êíîïêè ïîäêëþ÷åíû ê ýòèì ïèíàì
int buttonPin1 = 2;
int buttonPin2 = 3;

void setup(void){ 
  radio.begin();
  radio.openWritingPipe(pipe); // Îòêðûâàåì êàíàë ïåðåäà÷è
} 
void loop(void){
  //ïîêà êíîïêà (buttonPin1)íàæàòà îòïðàâëÿåì ïàêåò (111)â Arduino ¹2
  if (digitalRead(buttonPin1) == HIGH){ 
    msg[0] = 111; 
    radio.write(msg, 1);
  }
  if (digitalRead(buttonPin2) == HIGH){ 
    msg[0] = 112; 
    radio.write(msg, 1);
  }
}

Receptor

/*              êîä ¹2 äëÿ ïðè¸ìíèêà receiver
 ****************************
 óðîê îò Äìèòðèÿ Îñèïîâà. http://www.youtube.com/user/d36073?feature=watch
 v.01 NRF24L01 if Arduino ¹1 button press-Arduino ¹2 LED on
 Version 0.1 2013/07/14
 
 ïîäðîáíóþ âèäåî èíñòðóêöèþ âûëîæó çäåñü
https://www.youtube.com/watch?v=aJVSrGwZs2s
 
 êîä ¹2 äëÿ ïðè¸ìíèêà 
 êîä ¹1 äëÿ ïåðåäàò÷èêà 
 
 
 
 íà Arduino ¹1 íàæèìàåì êíîïêó, ÏÎÊÀ óäåðæèâàåì êíîïêó íàæàòîé, 
 íà Arduino ¹2 âÊëþ÷àåòñÿ (ãîðèò) ñâåòîäèîä, 
 
 NRF24L01+ 2.4GHz Antenna Wireless Transceiver Module For Microcontr
 
 Arduino1 NRF24L01 Serial send. - Arduino2 led. LOW HIGH
 https://www.youtube.com/watch?v=aHgxXXRwtOE&noredirect=1
 
 Arduino Ðàäèîìîäóëü nRF24L01 -2.4GHz RF24 Libraries. test
 https://www.youtube.com/watch?v=B6LHfwisgUQ
 
 http://forum.arduino.cc/index.php?topic=138663.0
 */

// ýòî ñêà÷àííàÿ áèáëèîòåêà
//https://github.com/maniacbug/RF24
//https://github.com/maniacbug/RF24/archive/master.zip
//http://yadi.sk/d/ZvMq19fB6lgPs

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

int msg[1];

// Set up nRF24L01 radio on SPI bus plus pins 9 & 10 
//Êîíòàêòû îò ðàäèîìîäóëÿ NRF24L01 ïîäêëþ÷àåì ê ïèíàìíàì -> Arduino

//SCK  -> 13
//MISO -> 12
//MOSI -> 11
//CSN  -> 10
//CE   -> 9

RF24 radio(9,10);

const uint64_t pipe = 0xE8E8F0F0E1LL; // àäðåñ êàíàëà 

//ñâåòîäèîäû ïîäêëþ÷åíû ê ýòèì ïèíàì
int LEDpin1 = 2;
int LEDpin2 = 3;

void setup(void){
  radio.begin();
  radio.openReadingPipe(1,pipe); // Îòêðûâàåì îäèí èç 6-òè êàíàëîâ ïðèåìà
  radio.startListening(); // Íà÷èíàåì ñëóøàòü ýôèð

  pinMode(LEDpin1, OUTPUT);
  pinMode(LEDpin2, OUTPUT);

}

void loop(void){
  if (radio.available()){
    bool done = false;    
    while (!done){
      done = radio.read(msg, 1);      
      //åñëè ïðèøåë ïàêåò îò Arduino ¹1 (111) âÊëþ÷àåòñÿ ñâåòîäèîä (ãîðèò)LEDpin1, HIGH
      if (msg[0] == 111){
        delay(10);
        digitalWrite(LEDpin1, HIGH);
      }
      else {
        digitalWrite(LEDpin1, LOW);
      }
      delay(10);
      if (msg[0] == 112){
        delay(10);
        digitalWrite(LEDpin2, HIGH);
      }
      else {
        digitalWrite(LEDpin2, LOW);
      }
      delay(10);
    }
  }
}

Montagem do Transmissor:

ARDUINO FÍSICO
2 Botão 1 junto ao *Resistor 1
3 Botão 2 junto ao Resistor 2
VCC Outro pino do botão 1 e botão 2
GND Outro pino do resistor 1 e resistor 2

*Resistor de 10K

Montagem do Receptor:

ARDUINO FÍSICO
2 **Resistor 1 - Led 1 (+)
3 Resistor 2 - Led 2 (+)
GND Led 1 e 2 (-)

**Resistor de 200R

Apartir desse exemplo, vou tentar chegar na minha necessidade. Caso eu tenha alguns empecilhos que não consiga resolver, volto a postar aqui.

Estas 2 linhas estão diferentes:

programa antigo:

RF24 radio(8,9);

programa novo:

RF24 radio(9,10);

Sim. São códigos bem diferentes.

Da última vez que vi, a biblioteca do maniacbug tinha bugs... a do Greg Copeland corrigiu esses bugs e adicionou funcionalidade.

Talvez ele já tenha criado uma nova versão com as correcções submetidas pelo Greg.

Pode ser. Agora estou pesquisando como passar valores analógicos via este RF.

Se alguém já possuir algum material e puder disponibilizar aqui para estudos eu agradeço.

Voltei atrás e fui ver o código inicial e surgiu-me uma dúvida. Como estava ligado o pino A4 quando corria o programa original? Repare que no código tem isto:

// 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;

Ou seja, o pino A4 serve para configurar o nó. Se o nó for receptor A4 deve estar a GND se o nó for emissor A4 pode ser deixado por ligar.

Hum.. Não sabia disso. Vou testar novamente. Estava sem ligação nenhuma. Ambas as placas. Porém, ainda faltam fazer o restante das ligações, que não sei quais são..

Sem ligação são os dois emissores, por isso, é normal que não funcione. Os dois programas são muito parecidos, sendo assim, não é normal que um funcione e o outro não.

  This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences.
Arduino: 1.0.6 (Windows NT (unknown)), Board: "Arduino Uno"
RF24\RF24.cpp.o: In function `RF24':
C:\Program Files (x86)\Arduino\libraries\RF24/RF24.cpp:241: multiple definition of `RF24::RF24(unsigned char, unsigned char)'
RF24-master\RF24.cpp.o:D:\Documentos\Arduino\libraries\RF24-master/RF24.cpp:241: first defined here
.
.
.
here
RF24\RF24.cpp.o: In function `RF24::write(void const*, unsigned char)':
C:\Program Files (x86)\Arduino\libraries\RF24/RF24.cpp:441: multiple definition of `RF24::write(void const*, unsigned char)'
RF24-master\RF24.cpp.o:D:\Documentos\Arduino\libraries\RF24-master/RF24.cpp:441: first defined here
RF24\RF24.cpp.o: In function `RF24::print_address_register(char const*, unsigned char, unsigned char)':
C:\Program Files (x86)\Arduino\libraries\RF24/RF24.cpp:220: multiple definition of `RF24::print_address_register(char const*, unsigned char, unsigned char)'
RF24-master\RF24.cpp.o:D:\Documentos\Arduino\libraries\RF24-master/RF24.cpp:220: first defined here
RF24\RF24.cpp.o: In function `RF24::printDetails()':
C:\Program Files (x86)\Arduino\libraries\RF24/RF24.cpp:309: multiple definition of `RF24::printDetails()'
RF24-master\RF24.cpp.o:D:\Documentos\Arduino\libraries\RF24-master/RF24.cpp:309: first defined here

Recebo esse erro ao compilar o código.

O mesmo desaparece quando comento/removo essa linha:

#include "nRF24L01.h"

Há algum problema?

Se a linha está comentada, não entendo para que poderia querer descomentá-la. No entanto, isso deve acontecer porque tem a biblioteca instalada em dois locais diferentes.

A linha não estava comentada. Eu é quem a comentei.

Antes:

#include "nRF24L01.h"

Depois:

//#include "nRF24L01.h"

O que diz a mensagem de erro é que tem a biblioteca RF24 instalada em dois locais diferentes. Em:

C:\Program Files (x86)\Arduino\libraries\RF24/RF24.cpp

e em:
D:\Documentos\Arduino\libraries\RF24-master/RF24.cpp

Se é assim, experimente a apagar uma e veja os resultados.

Uma dúvida:

Bubulindo, não sei se lembras, mas quando eu usava o nRF de 433MHz, você dizia-me que não era um método seguro, pois se houvesse alguém com receptor de mesma frequência ligada, poderia captar as minhas variáveis transmitidas certo?

Portanto, essa parte do código do nRF24L01+ é o que torna minha comunicação mais segura?

const uint64_t pipe = 0xE8E8F0F0E1LL;

Obrigado.

De certa forma sim...

No entanto, lembra-te que a partir do momento que está no ar nunca é 100% seguro. Mas ainda não me dediquei a tentar ver isso nos nRF.