quarta-feira, 4 de agosto de 2021

REDE MESH COM NINA W106 - ESP-MESH - ARDUINO PlatformIO

REDE MESH COM NINA W106 - ESP-MESH - ARDUINO PlatformIO


PARTE I

O objetivo deste BLOG é demonstrar como é possível utilizar o módulo NINA W106 para implementar um rede MESH. Foram utilizados 3 NINA W106 para os testes.

O ESP-MESH permite que vários dispositivos (nódulos) se comuniquem entre si sob uma única rede local sem fio. Neste guia, mostraremos como começar com a ESP-MESH usando o núcleo Arduino.

"O ESP-MESH é um protocolo de rede construído no topo do protocolo Wi-Fi. O ESP-MESH permite que inúmeros dispositivos (chamados de nós) espalhados por uma grande área física (tanto dentro como ao ar livre) sejam interligados sob uma única WLAN (Wireless Local-Area Network)."

ARQUITETURA DE REDE WI-FI ATUAL

Em uma arquitetura de rede Wi-Fi tradicional, um único nó (ponto de acesso – geralmente o roteador) está conectado a todos os outros nós (estações). Cada nó pode se comunicar entre si usando o ponto de acesso. No entanto, isso se limita à cobertura wi-fi do ponto de acesso. Todas as estações devem estar no intervalo para se conectar diretamente ao ponto de acesso. Isso não acontece com a ESP-MESH.

ARQUITETURA DE REDE ESP-MESH

Com o ESP-MESH, os nós não precisam se conectar a um nó central. Nós são responsáveis por transmitir transmissões uns aos outros. Isso permite que vários dispositivos se espalhem por uma grande área física. Os Nós podem se auto-organizar e conversar dinamicamente uns com os outros para garantir que o pacote atinja seu destino final de nó. Se qualquer nó for removido da rede, ele será capaz de se auto-organizar para garantir que os pacotes cheguem ao seu destino.

Biblioteca PainlessMesh

"PainlessMesh é uma verdadeira rede ad-hoc, o que significa que não é necessário planejamento, controlador central ou roteador. Qualquer sistema de 1 ou mais nódulos se auto-organizará em malha totalmente funcional. O tamanho máximo da malha é limitado (pensamos) pela quantidade de memória no heap que pode ser alocada ao buffer de subconsoções e, portanto, deve ser realmente muito alta." 

Arduino  PlatformIO (Instalação)

1) Baixe e instale o Visual Studio Code


2) Execute o Visual Studio Code


3) Na opção EXTENSIONS (canto esquerdo), procure por PlatformIO e Instale. Aguarde!

4) Uma vez instalado o PlatformIO, vá em PIO Home e crie um Novo Projeto e digite os parâmetros abaixo e então Finish


Aguarde alguns minutos para instalação do SDK. A instalação do SDK ficará em 

C:\Users\USER\.platformio>
e os fontes em
C:\Users\USER\Documents\PlatformIO\Projects\blink\src\main.cpp

5) Na opção EXPLORER você verá o projeto e o código fonte (Arduino Sintax). 


6) Observe o arquivo Platformio.ini que foi criado, você pode futuramente mudar para aceitar outro tipo de framework, como exemplo, ESP-IDF.

[env:nina_w10]
platform = espressif32
board = nina_w10
framework = arduino

Exemplo básico ESP-MESH (mensagens de transmissão)

Para começar com esp-MESH, vamos primeiro experimentar com o exemplo básico da biblioteca. Este exemplo cria uma rede de malha na qual todas as placas transmitem mensagens para todas as outras placas.

Experimentamos este exemplo com quatro placas NINA W106. Você pode adicionar ou remover placas. 

Copie o código abaixo para o Arduino  - PlatformIO

/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp-mesh-esp32-esp8266-painlessmesh/
  
  This is a simple example that uses the painlessMesh library: https://github.com/gmag11/painlessMesh/blob/master/examples/basic/basic.ino
*/

#include "painlessMesh.h"

#define   MESH_PREFIX     "whateverYouLike"
#define   MESH_PASSWORD   "somethingSneaky"
#define   MESH_PORT       5555

  Scheduler userScheduler; // to control your personal task
  painlessMesh  mesh;

// User stub
void sendMessage() ; // Prototype so PlatformIO doesn't complain

Task taskSendMessageTASK_SECOND * 1 , TASK_FOREVER, &sendMessage );

void sendMessage() {
  String msg = "Ola do no 1";
  msg += mesh.getNodeId();
  mesh.sendBroadcastmsg );
  taskSendMessage.setIntervalrandom( TASK_SECOND * 1, TASK_SECOND * 5 ));
}

// Needed for painless library
void receivedCallbackuint32_t fromString &msg ) {
  Serial.printf("startHere: Received from %u msg=%s\n"frommsg.c_str());
}

void newConnectionCallback(uint32_t nodeId) {
    Serial.printf("--> startHere: New Connection, nodeId = %u\n"nodeId);
}

void changedConnectionCallback() {
  Serial.printf("Changed connections\n");
}

void nodeTimeAdjustedCallback(int32_t offset) {
    Serial.printf("Adjusted time %u. Offset = %d\n"mesh.getNodeTime(),offset);
}

void setup() {
  Serial.begin(115200);

//mesh.setDebugMsgTypes( ERROR | MESH_STATUS | CONNECTION | SYNC | COMMUNICATION | GENERAL | MSG_TYPES | REMOTE ); // all types on
  mesh.setDebugMsgTypes( ERROR | STARTUP );  // set before init() so that you can see startup messages

  mesh.initMESH_PREFIXMESH_PASSWORD, &userSchedulerMESH_PORT );
  mesh.onReceive(&receivedCallback);
  mesh.onNewConnection(&newConnectionCallback);
  mesh.onChangedConnections(&changedConnectionCallback);
  mesh.onNodeTimeAdjusted(&nodeTimeAdjustedCallback);

  userScheduler.addTasktaskSendMessage );
  taskSendMessage.enable();
}

void loop() {
  // it will run the user scheduler as well
  mesh.update();
}

Adicione em PlatformIO.ini

lib_deps = painlessmesh/painlessMesh @ ^1.4.5
    ArduinoJson
    arduinoUnity
    TaskScheduler
    AsyncTCP


Antes de carregar o código, você pode configurar o MESH_PREFIX (é como o nome da rede MESH) e as variáveis MESH_PASSWORD (você pode defini-lo para o que quiser).

Em seguida, recomendamos que você altere a seguinte linha para cada placa para identificar facilmente o nó que enviou a mensagem. Por exemplo, para o nó 1, altere a mensagem da seguinte forma:

Como funciona o código

Comece incluindo a biblioteca PainlessMesh.

#include "painlessMesh.h"

Detalhes MESH
Em seguida, adicione os detalhes da malha. O MESH_PREFIX se refere ao nome da malha. Você pode alterá-lo para o que quiser.

#define MESH_PREFIX "o que quiser"
A MESH_PASSWORD, como o nome sugere, é a senha do mesh. Você pode alterá-lo para o que quiser.

#define MESH_PASSWORD "suasenha"
Todos os nós na malha devem usar o mesmo MESH_PREFIX e MESH_PASSWORD.

O MESH_PORT refere-se à porta TCP na qual você deseja que o servidor mesh seja executado. O padrão é 5555.

# define MESH_PORT 5555

#define   MESH_PREFIX     "o que quiser"
#define   MESH_PASSWORD   "suasenha"
#define   MESH_PORT       5555

Agendador (Scheduler)

É recomendado evitar o uso de delay() no código de rede mesh. Para manter a malha, algumas tarefas precisam ser realizadas em segundo plano. Usar delay() interromperá essas tarefas e pode fazer com que a malha perca estabilidade/desmorone.

Em vez disso, é recomendado usar TaskScheduler para executar suas tarefas que são usadas no próprio painlessMesh.

A linha a seguir cria um novo Scheduler chamado userScheduler.

Scheduler userScheduler; // para controlar sua tarefa pessoal

Scheduler userScheduler; // 

painlessMesh

Crie um objeto painlessMesh chamado mesh para lidar com a rede em malha.

painlessMesh  mesh;

Crie tarefas

Crie uma tarefa chamada taskSendMessage responsável por chamar a função sendMessage() a cada segundo enquanto o programa estiver em execução.

Task taskSendMessageTASK_SECOND * 1 , TASK_FOREVER, &sendMessage );

Envie uma mensagem para o Mesh

A função sendMessage() envia uma mensagem para todos os nós na rede de mensagens (broadcast).

void sendMessage() {
  String msg = "Ola do no 1";
  msg += mesh.getNodeId();
  mesh.sendBroadcastmsg );
  taskSendMessage.setIntervalrandom( TASK_SECOND * 1, TASK_SECOND * 5 ));
}

A mensagem contém o texto “Ola do no 1” seguido pelo ID do chip da placa.

String msg = "Olá do nó 1";
msg + = mesh.getNodeId();

Para transmitir uma mensagem, basta usar o método sendBroadcast() no objeto mesh e passar como argumento a mensagem (msg) que deseja enviar.

mesh.sendBroadcastmsg );

Cada vez que uma nova mensagem é enviada, o código muda o intervalo entre as mensagens (um a cinco segundos).

taskSendMessage.setIntervalrandom( TASK_SECOND * 1, TASK_SECOND * 5 ));

Funções de retorno de chamada de malha

A seguir, várias funções de retorno de chamada são criadas e serão chamadas quando eventos específicos acontecerem na malha.

A função receivedCallback() imprime o remetente da mensagem (de) e o conteúdo da mensagem (msg.c_str ()).

// Needed for painless library
void receivedCallbackuint32_t fromString &msg ) {
  Serial.printf("startHere: Received from %u msg=%s\n"frommsg.c_str());
}

A função newConnectionCallback() é executada sempre que um novo nó se conecta à rede. Esta função simplesmente imprime o ID do chip do novo nó. Você pode modificar a função para fazer qualquer outra tarefa.

void newConnectionCallback(uint32_t nodeId) {
    Serial.printf("--> startHere: New Connection, nodeId = %u\n"nodeId);
}

A função changedConnectionCallback() é executada sempre que uma conexão muda na rede (quando um nó entra ou sai da rede).

void changedConnectionCallback() {
  Serial.printf("Changed connections\n");
}

A função nodeTimeAdjustedCallback() é executada quando a rede ajusta a hora, para que todos os nós sejam sincronizados. Ele imprime o deslocamento.

void nodeTimeAdjustedCallback(int32_t offset) {
    Serial.printf("Adjusted time %u. Offset = %d\n"mesh.getNodeTime(),offset);
}

Setup

Em setup(), inicialize o monitor serial.

void setup() {
  Serial.begin(115200);

Escolha as mensagens de Debug

//mesh.setDebugMsgTypes( ERROR | MESH_STATUS | CONNECTION | SYNC | COMMUNICATION | GENERAL | MSG_TYPES | REMOTE ); // all types on
  mesh.setDebugMsgTypes( ERROR | STARTUP );  // set before init() so that you can see startup messages


Inicialize a malha com os detalhes definidos anteriormente.

 mesh.initMESH_PREFIXMESH_PASSWORD, &userSchedulerMESH_PORT );

Atribua todas as funções de retorno de chamada aos eventos correspondentes.

  mesh.initMESH_PREFIXMESH_PASSWORD, &userSchedulerMESH_PORT );
  mesh.onReceive(&receivedCallback);
  mesh.onNewConnection(&newConnectionCallback);
  mesh.onChangedConnections(&changedConnectionCallback);
  mesh.onNodeTimeAdjusted(&nodeTimeAdjustedCallback);

Finalmente, adicione a função taskSendMessage ao userScheduler. O Scheduler é responsável por lidar e executar as tarefas no momento certo.

userScheduler.addTasktaskSendMessage );

Por fim, habilite o taskSendMessage, para que o programa comece a enviar as mensagens para a malha.

taskSendMessage.enable();

Para manter a malha em execução, adicione mesh.update() ao loop().

void loop() {
  // it will run the user scheduler as well
  mesh.update();
}

Testes

Faça upload do código fornecido para todas as suas placas. Não se esqueça de modificar a mensagem para identificar facilmente o nó emissor

Com as placas conectadas ao seu computador, abra uma conexão serial com cada placa. Você pode usar o Serial Monitor ou um software como o PuTTY e abrir várias janelas para todas as placas.

Você deve ver que todos os fóruns recebem mensagens uns dos outros. Por exemplo, essas são as mensagens recebidas pelo Nó 1. Ele recebe as mensagens dos Nó 2, 3 e 4.

ESP-MESH Básico Exemplo 4 Placas Arduino Serial Monitor

Testes com 4 NINA W106


2 NINA W106

3 NINA W106

Duvidas:
suporte@smartcore.com.br

REFERÊNCIAS
https://github.com/espressif/esp-mdf
https://github.com/espressif/esp-mdf/tree/master/examples/get-started
ESP-MESH with ESP32 and ESP8266: Getting Started | Random Nerd Tutorials

Sobre a SMARTCORE

A SmartCore fornece módulos para comunicação wireless, biometria, conectividade, rastreamento e automação.
Nosso portfólio inclui modem 2G/3G/4G/NB-IoT/Cat.M, satelital, módulos WiFi, Bluetooth, GNSS / GPS, Sigfox, LoRa, leitor de cartão, leitor QR code, mecanismo de impressão, mini-board PC, antena, pigtail, LCD, bateria, repetidor GPS e sensores.
Mais detalhes em www.smartcore.com.br

 

sexta-feira, 22 de novembro de 2019

NINA W102 MESH

REDE MESH COM ESP-MDF


O objetivo deste BLOG é demonstrar como é possível utilizar o módulo NINA W102 para implementar um rede MESH. Foram utilizados 2 NINA W102, um como nó raíz (ROOT) e o outro como nó não raíz.

O ESP-MDF, ou Espressif Mesh Development Framework, é uma estrutura de desenvolvimento para o ESP-MESH, um protocolo de rede construído sobre o protocolo Wi-Fi. O ESP-MDF é baseado no chip ESP32.

Visão global
O ESP-MDF é baseado na pilha de protocolos ESP-MESH para facilitar o desenvolvimento do ESP-MESH. O ESP-MDF fornece os seguintes recursos:

Configuração rápida de rede: além da configuração manual com os aplicativos de configuração de rede, como o ESP-MESH App ou aplicativos de terceiros semelhantes, o ESP-MDF oferece uma maneira encadeada de configuração de rede, durante a qual os dispositivos estabelecem uma rede de forma autônoma e rápida, e formar uma área de cobertura maior.

Atualização estável: o processo de atualização tornou-se mais eficiente com recursos como retransmissão automática de fragmentos com falha, compactação de dados, reversão para uma versão anterior, verificação de firmware etc.

Depuração eficiente: são suportadas várias abordagens de depuração, como transmissão sem fio de logs e depuração sem fio, depuração por meio de um terminal de comando etc.

Controle de LAN: a rede pode ser controlada por um aplicativo, sensor etc.


Diversas demonstrações de aplicação: Oferece soluções abrangentes baseadas em ESP-MESH nas áreas de iluminação, etc.

Para implementação foi seguido o roteiro proposto em 
https://github.com/espressif/esp-mdf/tree/master/examples/get-started

Ele apresenta uma maneira rápida de construir uma rede ESP-MESH sem um roteador. Para executar este exemplo, você precisa de pelo menos duas placas de desenvolvimento, uma configurada como nó raiz e a outra como nó não raiz. Neste exemplo, todos os dispositivos são nós não raiz por padrão.

Nó raiz: existe apenas um nó raiz em uma rede ESP-MESH. As redes MESH podem ser diferenciadas por seus MESH_ID e canais.
Nó não raiz: inclua nós folha e nós intermediários, que selecionam automaticamente seus nós pai de acordo com as condições da rede.

Você precisa acessar o submenu Configuração de exemplo e configurar um dispositivo como nó raiz e os outros como nós não raiz com make menuconfig (Make) ou idf.py menuconfig (CMake).

Você também pode acessar o submenu Component config -> MDF Mwifi e configurar os parâmetros relacionados ao ESP-MESH, como número máximo de camadas, número de dispositivos conectados em cada camada, intervalo de transmissão etc.


Defina a função de retorno de chamada do evento;

Inicialize o wifi e inicie o ESP-MESH;

Crie uma função de manipulador de eventos:

Nós não raiz enviam o pacote de dados Hello root! ao nó raiz em um intervalo de três segundos e aguarde sua resposta;

O nó raiz responde o nó Hello done!quando recebe os dados.
Criar um timer: imprima no horário especificado as informações da rede ESP-MESH sobre as camadas, a força do sinal e a memória restante do nó pai.

O log do nó raiz ficaria assim:


Instale

Toolchain de configuração: configure de acordo com o sistema operacional do seu PC (Windows, Linux ou Mac OS).

Obtenha ESP-MDF:


git clone --recursive https://github.com/espressif/esp-mdf.git

Se você clonar sem a opção --recursive, navegue até o diretório esp-mdf e execute o comando git submodule update --init --recursive

Configure o caminho do ESP-MDF: O Toolchain usa a variável de ambiente MDF_PATH para acessar o ESP-MDF. A configuração dessa variável é semelhante à da variável IDF_PATH. Por favor, consulte Adicionar IDF_PATH ao perfil do usuário.


export MDF_PATH=~/esp/esp-mdf

Iniciar um projeto: A palavra project refere-se ao exemplo de comunicação entre dois dispositivos ESP-MESH.


cp -r $MDF_PATH/examples/get-started/ .
cd  get-started/
Build e Flash: Somente o número da porta serial precisa ser modificado. De resto, apenas mantenha a configuração padrão intacta.


make menuconfig (mude para 2MB, por causa do NINA W102)

Mude partition para
# Name,   Type, SubType,  Offset,   Size,  Flags
nvs,      data, nvs,      0x9000,   16k
otadata,  data, ota,      0xd000,   8k
phy_init, data, phy,      0xf000,   4k
ota_0,    app,  ota_0,    0x10000,  1M
#ota_1,    app,  ota_1,    ,         1920k
coredump, data, coredump, ,         64K
reserved, data, 0xfe,     ,         128K

make erase_flash flash
Debug
make monitor

Atualizar ESP-MDF:
cd ~/esp/esp-mdf
git pull
git submodule update --init --recursive

Colocando em execução em 2 NINA W102.






No repositório da Smartcore você pode pegar os bins e gravar respeitando os endereços abaixo!

0xd000    ota_data_initial.bin 
0x1000    bootloader.bin 
0x10000  get-started.bin 
0x8000    partitions.bin

Com um ROOT e 2 NODOS





Duvidas:
suporte@smartcore.com.br

REFERÊNCIAS
https://github.com/espressif/esp-mdf
https://github.com/espressif/esp-mdf/tree/master/examples/get-started

Sobre a SMARTCORE

A SmartCore fornece módulos para comunicação wireless, biometria, conectividade, rastreamento e automação.
Nosso portifólio inclui modem 2G/3G/4G/NB-IoT/Cat.M, satelital, módulos WiFi, Bluetooth, GNSS / GPS, Sigfox, LoRa, leitor de cartão, leitor QR code, mecanismo de impressão, mini-board PC, antena, pigtail, LCD, bateria, repetidor GPS e sensores.
Mais detalhes em www.smartcore.com.br