fbpixel
Etiquetas: ,
0
(0)

,

Um recurso muito prático no campo da IoT é a capacidade de programar um microcontrolador conectado, como um ESP8266, via WiFi. Esta técnica é designada por Programação Over-The-Air (OTA).

Hardware

  • NodeMCU ESP8266
  • Cabo USB A macho
  • Computador
  • Rede WiFi

Princípio de funcionamento

Em princípio, o ESP8266 NodeMCU é programado através da porta USB. O computador comunica o programa ao microcontrolador. Quando dois dispositivos estão ligados à mesma rede WiFi, podem comunicar entre si. Assim, é possível carregar código através da rede WiFi sem ter de se ligar a cada microcontrolador.

É igualmente possível carregar um código no NodeMCU quando este está configurado como ponto de acesso WiFi. Neste caso, o computador utilizado para a programação deve estar ligado à rede do NodeMCU.

Adicionar firmware ArduinoOTA

A biblioteca ArduinoOTA está disponível quando se instala o gestor do ESP8266. Para configurar a programação OTA, é necessário instalar o firmware. Para o fazer, pode utilizar o exemplo BasicOTA.ino disponível no IDE Arduino.

Certifique-se de que substitui ssid e password pelos identificadores da sua rede WiFi.

#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>

#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK  "your-password"
#endif

const char* ssid = STASSID;
const char* password = STAPSK;

void setup() {
  Serial.begin(115200);
  Serial.println("Booting");
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("Connection Failed! Rebooting...");
    delay(5000);
    ESP.restart();
  }

  // Port defaults to 8266
  // ArduinoOTA.setPort(8266);

  // Hostname defaults to esp8266-[ChipID]
  // ArduinoOTA.setHostname("myesp8266");

  // No authentication by default
  // ArduinoOTA.setPassword("admin");

  // Password can be set with it's md5 value as well
  // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
  // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");

  ArduinoOTA.onStart([]() {
    String type;
    if (ArduinoOTA.getCommand() == U_FLASH) {
      type = "sketch";
    } else { // U_FS
      type = "filesystem";
    }

    // NOTE: if updating FS this would be the place to unmount FS using FS.end()
    Serial.println("Start updating " + type);
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) {
      Serial.println("Auth Failed");
    } else if (error == OTA_BEGIN_ERROR) {
      Serial.println("Begin Failed");
    } else if (error == OTA_CONNECT_ERROR) {
      Serial.println("Connect Failed");
    } else if (error == OTA_RECEIVE_ERROR) {
      Serial.println("Receive Failed");
    } else if (error == OTA_END_ERROR) {
      Serial.println("End Failed");
    }
  });
  ArduinoOTA.begin();
  Serial.println("Ready");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  ArduinoOTA.handle();
}

Tome nota do endereço IP local do aparelho (aqui: 192.168.1.78).

Quando este código tiver sido carregado através de comunicação série, poderá carregar um código através de Wifi. Prima o botão RST ou EN no seu ESP e reinicie o Arduino IDE.

Modificar o seu programa antes de o carregar

Colocamos o código de inicialização na função initOTA(). Assim, será fácil copiá-lo para outros projectos. E acrescentamos um ecrã na porta série para verificar se o código foi modificado.

ATENÇÃO: O código de inicialização do ArduinoOTA deve estar presente em todos os códigos que carregar ou perderá a capacidade de efectuar transmissões aéreas.

#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>

const char* ssid = "*******";
const char* password = "********";

unsigned long previousMillis;

void setup() {
  Serial.begin(115200);
  Serial.println("Booting");
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("Connection Failed! Rebooting...");
    delay(5000);
    ESP.restart();
  }

  initOTA();

  Serial.println("Ready");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  ArduinoOTA.handle();

  if (millis() - previousMillis >= 500) {
    previousMillis = millis();
    Serial.println(F("Code has been update"));
  }
}

void initOTA() {
  // Port defaults to 8266
  // ArduinoOTA.setPort(8266);

  // Hostname defaults to esp8266-[ChipID]
  // ArduinoOTA.setHostname("myesp8266");

  // No authentication by default
  // ArduinoOTA.setPassword("admin");

  // Password can be set with it's md5 value as well
  // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
  // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");

  ArduinoOTA.onStart([]() {
    String type;
    if (ArduinoOTA.getCommand() == U_FLASH) {
      type = "sketch";
    } else { // U_FS
      type = "filesystem";
    }

    // NOTE: if updating FS this would be the place to unmount FS using FS.end()
    Serial.println("Start updating " + type);
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) {
      Serial.println("Auth Failed");
    } else if (error == OTA_BEGIN_ERROR) {
      Serial.println("Begin Failed");
    } else if (error == OTA_CONNECT_ERROR) {
      Serial.println("Connect Failed");
    } else if (error == OTA_RECEIVE_ERROR) {
      Serial.println("Receive Failed");
    } else if (error == OTA_END_ERROR) {
      Serial.println("End Failed");
    }
  });
  ArduinoOTA.begin();
}

Depois de ter modificado o seu código, em “Ferramenta> Porta”, seleccione a sua placa entre as portas de rede. (Se a porta de rede não for apresentada, consulte a secção seguinte)

Pode então carregar o seu código como faria com a comunicação em série.

Seleccione novamente a porta série e abra o monitor série para verificar se o código foi modificado.

Se a porta de rede não for exibida no IDE do Arduino

Se a porta de rede não estiver presente nas opções do Arduino IDE, terá de fazer um pequeno trabalho. É necessário ir ao Centro de Rede e Partilha

De seguida, vá a “Modificar parâmetros do mapa”.

Clique com o botão direito do rato na sua rede e vá para propriedades

Pode então desmarcar a opção “Protocolo Internet versão 6 (TCP)”.

Se voltar ao Arduino IDE, em “Tool > Port” (Ferramenta > Porta) deve ver a opção de porta de rede.

Pode verificar novamente o IPv6 assim que a sua porta de rede for reconhecida.

Bónus: visualização de mensagens de série OTA

A possibilidade de carregar um programa via WiFi é muito útil, mas vale a pena notar que se perde a capacidade de depurar com o monitor de série. É possível criar uma interface Web que permita visualizar as informações do ESP8266 NodeMCU.

Aqui veremos como usar a biblioteca RemoteDebug para se conectar ao microcontrolador via telnet e recuperar as mensagens enviadas.

  • Comece por instalar a biblioteca descarregando o ficheiro ZIP ou através do gestor de bibliotecas.
  • Criar um objecto RemoteDebug Debug; depois de incluir o objecto
  • Inicialize a depuração com Debug.begin(“ESP8266”);
  • Em seguida, substitua todos os Serial.print por Debug.print
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <RemoteDebug.h>

const char* ssid = "******";
const char* password = "*******";

RemoteDebug Debug;

unsigned long previousMillis;

void setup() {
  Serial.begin(115200);
  Serial.println("Booting");
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("Connection Failed! Rebooting...");
    delay(5000);
    ESP.restart();
  }

  // init remote debug
  Debug.begin("ESP8266"); 
  
  initOTA();

  Serial.println("Ready");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  ArduinoOTA.handle();
  Debug.handle();
  
  if (millis() - previousMillis >= 500) {
    previousMillis = millis();
    Debug.println(F("Code has been update"));
  }
}

void initOTA() {
  // Port defaults to 8266
  // ArduinoOTA.setPort(8266);

  // Hostname defaults to esp8266-[ChipID]
  //ArduinoOTA.setHostname("ESP8266");

  // No authentication by default
  // ArduinoOTA.setPassword("admin");

  // Password can be set with it's md5 value as well
  // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
  // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");

  ArduinoOTA.onStart([]() {
    String type;
    if (ArduinoOTA.getCommand() == U_FLASH) {
      type = "sketch";
    } else { // U_FS
      type = "filesystem";
    }

    // NOTE: if updating FS this would be the place to unmount FS using FS.end()
    Serial.println("Start updating " + type);
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) {
      Serial.println("Auth Failed");
    } else if (error == OTA_BEGIN_ERROR) {
      Serial.println("Begin Failed");
    } else if (error == OTA_CONNECT_ERROR) {
      Serial.println("Connect Failed");
    } else if (error == OTA_RECEIVE_ERROR) {
      Serial.println("Receive Failed");
    } else if (error == OTA_END_ERROR) {
      Serial.println("End Failed");
    }
  });
  ArduinoOTA.begin();
}

Para visualizar as mensagens enviadas via RemoteDebug, vamos utilizar o software PuTTy que já vimos várias vezes. Para esta aplicação, vamos configurar o PuTTy no telnet usando o endereço IP obtido do monitor serial.

Fontes

How useful was this post?

Click on a star to rate it!

Average rating 0 / 5. Vote count: 0

No votes so far! Be the first to rate this post.

As you found this post useful...

Follow us on social media!

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?