Sleep Modes - Economizando energia- ESP8266

Economizando energia

Atire a primeira pedra quem nunca pensou em fazer algo portátil com o ESP8266. Vamos aprender sobre os diversos modos de Sleep presente no ESP8266, desde o Modem Sleep até o Deep Sleep.

 

Por que Sleep em micro controladores?

Deixar o MCU ligado durante algum tempo ocioso, consome muita bateria desnecessariamente e torna inviável projetos portáteis, já que precisaríamos trocar constantemente a bateria ou pilha. Para isto, existem os Sleep modes, que adormecem certas funções do MCU, permitindo o uso em projetos portáteis.

Modem Sleep

Somente o rádio WiFi/Wireless do MCU é desligado, todo o resto do sistema continua ligado normalmente. É útil quando o envio de informações se faz em intervalos de tempos e que é preciso o funcionamento do sistema em geral, como por exemplo acender LEDs, fazer comunicações e etc. O rádio não fica completamente desligado, de acordo com os datasheet's, o ESP faz um gerenciamento entre os Beacons (DTIM) do seu roteador e desliga entre os intervalos definidos.

Consumo: ~15mA.

 

LightSleep

Rádio WiFi/Wireless e Clock interno são desligados. CPU fica pendente. Com este modo, é possível acordar o CPU com um sinal enviado (HIGH/LOW) para um pino definido no software, 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: ~400 μA.

 

Deep Sleep

Rádio WiFi/Wireless, CPU e CLOCK ficam desligados, Apenas o RTC continua ON. Este modo é o melhor 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.

 

Datasheet sobre os sleeps.

 

Como o foco deste material será a autonomia, será ensinado como é o funcionamento do Deep Sleep, já que tem o menor consumo e é facilmente configurado através do código. Caso você ainda não tenha conhecimento sobre os BOT's do Telegram, veja ESTE tutorial.

Faremos um sensor de luminosidade portátil, que irá detectar o nível de luz no local e enviar por um BOT no Telegram a mensagem para o nosso chat a cada 1 minuto. Entre os intervalos, entrará em Deep Sleep para poupar a bateria.

Este projeto poderá ser feito por qualquer ESP8266, porém é necessário que o GPIO16 (D0) esteja conectado ao RESET. O ESP8266 01 não conta com este pino fisicamente, entretanto, é possível liga-lo ao RESET da seguinte forma:

 

 

Mãos à obra

Componentes necessários

Para este projeto, usaremos novamente o NodeMCU, e também mostraremos o consumo dele durante o Deep-sleep.

 

Montando o projeto

Faça as ligações necessárias para se ler um LDR, conectado ao pino A0. Para o Deep Sleep acordar o MCU após o tempo definido, precisamos ligar o pino D0 ao RST.

 

Código do projeto

Não se esqueça de colocar as informações sobre seu WiFi, ID e TOKEN do Telegram. Ensinamos como pegar o ID no tutorial do Telegram, de uma olhada!

#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>

#define BOTtoken "1659677:AberDacEJadpENQS_mUTIvLfGQ5f6dQe"//Define o token do BOT.

WiFiClientSecure client;
UniversalTelegramBot bot(BOTtoken, client);

String ldr;

void setup()
{
   WiFi.mode(WIFI_STA);//Define o ESP como Station.
   WiFi.begin("SUA REDE", "SUA SENHA");//Conecta na rede.

   while (WiFi.status() != WL_CONNECTED)//Espera a conexão se estabelecer.
   {
      delay(1);
   }

   ldr += analogRead(A0);//Le o LDR.

   bot.sendSimpleMessage("SEU ID", ldr, "");//Envia o valor do LDR para o chat.

   ESP.deepSleep(1 * 60000000);//Dorme por 1 Minuto (Deep-Sleep em Micro segundos).
}

void loop()
{

}


Entendendo a fundo

Hardware

Para o Deep sleep funcionar corretamente, é preciso fazer a ligação do pino D0 (GPIO16) ao pino de RESET. Quando o RTC estoura o tempo (Overflow), é gerado um pulso LOW ao pino do RESET, fazendo com que o mesmo seja resetado e recomece o código do começo! Por este motivo, o código foi escrito no setup(), já que não foi necessário nenhuma ação dentro do loop(), mas isto não impede de escrever dentro do loop().

Sempre que o o ESP for resetado, ele iniciara o código do começo!

Software

-Função ESP.deepSleep()

ESP.deepSleep(1 * 60000000);//Dorme por 1 Minuto (Deep-Sleep em Micro segundos).

Este comando coloca o MCU em Deep-sleep por 1 Minuto. O valor à ser colocado na função é em Micro Segundos!

Após você usar este comando, o MCU irá dormir até que o tempo se acabe. Quando o tempo definido estourar (Acabar), o RTC irá gerar um pulso LOW ao pino RST, fazendo com que o MCU seja reiniciado completamente. Após o reset, o código irá se iniciar do começo normalmente e só entrara em Sleep novamente, quando chegar a respectiva linha do comando para dormir.

 

Fechamento

Faremos alguns cálculos de autonomia com Sleep.

Após testar este projeto, você pode medir o consumo da corrente no MCU utilizando um multímetro ou algo similar. Usarei um Osciloscópio para medir a tensão em cima de um resistor de 1 Ω, isso significa que os valores lidos da tensão pelo osciloscópio, serão a mesma que a corrente.

 

Para entender o gráfico do osciloscópio de uma maneira simples, primeiro veja que a escala vertical esta com 20mV por divisão, isto significa que a cada divisão vertical, corresponde a 20mV!

Fig 1 - Escala vertical em 20mV.


 

Fig 2 - Explicação do gráfico.


 

Fig 3 - Corrente em modo STA.


 

Como podemos ver, a corrente (FIG 3), está aproximadamente em 80mA quando o ESP8266 esta com o RF ligado. Usando Modem Sleep para desligar o RF, este consumo já iria para ~15mA!

Para medir a corrente quando o ESP8266 entra em Deep Sleep, foi necessário a redução da escala vertical, indo para 5mV (FIG 4) por divisão!, a leitura do gráfico é a mesma que o anterior (FIG 5).

Fig 4 - Escala vertical em 5mV.


Fig 5 - Corrente em Deep sleep.


 

Agora você deve estar se perguntando porque o consumo esta tão alto comparado ao datasheet (20μA). Isto se deve ao fato de que esta placa NodeMCU conta com diversos componentes, como por exemplo regulador de tensão e o conversor FTDI. Estes componentes "roubam" uma preciosa energia quando é ativado o Deep Sleep. Por este motivo, você não deve usar o NodeMCU para projetos portáteis, já que o consumo é muito maior. Para isto, use o ESP8266 01, 12, ou qualquer outro que não venha em uma placa (Kit de Desenvolvimento). Ainda sim, usando o ESP 01, há o LED vermelho que indica se o MCU esta ligado, o consumo não será 20μA enquanto não remover este LED!

 

Usamos ESTA ferramenta para fazer os cálculos, você também pode fazer o calculo de autonomia do seu projeto com ela!

  • Bateria 18650: 3,7V e 4000mAh.
  • NodeMCU: Duração do código = 2 Segundos por 80mA.
  • NodeMCU: Tempo de Sleep = 1 Minuto por 3mA.

 

Chegamos a conclusão que sem Sleep, o NodeMCU ficaria 40 horas ligado até que a bateria se acabe. Já com o Deep sleep, isso é aumentado para 583 horas (24 dias)!!!

Para comparar o Deep Sleep do teste com o "verdadeiro" Deep sleep de um ESP8266 (20μA), também foi feito o cálculo e chegamos a incríveis 1230 horas, o equivalente a 51 dias!

 

Dúvidas? Sugestões? Críticas? Comente abaixo!


Controlando seu projeto usando Telegram

Controlando seu projeto usando Telegram - ESP

Controlando seu projeto com Telegram

Imagine uma automação ou projeto que permite você “conversar” com seu Microcontrolador (MCU) e também receber comandos, parece difícil, mas é bem simples. Aprenderemos a usar o Telegram para criar automações e projetos das mais diversas possibilidades e utilidades que estabelece uma comunicação amigável com o MCU. Para essa experiência usaremos o NodeMCU 8266, mas você pode fazer com outros ESPs, tal como os da linha ESP8266 e o ESP32.

 

[toc]

O Telegram

Podemos fazer desde simples controles de LEDs, ou até uma automação residencial controlada pelo Telegram, já que os BOTs permitem controle total de informações.

 

Usaremos o Telegram pois nos permite criar “BOTs”. Estes BOT's, são como robôs virtuais e com eles, conseguimos criar uma interface IHM (Interface Homem-Máquina). Este método, permite o fluxo de informações de ambos sentidos (Input e Output), então conseguimos controlar o sistema e também ser notificado pelo sistema.

 

Criando seu Bot no Telegram

1-) Pesquise pelo "BotFather" no menu de pesquisa do Telegram, entre nele e clique em "Começar ou Reiniciar".

 

 

 

2-) Pelo BotFater podemos criar novos Bots, configura-los e muito mais. Para criar, faça:

  1. Digite "/newbot".
  2. Digite o nome do seu novo Bot.
  3. Digite o usuário do Bot com a terminação "bot".

 

3-) Logo após a criação, o BotFater enviará uma mensagem com o link do Bot e logo abaixo o Token do Bot. Você pode clicar neste link para abrir a conversa com seu Bot ou pode pesquisa-lo futuramente.

Você precisa desse Token para inserir no código!

 

Mãos a obra

Componentes necessários

Para este projeto, usaremos o ESP8266 (versão NodeMCU). Entretanto, pode ser feito igualmente com o ESP32, sendo necessário alguns pequenos ajustes.

  • 1x – ESP8266. (Usaremos o NodeMCU).
  • 1x – Telegram no Celular.
  • 1x - LED. (Usaremos o LED OnBoard da placa).

- Biblioteca utilizada

Clique AQUI para ir a pagina de download da biblioteca "UniversalTelegramBot" utilizada.

Alguns usuários relatam erro com a biblioteca "ArduinoJson".  Caso aconteça com você, será necessário instalar a biblioteca na Arduino IDE.

Para isso vá em "Gerenciador de bibliotecas", procure pela biblioteca "ArduinoJson", instale-a e reinicie a Arduino IDE.

- Código do projeto

Não se esqueça de alterar as credenciais do WiFi e também o Token do seu Bot. Sem isso não irá funcionar.

Vários usuários relatam erro com a versão 2.5 do esp8266 (core) instalado na Arduino IDE, que é resolvido instalando a 2.4.0.

 

#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>
#define BOTtoken "135924:AAErDKEJaQpEnqs_xj35asdGQ5kK6dQet4"//Define o Token do *seu* BOT

WiFiClientSecure client;
UniversalTelegramBot bot(BOTtoken, client);

String id, text;//Váriaveis para armazenamento do ID e TEXTO gerado pelo Usuario
unsigned long tempo;

void setup()
{
   pinMode(D4, OUTPUT);//LED conectado à saida
   WiFi.mode(WIFI_STA);//Define o WiFi como Estaçao
   connect();//Funçao para Conectar ao WiFi
}

void loop()
{
   if (millis() - tempo > 2000)//Faz a verificaçao das funçoes a cada 2 Segundos
   {
      connect();//Funçao para verificar se ainda há conexao
      readTel();//Funçao para ler o telegram
      tempo = millis();//Reseta o tempo
   }
}

void connect()//Funçao para Conectar ao wifi e verificar à conexao.
{
   if (WiFi.status() != WL_CONNECTED)//Caso nao esteja conectado ao WiFi, Ira conectarse
   {
      WiFi.begin("SUA REDE", "SUA SENHA");//Insira suas informaçoes da rede
      delay(2000);
   }
}

void readTel()//Funçao que faz a leitura do Telegram.
{
   int newmsg = bot.getUpdates(bot.last_message_received + 1);

   for (int i = 0; i < newmsg; i++)//Caso haja X mensagens novas, fara este loop X Vezes.
   {
      id = bot.messages[i].chat_id;//Armazenara o ID do Usuario à Váriavel.
      text = bot.messages[i].text;//Armazenara o TEXTO do Usuario à Váriavel.
      text.toUpperCase();//Converte a STRING_TEXT inteiramente em Maiuscúla.

      if (text.indexOf("ON") > -1)//Caso o texto recebido contenha "ON"
      {
         digitalWrite(D4, 0);//Liga o LED
         bot.sendMessage(id, "LED ON", "");//Envia uma Mensagem para a pessoa que enviou o Comando.
      }

      else if (text.indexOf("OFF") > -1)//Caso o texto recebido contenha "OFF"
      {
         digitalWrite(D4, 1);//Desliga o LED
         bot.sendMessage(id, "LED OFF", "");//Envia uma Mensagem para a pessoa que enviou o Comando.
      }

      else if (text.indexOf("START") > -1)//Caso o texto recebido contenha "START"
      {
         bot.sendSimpleMessage(id, id, "");//Envia uma mensagem com seu ID.
      }

      else//Caso o texto recebido nao for nenhum dos acima, Envia uma mensagem de erro.
      {
         bot.sendSimpleMessage(id, "Comando Invalido", "");
      }
   }

}

Colocando para funcionar

Após a criação do BOT e upload do código, podemos ver funcionando. Veja o BOT respondeu como o esperado aos comandos:

 


Entendendo a fundo

Software

-Função UniversalTelegramBot::sendMessage()

bot.sendMessage(id, "LED OFF", "");

Com esta função, é feito o envio da mensagem para o determinado ID (referente ao ID de quem enviou a mensagem ao Bot). Logo ao iniciar seu BOT, automaticamente é enviado uma mensagem "/START", e nosso sistema irá responder com o seu ID do Telegram; você pode usar isso para aceitar apenas comandos de seu ID.

 

-Variável id

id = bot.messages[i].chat_id;

Toda vez que o Bot receber um novo update (mensagem), irá armazenar o ID da pessoa que enviou a mensagem na variável id.

 

-Variável text

text = bot.messages[i].text;

Toda vez que o Bot receber um novo update (mensagem), irá armazenar o texto na variável text.

 

A biblioteca do Telegram permite mais opções interessantes, como por exemplo obter o horário em que a mensagem foi enviada ao Bot! Dê uma olhada na referência da biblioteca.

 

-Função UniversalTelegramBot::getUpdates()

int newmsg = bot.getUpdates(bot.last_message_received + 1);

Esta função faz a verificação de novas mensagens, sempre será lido da última (mais recente), para a primeira (mais antiga) mensagem no buffer do Bot. Isto será feito até que se tenha lido todas as mensagens disponíveis então tome cuidado para não travar ou atrasar o resto do seu código!


Desafio

Qualquer pessoa que adicionar seu Bot (basta pesquisar), pode enviar comandos e controla-lo. Você terá que criar algum tipo de “cadeado” para aceitar apenas comandos de pessoas autorizadas. Cada usuário no Telegram tem um ID, então você pode usar isso à seu favor e fazer o sistema aceitar apenas comandos de algumas pessoas.

Fechamento

Podemos facilmente incluir este controle com o Telegram em diversos projetos, permitindo que o mesmo seja controlado à distancia e até mesmo que você seja notificado, como por exemplo um alarme para sua casa que mande mensagem para seu celular ao detectar movimento. As aplicações são imensas, dependendo apenas da sua criatividade. Dúvidas? Sugestões? Críticas? Comente!