sexta-feira, setembro 18, 2015

Rádio nRF24L01+: Usando a Biblioteca RF24

Neste post vamos refazer o código do exemplo anterior, desta vez usando a biblioteca RF24.


Instalando a Biblioteca

Você pode baixar a bilioteca como um arquivo ZIP diretamente do github (o botão "Download Zip" está em baixo à direita).  Quando você expandir o zip, será criado um diretório com o nome RF24-master. Para ficar de acordo com as convenções do Arduino, renomeie o diretório para RF24.

Existem dois locais onde você pode colocar este diretório:
  • No diretório libraries do diretório onde estão os seus sketches
  • No diretório libraries do diretório onde está instalada a IDE do Arduino
Após instalar, se você estava com a IDE aberta, feche-a e abra novamente. Deve ter um item RF24 em File Examples.

Usando a Biblioteca

No caso do meu exemplo, bastaram pequenas edições em setup() e loop() para trocar as minhas rotinas pelas da biblioteca:
// Exemplo de uso do nRF24L01+ através da biblioteca RF24
// Daniel Quadros, 18/09/15

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

// Conexoes
const int pinLED = 6;
const int pinBotao = 7;
const int pinSelAddr = 8;
const int pinCE = 9;
const int pinCSN = 10;

// Este objeto encapsula o acesso ao nRF24L01+
RF24 radio(pinCE, pinCSN);

// Endereços
byte addresses[][6] = {"1Node","2Node"};

// Estado anterior do botão
uint8_t botaoAnt = HIGH;

void setup() 
{
  // Serial para debug
  Serial.begin(9600);
  Serial.println("Teste do nRF24L01+");

  // Iniciacao dos pinos de LED, Botao e Selecao do endereco
  pinMode (pinLED, OUTPUT);
  pinMode (pinBotao, INPUT);
  digitalWrite (pinBotao, HIGH);
  pinMode (pinSelAddr, INPUT);
  digitalWrite (pinSelAddr, HIGH);

  // Inicia o rádio
  radio.begin();
  
  // Seleciona os enderecos
  Serial.print("Recebendo no endereco ");
  if (digitalRead(pinSelAddr) == LOW)
  {
    radio.openWritingPipe(addresses[1]);
    radio.openReadingPipe(1,addresses[0]);
    Serial.println((char *) (addresses[0]));
  }
  else
  {
    radio.openWritingPipe(addresses[0]);
    radio.openReadingPipe(1,addresses[1]);
    Serial.println((char *) (addresses[1]));
  }

  // Iniciamos ouvindo
 radio.startListening();
}

void loop() 
{
  uint8_t botao;
  
  botao = digitalRead(pinBotao);
  if (botao != botaoAnt)
  {
    botaoAnt = botao;
    Serial.print ("Transmitindo: ");
    radio.stopListening();
    if (radio.write(&botao, 1))
       Serial.println ("Ok");
    else    
       Serial.println ("Erro");
    radio.startListening();
  }
  else if (radio.available())
  {
    uint8_t dado;
    radio.read(&dado, 1);
    Serial.print("Recebido ");
    Serial.println(dado);
    if (dado == LOW)
      digitalWrite(pinLED, HIGH);
    else
      digitalWrite(pinLED, LOW);
  }
}
Eu mantive o tamanho default de 5 bytes para o endereço e usei os endereços do exemplo "Getting Started". No lugar de "1Node" e "2Node" poderiam ser quaisquer conjuntos diferentes de 5 bytes. No caso de querer usar os outros "pipes" de recepção apenas o primeiro byte deve ser diferente.

A documentação oficial pode ser vista em http://tmrh20.github.io/RF24/.

Observação

Na wiki Arduino-info é mencionado que alguns Arduinos tem problemas para gerar na saída de 3V a corrente necessária para as transmissões. O exemplo "Getting Started" também se refere a isto, baixando a potência de transmissão. No meu caso não tive problemas, mas se você tentar reproduzir este exemplo e não funcionar, experimente baixar a potência (radio.setPALevel(RF24_PA_LOW)) e/ou colocar um capacitor de 10uF entre a saída de 3V e o terra.

No próximo post vou divagar um pouco sobre como usar este o rádio em várias situações.

4 comentários:

MatroX disse...

Amigo, boa noite.
Pode me dar uma ajuda?

Já faz algum tempo que estou tentando fazer esses módulos funcionarem e estou tendo o mesmo problema com diversos módulos/ códigos: o receptor recebe o dado imprime 2 vezes no monitor Serial e depois entra no caso de falha (radio não encontrado).
Tentei com outros códigos parecidos como este que envia o valor do sensor de temperatura para o outro modulo e faz a mesma coisa: Envia 2x o valor e depois para de funcionar.
(http://www.elec-cafe.com/arduino-wireless-temperature-lcd-display-nrf24l01-dht11/)

Teste que já fiz: substitui os dois nRF24L01, coloquei o capacitor de 4,7uf nos terminais 3,3v do nRF (para dar um impulso na transmissão) e até agora nada. O mesmo problema.
Estou postando esse video privado no youtube para que veja o comportamento bizarro. rs.

https://www.youtube.com/watch?v=BfN-Tt0sQSE

Obrigado. ;)
Att
Raphael

Daniel Quadros disse...

Raphael, duas sugestões: (1) No transmissor, coloque um radio.stopListening(); após o openWritePipe (2) Experimente mudar para a biblioteca que eu usei https://github.com/TMRh20/RF24 (atenção que tem pequenas mudanças na forma de uso). Boa sorte!

MatroX disse...

Grande Daniel, obrigado pela resposta. Vou tentar assim que tentar resolver um problema que apareceu do nada: Da erro no id.exe no momento de compilar (collect2.exe: error: ld returned 1 exit status).
Já teve esse problema antes?

Obrigado novamente.
Abs

MatroX disse...

Daniel, dei uma pesquisada aqui e ao que parece o pessoal tem substituído o ld.exe pela versão do arduino IDE 1.0.6. Fiz isso e funcionou. =D
Quanto ao rádio também funcionou! Obrigado pela Dica.

Agora preciso entender melhor a biblioteca para atender aos requisitos. Meu próximo desafio é criar uma "rede" de nFRs e mandar várias informações para uma única central.
Pretende fazer algum Tutorial sobre esse assunto?

Obrigado.
Abraços.