IoT

Economizando Energia – Sleep Modes no ESP8266

Eletrogate 21 de abril de 2022

Introdução

Então, você construiu um projeto usando o Módulo WiFi ESP8266 NodeMcu v3 – Lolin conectado a uma bateria ou a um power bank. Mas, depois de um tempo, percebeu que a bateria não dura muito neste sistema. Como podemos resolver isso? Uma boa opção é usar o Sleep mode do ESP8266. Com a revolução da IoT, está crescendo, a cada dia, o número de dispositivos conectados. No futuro, a maioria dos dispositivos será conectada entre si e se comunicará em tempo real. Um dos problemas enfrentados por esses dispositivos é o consumo de energia. Esse fator é crítico e decisivo para qualquer dispositivo e projeto IoT. O ESP8266 é um dos módulos mais populares para qualquer projeto IoT. Neste artigo, aprendemos como economizar energia ao usar o ESP8266. Iremos carregar os dados do sensor de temperatura TMP36 para a nuvem utilizando WiFi e MQTT. Depois, o ESP8266 irá dormir por um intervalo de 30 segundos.


Tipos de Sleep

Existem 3 tipos de Sleep mode no ESP8266: Modem-sleep, Light-sleep e Deep-sleep.

ItemModem-sleepLight-sleepDeep-sleep
Wi-FiOFFOFFOFF
System clockONOFFOFF
RTCONONON
CPUONPendingOFF
Corrente consumida15 mA0.4 mA~20 uA
Corrente Média (DTIM = 1)16.2 mA1.8 mA
Corrente Média (DTIM = 3)15.4 mA0.9 mA
Corrente Média (DTIM = 10)15.2 mA0.55 mA

NOTA IMPORTANTE: O consumo de energia da tabela é referente ao ESP8266 chip. Se você estiver usando uma placa de desenvolvimento, eles têm componentes passivos que consomem mais corrente.

Modem-Sleep

Modo padrão para o ESP8266. No entanto, só é ativado quando você está conectado a um ponto de acesso. Enquanto estiver no modo de suspensão do modem, o ESP8266 reduzirá o consumo de modem (WiFi). Para isso, desliga o próprio modem entre os intervalos do DTIM Beacon. Este intervalo é definido pelo seu roteador.

Consumo: ~15mA.

Light-Sleep

Executa a mesma função que Modem-sleep, mas também desliga o relógio do sistema e suspende a CPU. A CPU não é desligada, fica pendente. Com este modo, é possível acordar o CPU com um sinal enviado (HIGH/LOW) para um pino definido no firmware, continuando seu código normalmente. Como o anterior, este modo também possui o “Automatic sleep”, que faz o MCU dormir entre os intervalos do DTIM.

Consumo: ~0.4mA.

Deep-Sleep

Tudo está desligado, exceto o Real Time Clock (RTC), usado pelo computador para mantém a medição de tempo. Esta é a melhor opção na questão de consumo, já que praticamente todo o MCU fica desligado. É útil quando precisamos, por exemplo, enviar dados de um sensor a cada 5 minutos para um banco de dados ou gravar na EEPROM para, futuramente, ser enviado, caso não haja conexão com a internet.

Consumo: ~20μA.

Para mais detalhes, leia a documentação.

Materiais necessários para os projetos de exemplo:

Para desenvolver os exemplos, iremos precisar de:

Forma de acordar
Depois de colocar o ESP8266 no modo Deep-sleep, existem diferentes maneiras de acorda-lo:

  1. Acordar por tempo: O ESP8266 acorda após um período de tempo predefinido;
  2. Acordar por interrupção externa (botão): O ESP8266 acorda quando você pressiona o botão RST (o ESP8266 é reiniciado).

Exemplo 1 - Deep-Sleep, Acordando com Tempo

Neste exemplo, é impresso na serial “Entrando em Deep-Sleep por 30 segundos”, adormecemos por 30 segundos, acordando, em seguida, e repetindo o ciclo.

É importante observar que o tempo de suspensão é em microssegundos (µs).

Circuito

Ligação Deep SleepLigação para o Deep Sleep

 

Para habilitar o Deep-sleep, precisamos vincular o pino RST ao GPIO 16 no ESP8266. No NodeMCU, o GPIO 16 é representado como D0.

Pinos do NodeMcu

Pinos do NodeMcu

Se dermos uma olhada na pinagem do NodeMCU, podemos ver que o GPIO 16 é o WAKE.

Código:

/**
 * Exemplo mostrando como colocar o ESP8266 no modo Deep-sleep
 */
 
void setup() {
  Serial.begin(115200);
  Serial.setTimeout(2000);

  while(!Serial) { }
  
  Serial.println("Acordado!");

  Serial.println("Entrando em Deep-Sleep por 30 segundos");
  ESP.deepSleep(30e6); // 30e6 = 30000000 microssegundos = 30 segundos
}

void loop() {
}

NOTA IMPORTANTE: Não conecte o GPIO16 ao RST antes de fazer o upload do código, pois você pode ter dificuldade em fazer o upload do código. Conecte o GPIO16 ao pino RST somente após o upload do código.

O pino RST é mantido em um sinal HIGH enquanto o ESP8266 está funcionando. No entanto, quando o pino RST recebe um sinal LOW, ele reinicia o microcontrolador.

ESP.deepSleep(30e6); // 30e6 = 30000000 microssegundos = 30 segundos

Após usar o comando acima, o MCU irá dormir até que o tempo acabe (30 segundos). Quando o tempo definido estourar (Acabar), o RTC irá gerar um pulso LOW no pino GPIO16, que está conectado ao pino RST, fazendo com que o MCU seja reiniciado completamente.


Exemplo 2 - Deep-Sleep, Acordando com Botão

Você também pode ativar o ESP8266 com um despertador externo, como pressionar uma chave botão R13-507 ou um interruptor magnético reed switch. Você só precisa colocar o ESP8266 no modo de deep-sleep por um período indefinido de tempo e, em seguida, definir o pino RST para LOW para acordar o ESP8266.

Para testar essa configuração, conecte um botão à sua placa ESP8266, conforme mostrado no diagrama esquemático a seguir. Quando você pressiona o botão, o pino RST fica LOW.

deep-sleep ligação externa

 

Código:

/**
 * Exemplo de como acordar o ESP8266 do modo Deep-sleep com botão 
 */
 
void setup() 
{
  Serial.begin(115200);
  Serial.setTimeout(2000);

  while(!Serial) { }
  
  Serial.println("Acordado!");

  Serial.println("Estou acordado, mas vou entrar no modo de deep sleep até que o pino RESET esteja conectado a um sinal LOW");
  ESP.deepSleep(0);
}

void loop() {}

Exemplo 3 - Deep-Sleep com Envio de Dados

Nesse exemplo, o ESP8266 envia a leitura do sensor de temperatura TMP36 para um serviço de MQTT gratuito (broker.mqtt-dashboard.com) a cada 30 segundos e dorme em seguida. Caso queira criar seu próprio broker, leia nosso post: Automação com Broker MQTT e Raspberry Pi

Circuito

Ligação para o deep sleep com sensor

Ligação para o deep sleep com sensor

Código:

/**
 * @file SleepMode_Test.ino
 * @author Saulo Aislan
 * @brief Firmware que ler o sensor de temperatura, envia os dados
 * via MQTT e entra no modo Deep Sleep, permanecendo por 30 segundos.
 * @version 0.1
 * 
 * @copyright Copyright (c) 2022
 * 
*/
 
/* Inclusão de bibliotecas */
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

/* WiFi credenciais */
const char* WIFI_SSID = "**********";
const char* WIFI_PASS = "**********";

/* MQTT credenciais */
const char* mqttServer = "broker.mqtt-dashboard.com";
const int mqttPort = 1883;

WiFiClient espClient;
PubSubClient client(espClient);

/**
 * @brief Conecta ao WiFi
 */
void connectToWifi()
{
  Serial.println();
  Serial.print("Conectando a ");
  Serial.println(WIFI_SSID);

  WiFi.begin(WIFI_SSID, WIFI_PASS);

  // WiFi fix: https://github.com/esp8266/Arduino/issues/2186
  WiFi.persistent(false);
  WiFi.mode(WIFI_OFF);
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASS);

  unsigned long wifiConnectStart = millis();

  while (WiFi.status() != WL_CONNECTED)
  {
    if (WiFi.status() == WL_CONNECT_FAILED)
    {
      Serial.println("Falha ao conectar no WiFi. Por favor verifique as credenciais: ");
    }

    delay(500);
    Serial.println("...");
    if (millis() - wifiConnectStart > 5000)
    {
      Serial.println("Falha ao conectar no WiFi");
      return;
    }
  }

  Serial.println("");
  Serial.println("WiFi conectado");
  Serial.println("IP: ");
  Serial.println(WiFi.localIP());
}


/**
 * @brief Envia os dados via MQTT
 * @param double tempC Temperatura em Celsius
 */
void publishMsg(double tempC)
{
  client.setServer(mqttServer, mqttPort);
  bool ret = false;
  String msg = "{Temperatura:" + String(tempC) + "}";
  
  while (!client.connected() && !ret)
  {
    Serial.println("Conectando ao MQTT...");
 
    if (client.connect("EletrogateClient"))
    {
      Serial.println("Conectado com Sucesso");  
      ret = client.publish("topic/eletrogate", (char*) msg.c_str()); 
      delay(5000);
    }
    else
    {
      Serial.print("Falha: ");
      Serial.print(client.state());
    }
  }
}

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

  while (!Serial) { }

  Serial.println("-------------------------------------");
  Serial.println("Rodando o Firmware de Deep Sleep!");
  Serial.println("-------------------------------------");

  connectToWifi(); /* Conecta ao WiFi */
  
  int temp = analogRead(A0); /* Pino do sensor de Tmeperatura */

  double tempC = (((temp / 1024.0) * 3.2) - 0.5) * 100.0; /* Conversão para Celsius */

  Serial.println();
  Serial.print("Temperatura: ");
  Serial.print(tempC);
  Serial.println(" C°");
  
  publishMsg(tempC); /* Envia os dados via MQTT */
  
  Serial.println("Entrando em Deep-Sleep por 30 segundos");
  ESP.deepSleep(30e6); // 30e6 is 30 microseconds
}
void loop(){}

Neste exemplo, o firmware executa os seguintes passos:

  • Conecte-se ao WiFi
  • Ler sensor de temperatura TMP36
  • Envia para o serviço MQTT
  • Dorme por 30 segundos
  • Repete o ciclo

Para visualizar os dados do broker MQTT, estou usando o MQTT Explorer, disponível nesse link. Mas, você pode usar o software de sua preferência. As configurações da conexão para esse exemplo são as seguintes:

Mqtt exeplorer

 

Devemos adicionar “topic/eletrogate” com QoS 0(zero) no tópico subscriberMQTT topico


Vídeo Demonstrativo

No vídeo podemos observar o ESP8266 conectando ao WiFi, coletando a temperatura, enviando via MQTT e indo dormir por 30 segundos. Também podemos observar o recebimento da temperatura no MQTT Explorer a cada 30 segundos.


Conclusão

Aprendemos sobre os diferentes modos de operação do ESP8266 e diferentes modos de suspensão. Agora que você sabe como colocar o ESP8266 para dormir, pode tornar seus projetos e dispositivos mais energicamente eficientes. Para mais materiais como esse, continue acompanhando as postagens semanais do blog e não deixe de visitar nossa loja. Lá, você encontra todos os componentes necessários para desenvolver esse e muitos outros projetos! Que a força estejam com vocês e até mais!

Tenha a Metodologia Eletrogate na sua Escola! Conheça nosso Programa de Robótica Educacional.


Sobre o Autor


Saulo Aislan

Graduando em Tecnologia em Telemática pelo IFPB – Campus de Campina Grande – PB. Tenho experiência com os microcontroladores da família Arduino, ESP8266, ESP32, STM32 e microprocessador Raspberry Pi. Tenho projetos na áreas de IoTs voltada para a indústria 4.0, agroindústria e indústria aeroespacial civil utilizando LoRa, Bluetooth, ZigBee e Wi-Fi. Atualmente estudando e desenvolvendo em FreeRTOS para sistemas em tempo real com ESP32 e LoRaWan para Smart City e compartilhando alguns projetos no blog da Eletrogate.


Eletrogate

21 de abril de 2022

A Eletrogate é uma loja virtual de componentes eletrônicos do Brasil e possui diversos produtos relacionados à Arduino, Automação, Robótica e Eletrônica em geral.

Conheça a Metodologia Eletrogate e Lecione um Curso de Robótica nas Escolas da sua Região!

Eletrogate Robô

Cadastre-se e fique por
dentro de novidades!