Que tal montar uma rede de
arduinos? Então, hoje vamos empregar os Arduinos Nano (RF-Nano) utilizando
rádio NRF24L01 para fazer a transmissão de mensagens entre eles. Confira no
vídeo!
RECURSOS USADOS
- 2 ou mais RF-Nano
PINAGEM
Arduino Uno com NRF24L01+
O ATmega328 já usa
D9,D10,D11,D12, e D13 não podem ser usados
BIBLIOTECAS
RF24 by TMRh20
FLUXOGRAMA MASTER
CÓDIGO
Declarações e variáveis
#include <SPI.h>
#include <RF24.h>
//Quantidade de nós slave
#define NODES_COUNT 2
//Nomeamos requisição chamada 'count'. Neste exemplo vamos fazer apenas um request chamado count
//onde o slave nos retornará a quantidade de requisições que ele recebeu.
//Você pode criar novos tipos de requisições de acordo com o que queira, como valores de sensores por exemplo.
#define REQUEST_VALUE_COUNT "count"
//Intervalo entre as requisições que este ESP fará
#define REQUEST_INTERVAL 1000
//Quantidade de tempo de espera máxima para uma resposta
#define TIMEOUT 3000
//Objeto responsável pela comunicação via rádio
//Pino 10 = Chip enable, Pino 9 = chip select
RF24 radio(10, 9);
//Endereço dos nós slave. Cada slave que for utilizar deve-se trocar o 'address' (no Slave.ino) para um deste array.
//5 caracteres para cada endereço. Se for abrir várias leituras simultâneas, a partir do segundo endereço o 1 primeiro
//caractere deve ser diferente e o resto dos bytes iguais. Neste exemplo estamos lendo um de cada vez,
//desligando a leitura do outro enquanto isso.
uint8_t addresses[NODES_COUNT][6] = {"1node", "2node"};
//Índice do slave que estamos nos comunicando atualmente
int currentSlaveIndex = 0;
//Estrutura de exemplo de uma requisição que o master vai fazer para os slaves
//Modifique de acordo com a sua necessidade
//Deve ser igual no código dos slaves
struct Request
{
unsigned long millis;
char message[20];
};
//Estrutura de exemplo de uma resposta que os slaves enviarão para o master
//Modifique ou adicione novas estruturas de acordo com a sua necessidade
//Deve ser igual no código dos slaves
struct Response
{
unsigned long millis;
int value;
};
setup
void setup()
{
Serial.begin(115200);
//Inicializa o objeto que vai controlar o rádio
radio.begin();
Serial.println("Master Started");
}
loop
void loop()
{
//Envia requisição para o slave atual. Retorna true se conseguiu ou false caso contrário
if(sendRequest())
{
//Se chegou aqui a requisição foi bem sucedida
Serial.print("Successfully sent request to ");
Serial.println((char*)addresses[currentSlaveIndex]);
//Tenta ler a resposta
tryToReadResponse();
}
else
{
//Se chegou aqui houve erro no envio da requisição ou no recebimento do ACK
Serial.print("Failed to send request to ");
Serial.println((char*)addresses[currentSlaveIndex]);
}
//Modifica o índice para o próximo slave
currentSlaveIndex++;
//Se estourou a quantidade de índices, voltamos para o 0
if(currentSlaveIndex >= NODES_COUNT)
{
currentSlaveIndex = 0;
}
//Espera o tempo estabelecido
delay(REQUEST_INTERVAL);
}
sendRequest
bool sendRequest()
{
//Para enviar precisamos desativar o modo de recebimento
radio.stopListening();
//Ativa a escrita no endereço do slave atual
radio.openWritingPipe(addresses[currentSlaveIndex]);
//Cria uma requisição dizendo qual o tempo de boot (apenas como exemplo de dado que pode ser enviado)
//e mensagem pedindo o valor do contador que o slave mantém e incrementa a cada requisição
Request request = {millis(), REQUEST_VALUE_COUNT};
//Faz o envio. Retorna true se o envio for confirmado (está com ACK ativado) ou false caso contrário
return radio.write(&request, sizeof(request));
}
tryToReadResponse
void tryToReadResponse()
{
//Informa o endereço de leitura como sendo o endereço do slave atual
radio.openReadingPipe(0, addresses[currentSlaveIndex]);
//Ativa o recebimento de dados
radio.startListening();
//Se conseguiu obter uma resposta dentro do tempo máximo estabelecido
if(gotResponseInTime())
{
//Faz a leitura da resposta
Response response;
radio.read(&response, sizeof(response));
//Mostra no monitor serial
printResponse(response);
}
}
gotResponseInTime
bool gotResponseInTime()
{
//Marca o tempo que começou
unsigned long start = millis();
//Enquanto o slave não enviar nada
while (!radio.available())
{
//Verifica se passou do tempo de espera
if(millis() - start > TIMEOUT)
{
Serial.print((char*)addresses[currentSlaveIndex]);
Serial.println(" response timeout");
//Se chegou aqui significa que o slave demorou além do tempo de espera para nos enviar uma resposta
return false;
}
}
//Se chegou aqui significa o slave enviou a resposta dentro do tempo
return true;
}
printResponse
void printResponse(Response response)
{
//Mostra no monitor serial o endereço, valor da contagem de requisições e tempo de boot do slave
Serial.print("Received response from ");
Serial.print((char*)addresses[currentSlaveIndex]);
Serial.print(" with value ");
Serial.print(response.value);
Serial.print(". Sender boot time ");
Serial.print(response.millis);
Serial.println("ms.");
}
FLUXOGRAMA SLAVE
CÓDIGO
Declarações e variáveis
#include <SPI.h>
#include <RF24.h>
//Nomeamos uma requisição chamada 'count' assim como está no código do master
#define REQUEST_VALUE_COUNT "count"
//Objeto responsável pela comunicação via rádio
//Pino 10 = Chip enable, Pino 9 = chip select
RF24 radio(10, 9);
//Endereço deste slave. Deve ser um dos que estão no array de endereços do master.
//Cada slave deve possuir um diferente.
const uint8_t address[6] = "1node";
//Contador de requisições
int count = 0;
//Estrutura de exemplo de uma requisição que o master vai fazer para os slaves
//Modifique de acordo com a sua necessidade
//Deve ser igual no código do master
struct Request
{
unsigned long millis;
char message[20];
};
//Estrutura de exemplo de uma resposta que os slaves enviarão para o master
//Modifique ou adicione novas estruturas de acordo com a sua necessidade
//Deve ser igual no código do master
struct Response
{
unsigned long millis;
int value;
};
setup
void setup() {
Serial.begin(115200);
//Inicializa o objeto que vai controlar o rádio
radio.begin();
//Informa o endereço de leitura
radio.openReadingPipe(0, address);
//Ativa o recebimento de dados
radio.startListening();
Serial.print("Slave ");
Serial.print((char*)address);
Serial.println(" Started");
}
loop
void loop()
{
//Se chegou algo do master
if (radio.available())
{
//Fazemos a leitura da requisição e enviamos uma resposta
readAndAnswerRequest();
}
}
readAndAnswerRequest
void readAndAnswerRequest()
{
//Fazemos a leitura da requisição
Request request;
radio.read(&request, sizeof(request));
//Incrementa o contador de requisições
count++;
//Mostramos a requisição no monitor serial
printRequest(request);
//Se a mensagem é igual a string que está em 'REQUEST_VALUE_COUNT'
//significa que é uma requisição para enviar o contador
//Este é apenas um exemplo, mas você pode adicionar outras requisições como
//valores de sensores
if(strcmp(request.message, REQUEST_VALUE_COUNT) == 0)
{
//Envia a respostas
sendCountResponse();
}
}
printRequest
void printRequest(Request request)
{
//Mostra no monitor serial a mensagem recebida e o tempo de boot do master como exemplo
Serial.print("Got request with message '");
Serial.print(request.message);
Serial.print("'. Sender boot time ");
Serial.print(request.millis);
Serial.println("ms.");
}
sendCountResponse
void sendCountResponse()
{
//Para enviar precisamos desativar o modo de recebimento
radio.stopListening();
//Informamos o endereço para onde iremos enviar
radio.openWritingPipe(address);
//Cria uma estrutura de reposta contendo o tempo de boot atual deste slave e o contador de requisições
Response response = {millis(), count};
//Faz o envio da resposta. Retorna true se bem sucedido ou false caso contrário
if (!radio.write(&response, sizeof(response)))
{
Serial.println("failed");
}
//Reativa o modo de recebimento
radio.startListening();
}














0 Comentários