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.
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.
- 1 – ESP8266 (Usaremos o NodeMCU).
- 1 – LDR.
- 1 – Resistor de 470 Ω.
- X – Jumper’s.
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!
Parabéns pelo tópico. Uma pergunta. Meus ESP8266, ao ser reiniciado, por falta de energia, ou tirado da tomada simplesmente, não conecta no Blynk. O wifi se reconecta mas o blynk somente se reconecta se eu desligar o sensor alimentado no 3.3v do ESP. Seria o consumo do sensor que prejudica a conexão?
Olá José, muito interessante seu artigo. Estou montando um sistema de supervisão do nível de uma caixa d’água e estou usando um ESP8266-01 comandado por um Arduino Nano. Nos intervalos de transmissão quero fazer o ESP dormir. É possível usar o pino CH_PD para isso ? Você sabe qual o comando AT para ativar o deep-sleep no ESP8266-01 ?
Seria interessante acrescentar uma informação José. Estava tentando utilizar o deepSleep em um ESP12 e deu o maior trabalho, pois assim que executava o comando, ele resetava e não entrava em sleep. Depois de muito pesquisar nos fóruns gringos descobri que era necessário colocar um delay(100) milissegundos depois do comando ESP.deepSleep, para garantir eu coloquei antes e depois. Como esse seu tutorial é o primeiro em português das pesquisas do google, seria interessante você colocar uma observação aí para o pessoal. Levei quase meio dia até descobrir o problema. Vlw. Abs
Post top, tenho uma duvida, qual seria a melhor forma para desativar o sleep? (se puder mostrar o código) Estou utilizando uma placa para ligar e desligar um relé e gostaria que nunca entrasse em sleep mode, ficasse sempre rodando o WifiServer porém após alguns minutos ele entra em sleep e nem o botão que eu tenho na placa responde, somente desligando e ligando a placa de novo :(
É só nao colocar para dormir, apague as linhas de sleep()
Olá !! Parabéns, tirou duvidas sobre sleep, Por favor helpp, Nunca fiz projetos com ESP, faço interruptor com receptor ir e rele solido, a ideia eh ficar o menor possível, e com wi-fi, Com ESP01 só 2 IO´s, pensei em ESP12, bateria de celular e mini usb para carregar a bateria, mas o problema eh q totalmente carregada, fica entre 4v. sem contar q quando carregando passa d 4.5v, Qual solução vc indicaria. um regulador ams1117 3.3, resolve isso ? no meu caso não posso deixar em sleep, a bateria aguentaria qto tempo mais ou menos ? Agradeço desde já, Abraçao.
Reguladores lineares normais tem uma corrente de Quiescent (em IDLE) muito alta, a duração da sua bateria não será tão quanto reguladores especificos como chaveados ou LDO’s…. O tempo que aguenta depende totalmente do consumo do seu device, tensão mínima de funcionamento e etc. Procure algum conversor para 3.3V de baixo Quiescent.
Opa José. Tudo tranquilo ?! Vlw mesmo pela atenção e explicação, fico muito grato, Como a ideia eh um interruptor com um receptor ir e mqtt, tem q ficar ligado direto, ai com bat, de celuar naum vira, com essas maiores, tem q ter carregador especifico (caro), tbm tem q ter conversor como vc explicou, Como a ideia eh pra vender o projetinho, o custo naum compensa. Vou tentar com fonte de celular e um regulador linear mesmo. Tenho em casa alguns, com fonte capacitiva, ir, óptico reflexivo , compacto, se puder dar uma olhada, dar uma opinião. https://youtu.be/MpXD13eZAx0
Mais uma vez, muito obrigado, Abração !!
Parabéns! Exatamente o que queria saber. Muito obrigado.
Olá, parabéns pela simplicidade do artigo e por escolher o exemplo de código para o deep sleep, bem pensado ! Ainda sobre isso, se eu acordar um NodeMCU a cada 15 minutos, capturar uma medição de um sensor local, transmitir por wifi e dormir de novo, quanto tempo uma ou duas baterias 18650 durariam aproximadamente, dá para calcular ? Valeu !
Você precisa fazer a média ponderada do uso em Sleep e Running, já escrevi sobre isso no Embarcados, de uma olhada: https://www.embarcados.com.br/conceitos-de-economia-em-microcontroladores/
Boa José Morais, parabéns.
Sou iniciante no estudo e programação do arduino.
Estou montando um projeto onde tenho dois NRF24l01 se comunicando entre si, e gostaria de colocar ambos para dormir após um tempo sem uso, isso pode levar até mais de 1 dia. Voltando só a funcionar só após alguma interrupção externa.
Com seu código, consigo realizar isso?
Provavelmente com o mesmo código não, que foi desenvolvido para a biblioteca do ESP8266. Nunca usei o NRF então não posso ajudar muito, mas você terá que acordar o microcontrolador que controla o NRF (se for o ESP8266, ai o código funcionará). A interrupção externa (por pino) é bem simples de fazer e só irá acordar o MCU com um sinal no pino, um pressionar de botão por exemplo. De uma procurada no Google.
Cara, eu queria fazer o meu dormir pra sempre, até ele notar um evento, uma queda de temperatura ou algo assim
O problema do Deep Sleep é que o MCU é simplesmente desligado, ou seja, não conseguimos ler uma “queda de temperatura”. Entretanto se seu sensor for analogico, como um NTC/PTC, pode usar um resistor e conhecendo o nivel HIGH/LOW do MCU, conseguimos criar interrupções para quedas/elevações de tensão em um pino. Com isso você poderia deixar o MCU dormindo para sempre e acordar com uma “interrupção externa”, onde é acordado pelo nivel HIGH ou LOW de um pino.
Procurei alguns tutoriais e o seu é muito bom!!! Vou recomendar a todos os meus conhecidos que também pretendem “…aprimorar e fazer a diferença nessa imensa área tecnológica.”
Obrigado por compartilhar o seu conhecimento!
Obrigado! Espero que ajude vocês.