banner

Rede WiFi de Arduinos


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


https://github.com/nRF24/RF24

 

 

 

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();
}

 

 

FAÇA O DOWNLOAD DOS ARQUIVOS

 

 


Nenhum comentário:

Tecnologia do Blogger.