quinta-feira, 21 de maio de 2020

NINA B302 E ETHERNET RESPONDENDO A COMANDOS DO ASSISTENTE ALEXA

U-BLOX NINA B302 E ETHERNET 802.3 (BLYNK) COM ALEXA
 MÉTODO RÁPIDO VIA SINRIC

O objetivo deste BLOG é demonstrar como é possível utilizar o ARDUINO para programar o módulo U-BLOX NINA B302 para ter acesso a INTERNET via 802.3, por meio do módulo ENC28J60. Foi utilizado o BREAKOUT NINA B302 para o teste. Uma vez conectado na Internet, poderá receber comandos enviados pelo ASSISTENTE ALEXA!

Turn On Device e Turn Off Devices são uma das palavras chaves para a assistente Alexa. Ao falar estes comandos um Relê será Ligado e Desligado e uma mensagem ao APP BLYNK também será enviado.

SMARTCORE

A SmartCore fornece módulos para comuniçã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

ENC28J60
O módulo Ethernet ENC28J60 utiliza o novo IC controlador controlador independente Microchip ENC28J60 com uma série de recursos para lidar com a maioria dos requisitos de protocolo de rede. A placa se conecta diretamente à maioria dos microcontroladores com uma interface SPI padrão com uma velocidade de transferência de até 20MHz.

 SINRIC

Utilizado também também para testar o EndDevice

Com Sinric, você pode conectar sua placa de desenvolvimento IOT com a Alexa através de uma Skill confiável

Vamos começar:

1. Acesse https://sinric.com/

2. Crie uma conta gratuita e faça log in

3. Pelo aplicativo da Alexa, ou pelo site, instale e ative a skill "Sinric"

4. Crie um novo dispositivo, como por exemplo uma TV. Anote o token de autorização, a chave de autenticação e o ID de se novo dispositivo.

5. O aplicativo da Alexa irá mostrar uma notificação informando que encontrou um novo dispositivo.

7. Carrego o exemplo abaixo em seu sketch 

Altere o token, chave de autenticação e dados do WiFI com os seus próprios.

ASSISTENTE ALEXA

O Amazon Alexa é um serviço de voz na nuvem da Amazon que permite que os desenvolvedores controlem por voz os serviços da Amazon conectados. Um aplicativo exemplo é o Amazon Echo, que é um assistente de controle de voz. Quando os usuários falam com o Amazon Echo, ele analisa a voz recebida e faz uma resposta apropriada. Neste exemplo, apresenta-se como conectar os serviços da Amazon (incluindo o Amazon Alexa, o AWS Lambda, o AWS IoT Core, o AWS IAM).

Skill

O Amazon Alexa Skills Kit (ASK) é um serviço de voz. Ele pode ser conectado a serviços da nuvem e o usuário pode controlar por voz os serviços conectados e receber resposta de voz. O recurso de análise de voz fornecido pelo Amazon Alexa está pronto para uso, faz com que os desenvolvedores possam se concentrar no design do serviço em nuvem e no modelo de interação do usuário.

Instalando Arduino Adafruit no NINA B302


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




como "URL adicional do gerenciador de pastas"

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.


Gravando bootloader da Adafruit

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 ...



...nestes pinos da placa BREAKOUT


Você pode também usar o ST-LINK V2



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



Futuramente altere arquivo variant.cpp para que as GPIOS sejam os mesmos do NINA B302, atualmente estão para o ADAFRUIT FEATHER EXPRESS.

Copie 

Criado pelo Autor

variant.h
viariant.cpp





ÓTIMA REFERENCIA PARA PINOS DO ARDUINO E PINOS (GPIOS) DO NINA B302


Consulte

Instalando LIBS no NINA B302


1) UIPEthernet


Ver LINK

"
  1. To fix UIPEthernet, just copy these following files into the UIPEthernet directory to overwrite the old files:
"
Em
Enc28J60Network.cpp adicione

void Enc28J60Network::init(uint8_t* macaddr) { Serial.print("ENC28J60_CONTROL_CS ="); Serial.println(ENC28J60_CONTROL_CS); Serial.print("SS ="); Serial.println(SS); Serial.print("SPI_MOSI ="); Serial.println(SPI_MOSI); Serial.print("SPI_MISO ="); Serial.println(SPI_MISO); Serial.print("SPI_SCK ="); Serial.println(SPI_SCK);

e

// For nRF52 #define ENC28J60_USE_SPILIB true uint8_t ENC28J60ControlCS = 10; //ENC28J60_CONTROL_CS;

2) WEBSOCKETS


Veja o README

3) Abra o exemplo NRF52_BLYNK_ENC_ALEXA.INO

Mude as credenciais.

4) Código fonte

/**************************************************************************************************************************** nRF52_Blynk_ENC_Alexa.ino For nRF52 using ENC28J60 Shield/Module BlynkEthernet_WM is a library for Teensy, ESP, SAM DUE and SAMD boards, with Ethernet W5X00 or ENC28J60 shields, to enable easy configuration/reconfiguration and autoconnect/autoreconnect of Ethernet/Blynk AVR Mega and W5100 is not supported. Library modified from Blynk library v0.6.1 https://github.com/blynkkk/blynk-library/releases Built by Khoi Hoang https://github.com/khoih-prog/BlynkEthernet_WM Licensed under MIT license Version: 1.0.16 Based on and modified from WebSockets libarary https://github.com/Links2004/arduinoWebSockets to support other boards such as SAMD21, SAMD51, Adafruit's nRF52 boards, etc. Built by Khoi Hoang https://github.com/khoih-prog/WebSockets_Generic Licensed under MIT license Version: 2.1.3 Created on: 24.05.2015 Author: Markus Sattler Version Modified By Date Comments ------- ----------- ---------- ----------- 2.1.3 K Hoang 15/05/2020 Initial porting to support SAMD21, SAMD51, nRF52 boards, such as AdaFruit Feather nRF52832, nRF52840 Express, BlueFruit Sense, Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, etc. *****************************************************************************************************************************/ #include "defines.h" #include "Credentials.h" #include "dynamicParams.h" #define DEBUG_SETUP 2 //Last device status, to minimize reporting / updating traffic //Only report / update when current status != last satus bool lastDevice_01_ON; #define RELAY_PIN_1 5 #include <WebSocketsClient_Generic.h> // get it from https://github.com/khoih-prog/WebSockets_Generic #include <ArduinoJson.h> // get it from https://arduinojson.org/ or install via Arduino library manager WebSocketsClient webSocket; uint64_t heartbeatTimestamp = 0; bool isConnected = false; void setPowerStateOnServer(String deviceId, String value); //To increase no of devices as needed void turnOn(String deviceId) { if (deviceId == SINRIC_Device_ID_1) // Device ID of 1st device { #if (DEBUG_SETUP > 1) Serial.print("Turn on device id: "); Serial.println(deviceId); #endif digitalWrite(RELAY_PIN_1, HIGH); } else { #if (DEBUG_SETUP > 1) Serial.print("Turn on for unknown device id: "); Serial.println(deviceId); #endif } } //To increase no of devices as needed void turnOff(String deviceId) { if (deviceId == SINRIC_Device_ID_1) // Device ID of 1st device { #if (DEBUG_SETUP > 1) Serial.print("Turn off Device ID: "); Serial.println(deviceId); #endif digitalWrite(RELAY_PIN_1, LOW); } else { #if (DEBUG_SETUP > 1) Serial.print("Turn off for unknown device id: "); Serial.println(deviceId); #endif } } void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { switch (type) { case WStype_DISCONNECTED: isConnected = false; #if (DEBUG_SETUP > 0) Serial.printf("[WSc] Webservice disconnected from sinric.com!\n"); #endif break; case WStype_CONNECTED: { isConnected = true; #if (DEBUG_SETUP > 0) Serial.printf("[WSc] Service connected to sinric.com at url: %s\n", payload); Serial.printf("Waiting for commands from sinric.com ...\n"); #endif } break; case WStype_TEXT: { #if (DEBUG_SETUP > 1) Serial.printf("[WSc] get text: %s\n", payload); #endif // Example payloads // For Switch or Light device types // {"deviceId": xxxx, "action": "setPowerState", value: "ON"} // https://developer.amazon.com/docs/device-apis/alexa-powercontroller.html // For Light device type // Look at the light example in github #if (ARDUINOJSON_VERSION_MAJOR >= 6) DynamicJsonDocument json(1024); auto deserializeError = deserializeJson(json, (char*)payload); if ( deserializeError ) { Serial.println("JSON parseObject() failed"); return; } //serializeJson(json, Serial); #else DynamicJsonBuffer jsonBuffer; // Parse JSON string JsonObject& json = jsonBuffer.parseObject((char*)payload); // Test if parsing succeeds. if (!json.success()) { Serial.println("JSON parseObject() failed"); return; } #endif String deviceId = json ["deviceId"]; String action = json ["action"]; if (action == "setPowerState") { // Switch or Light String value = json ["value"]; if (value == "ON") { turnOn(deviceId); } else { turnOff(deviceId); } } else if (action == "SetTargetTemperature") { String deviceId = json ["deviceId"]; String action = json ["action"]; String value = json ["value"]; } else if (action == "test") { #if (DEBUG_SETUP > 1) Serial.println("[WSc] received test command from sinric.com"); #endif } } break; case WStype_BIN: #if (DEBUG_SETUP > 1) Serial.printf("[WSc] get binary length: %u\n", length); #endif break; } } // If you are going to use a push button to on/off the switch manually, use this function to update the status on the server // so it will reflect on Alexa app. // eg: setPowerStateOnServer("deviceid", "ON") void setPowerStateOnServer(String deviceId, String value) { #if (ARDUINOJSON_VERSION_MAJOR >= 6) DynamicJsonDocument root(1024); #else DynamicJsonBuffer jsonBuffer; JsonObject& root = jsonBuffer.createObject(); #endif root["deviceId"] = deviceId; root["action"] = "setPowerState"; root["value"] = value; //StreamString databuf; String databuf; #if (ARDUINOJSON_VERSION_MAJOR >= 6) serializeJson(root, databuf); #else root.printTo(databuf); #endif webSocket.sendTXT(databuf); } // Create VirtualLEDs bound to Virtual Pins to reflect the status of PINs WidgetLED LED_D1(V1); #define BLYNK_STATUS_UPDATE_INTERVAL 2000 // in millisecs => 2 secs BlynkTimer timer; void updateBlynkStatus( void ) { // Give Blynk the current status to display on user's Blynk screen if (digitalRead(RELAY_PIN_1)) { if (!lastDevice_01_ON) { LED_D1.on(); //Update for Alexa setPowerStateOnServer(SINRIC_Device_ID_1, "ON"); } lastDevice_01_ON = true; } else { if (lastDevice_01_ON) { LED_D1.off(); //Update for Alexa setPowerStateOnServer(SINRIC_Device_ID_1, "OFF"); } lastDevice_01_ON = false; } } void myTimerEvent(void) { updateBlynkStatus(); } void heartBeatPrint(void) { static int num = 1; if (Blynk.connected()) Serial.print(F("B")); else Serial.print(F("F")); if (num == 80) { Serial.println(); num = 1; } else if (num++ % 10 == 0) { Serial.print(F(" ")); } } void check_status() { static unsigned long checkstatus_timeout = 0; #define STATUS_CHECK_INTERVAL 10000L // Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change. if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0)) { heartBeatPrint(); checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL; } } void setup() { //Assuming all devices on, to be safe, we have to turn off all of them later by calling updateBlynkStatus() //Call only after Blynk and Alexa / SINRIC already initialized lastDevice_01_ON = true; pinMode(RELAY_PIN_1, OUTPUT); digitalWrite(RELAY_PIN_1, LOW); // Debug console Serial.begin(115200); while (!Serial); #if USE_BLYNK_WM #if ( USE_LITTLEFS || USE_SPIFFS) Serial.println("\nStart ENC28J60_Blynk using " + String(CurrentFileFS) + " on " + String(BOARD_TYPE)); #else Serial.println("\nStart ENC28J60_Blynk on " + String(BOARD_TYPE)); #endif Blynk.begin(); #else #if USE_LOCAL_SERVER Serial.println("\nStart ENC28J60_Blynk, no WM, on " + String(BOARD_TYPE) + String(" using Local Server")); Blynk.begin(auth, server, BLYNK_HARDWARE_PORT); #else Serial.println("\nStart ENC28J60_Blynk, no WM, on " + String(BOARD_TYPE) + String(" using Cloud Server")); //Blynk.begin(auth); // You can also specify server: Blynk.begin(auth, server, BLYNK_HARDWARE_PORT); #endif #endif // Setup a function to be called every BLYNK_STATUS_UPDATE_INTERVAL/1000 seconds timer.setInterval(BLYNK_STATUS_UPDATE_INTERVAL, myTimerEvent); // server address, port and URL //webSocket.begin("iot.sinric.com", 80, "/"); webSocket.begin(SINRIC_WEBSERVER, SINRIC_WEBSERVER_PORT, "/"); // event handler webSocket.onEvent(webSocketEvent); webSocket.setAuthorization("apikey", SINRIC_API_KEY); // try again every SINRIC_WEBSOCKET_RETRY_TIME = 5000ms if connection has failed // If you see 'class WebSocketsClient' has no member named 'setReconnectInterval' error update arduinoWebSockets webSocket.setReconnectInterval(SINRIC_WEBSOCKET_RETRY_TIME /*5000*/); //Call only after Blynk and Alexa / SINRIC already initialized updateBlynkStatus(); } #if (USE_BLYNK_WM && USE_DYNAMIC_PARAMETERS) void displayCredentials(void) { Serial.println("\nYour stored Credentials :"); for (int i = 0; i < NUM_MENU_ITEMS; i++) { Serial.println(String(myMenuItems[i].displayName) + " = " + myMenuItems[i].pdata); } } #endif void loop() { Blynk.run(); timer.run(); check_status(); webSocket.loop(); if (isConnected) { uint64_t now = millis(); // Send heartbeat in order to avoid disconnections during ISP resetting IPs over night. Thanks @MacSass if ((now - heartbeatTimestamp) > HEARTBEAT_INTERVAL) { heartbeatTimestamp = now; webSocket.sendTXT("H"); } } #if (USE_BLYNK_WM && USE_DYNAMIC_PARAMETERS) static bool displayedCredentials = false; if (!displayedCredentials) { for (int i = 0; i < NUM_MENU_ITEMS; i++) { if (!strlen(myMenuItems[i].pdata)) { break; } if ( i == (NUM_MENU_ITEMS - 1) ) { displayedCredentials = true; displayCredentials(); } } } #endif }

5) Compile e grave



6) Ligue o ENC28J60 no B302 conforme esquemas abaixo

static const uint8_t SS   = (4);----> CS  (ENC28J60)
static const uint8_t MOSI = PIN_SPI_MOSI; ----> SI (ENC28J60)
static const uint8_t MISO = PIN_SPI_MISO;----> SO (ENC28J60)
static const uint8_t SCK  = PIN_SPI_SCK;----> SCK      (ENC28J60)

#define PIN_SPI_MISO         (24)    //24 original   IO8
#define PIN_SPI_MOSI         (25)    //25 original   IO3
#define PIN_SPI_SCK          (26)    //26 original    IO45

// D24 .. D26 (aka SPI pins)
  32,  // D24 is P1.00 (SPI MISO)
  15,  // D25 is P0.15 (SPI MOSI)
   7,  // D26 is P0.07 (SPI SCK )
  14,  // D10 is P0.14


7) Executando aplicação no NINA B302


8) Executando Aplicação no ALEXA APP (SKILL SINRIC)





Alexa SKILL

Comando de voz Liga / Desliga LED 
WidgetLED LED_D1(V1);





Questões: suporte@smartcore.com.br

FONTES: 
THANKS TO Khoi Hoang

https://www.arduino.cc
https://raw.githubusercontent.com/sparkfun/Arduino_Boards/nrf5/IDE_Board_Manager/package_sparkfun_index.json
https://github.com/khoih-prog/EthernetWebServer
https://www.microchip.com/wwwproducts/en/en022889
https://www.elecrow.com/enc28j60-ethernet-module-p-587.html
 

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

 

Nenhum comentário:

Postar um comentário