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!
Estudante de Engenharia da Computação pela USC, pretende se aprimorar e fazer a diferença nesta imensa área da tecnologia. Apaixonado por IoT, sistemas embarcados, microcontroladores e integração da computação nos mais diversos fins práticos e didáticos.
17 Comments
Deixe uma pergunta, sugestão ou elogio! Estamos ansiosos para ter ouvir!Cancelar resposta
Este site utiliza o Akismet para reduzir spam. Saiba como seus dados em comentários são processados.
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.