NRF24L01 é um módulo transceptor que opera na frequência de 2,4GHz de baixo custo, facilmente encontrado no mercado e com pequeno consumo de energia. O NRF24L01 também pode se comunicar com um total de 6 outros mesmos módulos NRF24L01 ao mesmo tempo.
Esse módulo é uma ótima opção de comunicação Wirelles com as mais variadas plataformas microcontroladoras disponíveis como Arduino, PIC, Raspberry e outras. Seu alcance pode alcançar 10 metros em ambientes internos, 50 metros em campo aberto e até 1Km com a versão de antena externa.
Especificações do Módulo NRF24L01
-
- Tensão de operação: 1,9V – 3.6VDC;
- Potência máxima de saída: 20 dBm;
- Consumo(transmitindo): 115mA(pico);
- Consumo(recebendo): 45mA(pico);
- Consumo(power-down): 4.2uA;
- Sensibilidade em modo de recepção 2Mbp: -92dBm;
- Sensibilidade em modo de recepção 1Mbps: -95dBm;
- Sensibilidade em modo de recepção 250kbps: -104dBm;
- PA ganho: 20dB;
- LNA ganho: 10dB;
- LNA figura de ruído: 2.6Db;
- Ganho da antena (pico): 2 dBi;
- Taxa de 2MB (área aberta): 520m;
- Taxa de 1MB (área aberta): 750m;
- Taxa de 250kb (área aberta): 1000m;
- Temperatura de operação: -40 a 85º Celsius.
Material para Teste e Projeto
-
- 02 – Arduino
- 02 – Módulo NRF24L01
- 03 – Push button
- 03 – LED
- 03 – Resistor 10KΩ
- 03 – Resistor 220Ω
- Jumpers para conexão
Teste dos Módulos NRF24L01
Geralmente quando obtemos algum dispositivo ou sensor novo, queremos prontamente ter a possibilidade de testá-lo imediatamente. Então, antes de partimos para o projeto, faremos um teste nos transceptores NRFL2401 com uma rotina bem simples.
Conexão com o Arduino
A pinagem do módulo com Arduino é bem simples, mas deve ser feita com muito cuidado para não ser conectada de modo errado. Então, conecte os módulo de acordo com os esquemas:
Feito isso, inclua a biblioteca RF24.h, em seguida, carregue os códigos transmissor e receptor em cada placa.
Código teste transmissor
#include <SPI.h> #include <nRF24L01.h> #include <RF24.h> RF24 radio(7, 8); const byte rxAddr[6] = "00001"; void setup() { radio.begin(); radio.setRetries(15, 15); radio.openWritingPipe(rxAddr); radio.stopListening(); } void loop() { const char text[] = "Hello World"; radio.write(&text, sizeof(text)); delay(1000); }
Código teste Receptor
#include <SPI.h> #include <nRF24L01.h> #include <RF24.h> RF24 radio(7, 8); const byte rxAddr[6] = "00001"; void setup() { while (!Serial); Serial.begin(9600); radio.begin(); radio.openReadingPipe(0, rxAddr); radio.startListening(); } void loop() { if (radio.available()) { char text[32] = {0}; radio.read(&text, sizeof(text)); Serial.println(text); } }
Então, com isso, abra o Monitor Serial da porta COM do receptor e observe a mensagem carregada a cada 1 segundo.
Projeto
Agora, faremos uma aplicação bem simples onde comandaremos um acendimento de LEDs via transmissão e recepção pelos módulos NRF24L01.
Monte o transmissor com os botões auxiliado por uma protoboard conforme esquema:
Faça o mesmo para o receptor, mas com os LEDs conforme esquema:
Então, ao finalizar a montagem, basta somente carregar os códigos:
Transmissor
#include <RF24.h> //*************** Controle do RF *********************** #define radioID 0 //Informar "0" para um dispositivo e "1" para o outro dispositivo struct estruturaDadosRF { boolean ligando = false; //Esta variavel será usada para solicitar os dados do outro aparelho. Será útil quando o aparelho solicitante esta sendo ligado, para manter os valores do aparelho que já esta ligado. boolean botao1 = false; boolean botao2 = false; boolean botao3 = false; }; typedef struct estruturaDadosRF tipoDadosRF; tipoDadosRF dadosRF; tipoDadosRF dadosRecebidos; boolean transmitido = true; boolean alterado = false; RF24 radio(7, 8); byte enderecos[][6] = {"1node", "2node"}; //*************** Controle do Projeto LOCAL ************ boolean botao1Ant = HIGH; boolean botao1 = HIGH; boolean botao2Ant = HIGH; boolean botao2 = HIGH; boolean botao3Ant = HIGH; boolean botao3 = HIGH; void setup() { //*************** Controle do RF *********************** radio.begin(); #if radioID == 0 radio.openWritingPipe(enderecos[0]); radio.openReadingPipe(1, enderecos[1]); #else radio.openWritingPipe(enderecos[1]); radio.openReadingPipe(1, enderecos[0]); #endif //Solicita os dados do outro aparelho, se ele estiver ligado. Tenta a comunicação por 2 segundos. dadosRF.ligando = true; radio.stopListening(); long tempoInicio = millis(); while ( !radio.write( &dadosRF, sizeof(tipoDadosRF) ) ) { if ((millis() - tempoInicio) > 2000) { break; } } dadosRF.ligando = false; radio.startListening(); //*************** Controle do Projeto LOCAL ************ pinMode(2, INPUT_PULLUP); pinMode(3, INPUT_PULLUP); pinMode(4, INPUT_PULLUP); Serial.begin(9600); } void loop() { //*************** Controle do RF *********************** // se houve alteração dos dados, envia para o outro radio if (alterado || !transmitido) { radio.stopListening(); transmitido = radio.write( &dadosRF, sizeof(tipoDadosRF) ); radio.startListening(); alterado = false; } //verifica se esta recebendo mensagem if (radio.available()) { radio.read( &dadosRecebidos, sizeof(tipoDadosRF) ); //verifica se houve solicitação de envio dos dados if (dadosRecebidos.ligando) { alterado = true; } else { dadosRF = dadosRecebidos; } } botao1 = digitalRead(2); if (botao1 && (botao1 != botao1Ant)) { dadosRF.botao1 = !dadosRF.botao1; Serial.println("Azul"); alterado = true; //esta variavel controla o envio dos dados sempre que houver uma alteração } botao1Ant = botao1; botao2 = digitalRead(3); if (botao2 && (botao2 != botao2Ant)) { dadosRF.botao2 = !dadosRF.botao2; Serial.println("Verde"); alterado = true; //esta variavel controla o envio dos dados sempre que houver uma alteração } botao2Ant = botao2; botao3 = digitalRead(4); if (botao3 && (botao3 != botao3Ant)) { dadosRF.botao3 = !dadosRF.botao3; Serial.println("Vermelho"); alterado = true; //esta variavel controla o envio dos dados sempre que houver uma alteração } botao3Ant = botao3; delay(10); }
Receptor
#include <RF24.h> //*************** Controle do RF *********************** #define radioID 1 //Informar "0" para um dispositivo e "1" para o outro dispositivo struct estruturaDadosRF { boolean ligando = false; //Esta variavel será usada para solicitar os dados do outro aparelho. Será útil quando o aparelho solicitante esta sendo ligado, para manter os valores do aparelho que já esta ligado. boolean botao1 = false; boolean botao2 = false; boolean botao3 = false; }; typedef struct estruturaDadosRF tipoDadosRF; tipoDadosRF dadosRF; tipoDadosRF dadosRecebidos; boolean transmitido = true; boolean alterado = false; RF24 radio(7, 8); byte enderecos[][6] = {"1node", "2node"}; //*************** Controle do Projeto LOCAL ************ boolean botao1Ant = HIGH; boolean botao1 = HIGH; boolean botao2Ant = HIGH; boolean botao2 = HIGH; boolean botao3Ant = HIGH; boolean botao3 = HIGH; # define LedAzul 22 # define LedVerde 23 # define LedVermelho 24 void setup() { Serial.begin(9600); //*************** Controle do RF *********************** radio.begin(); #if radioID == 0 radio.openWritingPipe(enderecos[0]); radio.openReadingPipe(1, enderecos[1]); #else radio.openWritingPipe(enderecos[1]); radio.openReadingPipe(1, enderecos[0]); #endif //Solicita os dados do outro aparelho, se ele estiver ligado. Tenta a comunicação por 2 segundos. dadosRF.ligando = true; radio.stopListening(); long tempoInicio = millis(); while ( !radio.write( &dadosRF, sizeof(tipoDadosRF) ) ) { if ((millis() - tempoInicio) > 2000) { break; } } dadosRF.ligando = false; radio.startListening(); //*************** Controle do Projeto LOCAL ************ pinMode(LedAzul, OUTPUT); pinMode(LedVerde, OUTPUT); pinMode(LedVermelho, OUTPUT); } void loop() { //*************** Controle do RF *********************** // se houve alteração dos dados, envia para o outro radio if (alterado || !transmitido) { radio.stopListening(); transmitido = radio.write( &dadosRF, sizeof(tipoDadosRF) ); radio.startListening(); alterado = false; } //verifica se esta recebendo mensagem if (radio.available()) { radio.read( &dadosRecebidos, sizeof(tipoDadosRF) ); //verifica se houve solicitação de envio dos dados if (dadosRecebidos.ligando) { alterado = true; } else { dadosRF = dadosRecebidos; } } //*************** Controle do Projeto LOCAL ************ if (dadosRF.botao1) { dadosRF.botao1 = !dadosRF.botao1; digitalWrite(LedAzul, digitalRead(LedAzul) ^ 1); // Acende e apaga LED Azul Serial.println("Azul"); alterado = true; //esta variavel controla o envio dos dados sempre que houver uma alteração } if (dadosRF.botao2) { dadosRF.botao2 = !dadosRF.botao2; digitalWrite(LedVerde, digitalRead(LedVerde) ^ 1); // Acende e apaga LED Verde Serial.println("Verde"); alterado = true; //esta variavel controla o envio dos dados sempre que houver uma alteração } if (dadosRF.botao3) { dadosRF.botao3 = !dadosRF.botao3; digitalWrite(LedVermelho, digitalRead(LedVermelho) ^ 1); // Acende e apaga LED Verde Serial.println("Vermelho"); alterado = true; //esta variavel controla o envio dos dados sempre que houver uma alteração } delay(10); }
Finalmente, agora é só testar se o projeto está funcionando adequadamente e percebemos que ao pressionar os botões, os respectivos LEDs acendem ou apagam.