O objetivo deste BLOG é demonstrar como é possível acessar o NINA B302 (em uma rede LAN) de qualquer parte do mundo.
O exemplo programará o ROUTER para que direcione os acessos via WAN para a LAN, onde está o NINA B302 rodando uma aplicação WEB SERVER.
O exemplo também atualizará a tabela de DNS (DUCKDNS.ORG) para que sempre tenha o acesso ao IP PÚBLICO de sua máquina e então o IP LOCAL onde está o seu NINA B302.
Veja a vantagem:
Muitos de nós estão encaminhando manualmente a porta no dispositivo de gateway da Internet (IGD, roteador) para fornecer acesso aos serviços da Web locais da Internet.
Esta biblioteca fornece a maneira mais fácil de encaminhar automaticamente a porta usando o Simple Service Discovery Protocol (SSDP).
O SSDP fornece um mecanismo pelo qual clientes de rede, com pouca ou nenhuma configuração estática, podem descobrir serviços de rede. O SSDP consegue isso fornecendo suporte de descoberta multicast, bem como notificação baseada em servidor e roteamento de descoberta.
O SSDP é usado para anúncio e descoberta de serviços de rede e informações de presença. Ele realiza a tarefa sem assistência de mecanismos de configuração baseados em servidor, como protocolo de configuração dinâmica de hosts (DHCP) ou sistema de nomes de domínio (DNS), e sem configuração estática especial de um host de rede. O SSDP é a base do protocolo de descoberta de Universal Plug and Play (UPnP) e destina-se ao uso em ambientes residenciais ou de pequenos escritórios.
Esta biblioteca UPnP_Generic é criada para atualizar automaticamente seus IGDs com as informações de encaminhamento de porta solicitadas, usando uma das muitas placas / blindagens disponíveis. Consulte Placas atualmente suportadas.
O tempo entre as verificações para atualizar os mapeamentos de porta UPnP é configurável para corresponder ao seu caso de uso e é definido nos exemplos em 10 minutos. O LEASE_DURATION também é configurável e padrão para 10 horas (36000s). O nome do servidor virtual também pode ser especificado no esboço e é mostrado no IGD, por exemplo, NRF52-W5X00 ou ESP8266-WIFI.
O objetivo deste BLOG é mostrar um exemplo em ARDUINO que permite o NINA B302 se transformar num webserver WIFI, utilizando o W102 (COMANDOS AT) COMO COPROCESSOR WIFI 802.11.
Utilize a programação clássica com Sockets do Arduino! Compilei a última versão dos comandos AT disponível. Alguns pequenos bugs revolvidos!
Utilize a programação clássica com Sockets do Arduino! Compilei a última versão dos comandos AT disponível. Alguns pequenos bugs revolvidos!
COPROCESSOR PARA O NINA B302
MONTAGEM
Adquirimos então os seguintes componentes
-Botão de RESET;
-Botão de Modo BOOTLOADER (W102);
-Plugável no PROTOBOARD;
-Acesso às várias GPIOS;
Pequena
Abaixo o roteiro para você seguir:
Baixe e instale o Arduino IDE
Inicie o Arduino IDE, vá em Preferências e adicione
https://www.adafruit.com/package_adafruit_index.json
Abra o Boards Manager no menu Tools -> Board e instale o "Adafruit nRF52 by Adafruit"
Selecione sua placa nRF5 no menu Ferramentas -> Placa
Adafruit Bluefruit nRF52 Feather
OBSERVAÇÃO: Durante a instalação, o Arduino IDE leva alguns minutos para extrair as ferramentas após o download, por favor, seja paciente.
Use o gravador SEGGER JLINK para gravar o BREAKOUT com módulo NINA B302, conecte nos pinos do SWCLK (pino 7) e SWDIO (pino 9) do SEGGER JLINK nos pinos SWDCLK e SWDIO do BREAKOUT (pinos nas laterais, próximo à antena). Não esquecer de ligar os GND do BREAKOUT no GND do SEGGER JTAG, bem como alimentar o BREAKOUT com 3.3V.
Ligue os pinos SWD DIO e CLK ...
Abra J-FLASH lite e grave o bootloader da Adafruit
O mesmo se encontra em
....\packages\adafruit\hardware\nrf52\0.19.0\bootloader\feather_nrf52840_express
Compile depois para o NINA B302
https://github.com/adafruit/Adafruit_nRF52_Bootloader
Com ele, você poderá transferir programas via DFU USB. Maiores detalhes sobre este bootloader
https://learn.adafruit.com/introducing-the-adafruit-nrf52840-feather/update-bootloader
Segundo a documentação, se você pressionar o reset, o módulo aguardará por um certo tempo se há algo sendo enviado pelo Arduino, ou seja, o programa a ser gravado via DFU.
ATENÇÃO, o bootloader usa USB para gravação do NINA 302, OU SEJA, CRIA UMA COMM VIRTUAL, TAMBÉM PARA SER A SERIAL PADRÃO DO ARDUINO
INSTALE OS DRIVERS
https://github.com/adafruit/Adafruit_Windows_Drivers
Conecte na USB + e USB - um cabo USB, AGUARDE INSTALAR OS DRIVERS
Aqui você encontra variant.cpp e variant.h e boards.txt
https://ricardoadulis.sharepoint.com/:f:/r/sites/smartcore/Shared%20Documents/---%20SmartCore%20-%20tecnico%20publico/NINA%20B302/Arduino_variant?csf=1&web=1&e=7URfTD
Ao copiá-los e executar o ARDUINO teremos o NINA B302 na lista.
ÓTIMA REFERENCIA PARA PINOS DO ARDUINO E PINOS (GPIOS) DO NINA B302
https://www.u-blox.com/sites/default/files/NINA-B3_DataSheet_%28UBX-17052099%29.pdf
Ligue os pino do NINA B302 no NINA W102
INSTALE LIB AT WEBSERVER - EXEMPLOS QUE USAM AT COMMANDS (ESPRESSIF)
BREAKOUT B302 | BREAKOUT W102 | ||
TXD | IO23 | TXD | IO22 |
RXD | IO22 | RXD | IO23 |
GND | GND |
INSTALE LIB AT WEBSERVER - EXEMPLOS QUE USAM AT COMMANDS (ESPRESSIF)
Mude as credenciais no programa NRF52_SimpleServer e compile e pressione o botão para gravar
char ssid[] = "Andreia Oi Miguel 2.4G"; // your network SSID (name)
char pass[] = "xxxxxxxxxx"; // your network password
e descomente
// Uncomment to use ESP32-AT commands
#define USE_ESP32_AT true
Como podem observar, o programa será transferido!
Abra a serial
Abra o IP com seu BROWSER preferido via DUCKDNS ou localmente (LAN)
Abra a serial
DUCKDNS
LAN
/****************************************************************************************************************************
nRF52_SimpleServer.ino
For all Generic boards such as ESP8266, ESP32, SAMD21/SAMD51, nRF52, STM32F/L/H/G/WB/MP1
with WiFiNINA, ESP8266/ESP32 WiFi, ESP8266-AT, W5x00 Ethernet shields
DDNS_Generic is a library to automatically add port mappings to router using UPnP SSDP
(Simple Service Discovery Protocol) in order to provide access to the local Web Services from the Internet.
Based on and modified from Ofek Pearl's TinyUPnP Library (https://github.com/ofekp/TinyUPnP)
Built by Khoi Hoang https://github.com/khoih-prog/UPnP_Generic
Licensed under MIT license
Version: 3.1.4
Version Modified By Date Comments
------- ----------- ---------- -----------
3.1.4 K Hoang 23/09/2020 Initial coding for Generic boards using many WiFi/Ethernet modules/shields.
*****************************************************************************************************************************/
/*
Note: This example includes the library EasyDDNS. You'll have to add this package using your Arduino Library Manager.
The purpose of this package is to publish your dynamic IP to a DDNS service that will allocate a human readable
address to your current IP. If you do not need that, you can remove this dependency.
*/
#include "defines.h"
#define UPNP_USING_ETHERNET false
#define UPNP_USING_WIFI true
#include <UPnP_Generic.h>
#define LISTEN_PORT 7052
#define LEASE_DURATION 36000 // seconds
#define FRIENDLY_NAME "NRF52-WIFI-ESPAT" // this name will appear in your router port forwarding section
UPnP* uPnP;
ESP8266_AT_WebServer server(LISTEN_PORT);
const int led = 13;
int status = WL_IDLE_STATUS; // the Wifi radio's status
void onUpdateCallback(const char* oldIP, const char* newIP)
{
Serial.print("DDNSGeneric - IP Change Detected: ");
Serial.println(newIP);
}
void handleRoot()
{
#define BUFFER_SIZE 400
digitalWrite(led, 1);
char temp[BUFFER_SIZE];
int sec = millis() / 1000;
int min = sec / 60;
int hr = min / 60;
int day = hr / 24;
snprintf(temp, BUFFER_SIZE - 1,
"<html>\
<head>\
<meta http-equiv='refresh' content='5'/>\
<title>%s</title>\
<style>\
body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }\
</style>\
</head>\
<body>\
<h1>Hello from %s</h1>\
<h3>running UPnP_Generic & DDNS_Generic</h3>\
<h3>on %s</h3>\
<p>Uptime: %d d %02d:%02d:%02d</p>\
</body>\
</html>", BOARD_NAME, BOARD_NAME, SHIELD_TYPE, day, hr, min % 60, sec % 60);
server.send(200, "text/html", temp);
digitalWrite(led, 0);
}
void handleNotFound()
{
digitalWrite(led, 1);
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i = 0; i < server.args(); i++)
{
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/plain", message);
digitalWrite(led, 0);
}
void setup(void)
{
pinMode(led, OUTPUT);
digitalWrite(led, 0);
Serial.begin(115200);
while (!Serial);
Serial.print("\nStart nRF52_SimpleServer on " + String(BOARD_NAME));
Serial.println(" with " + String(SHIELD_TYPE));
// initialize serial for ESP module
EspSerial.begin(115200);
// initialize ESP module
WiFi.init(&EspSerial);
Serial.println(F("WiFi shield init done"));
// check for the presence of the shield
if (WiFi.status() == WL_NO_SHIELD)
{
Serial.println(F("WiFi shield not present"));
// don't continue
while (true);
}
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, pass);
// Wait for connection
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("");
IPAddress localIP = WiFi.localIP();
Serial.print("IP address: ");
Serial.println(localIP);
//Serial.print(F("Gateway IP : "));
//Serial.println(WiFi.gatewayIP());
////////////////
DDNSGeneric.service("duckdns"); // Enter your DDNS Service Name - "duckdns" / "noip"
/*
For DDNS Providers where you get a token:
DDNSGeneric.client("domain", "token");
For DDNS Providers where you get username and password: ( Leave the password field empty "" if not required )
DDNSGeneric.client("domain", "username", "password");
*/
DDNSGeneric.client("account.duckdns.org", "12345678-1234-1234-1234-123456789012");
DDNSGeneric.onUpdate(onUpdateCallback);
////////////////
uPnP = new UPnP(30000); // -1 means blocking, preferably, use a timeout value (ms)
if (uPnP)
{
uPnP->addPortMappingConfig(localIP, LISTEN_PORT, RULE_PROTOCOL_TCP, LEASE_DURATION, FRIENDLY_NAME);
bool portMappingAdded = false;
#define RETRY_TIMES 4
int retries = 0;
while (!portMappingAdded && (retries < RETRY_TIMES))
{
Serial.println("Add Port Forwarding, Try # " + String(++retries));
int result = uPnP->commitPortMappings();
portMappingAdded = ( (result == PORT_MAP_SUCCESS) || (result == ALREADY_MAPPED) );
//Serial.println("commitPortMappings result =" + String(result));
if (!portMappingAdded)
{
// for debugging, you can see this in your router too under forwarding or UPnP
//uPnP->printAllPortMappings();
//Serial.println(F("This was printed because adding the required port mapping failed"));
if (retries < RETRY_TIMES)
delay(10000); // 10 seconds before trying again
}
}
uPnP->printAllPortMappings();
Serial.println("\nUPnP done");
}
server.on("/", handleRoot);
server.on("/inline", []()
{
server.send(200, "text/plain", "this works as well");
});
server.onNotFound(handleNotFound);
server.begin();
Serial.print(F("HTTP EthernetWebServer is @ IP : "));
Serial.print(localIP);
Serial.print(", port = ");
Serial.println(LISTEN_PORT);
}
void loop(void)
{
DDNSGeneric.update(300000);
uPnP->updatePortMappings(600000); // 10 minutes
server.handleClient();
}
THANKS TO Khoi Hoang
suporte@smartcore.com.br
Referências:
https://nina-w102-at-commands.blogspot.com/2020/07/nina-w102-compilando-comandos-no.html
https://www.espressif.com/sites/default/files/documentation/4a-esp8266_at_instruction_set_en.pdf
https://www.u-blox.com/en/docs/UBX-17056481
https://www.u-blox.com/sites/default/files/NINA-B3_DataSheet_%28UBX-17052099%29.pdf
https://www.u-blox.com/en/docs/UBX-17056481
https://www.u-blox.com/sites/default/files/NINA-B3_DataSheet_%28UBX-17052099%29.pdf
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
Nenhum comentário:
Postar um comentário