Manual
do
Maker
.
com
Da série sobre sleep modes, recomendei o artigo de modem sleep do ESP8266, que é diferente do ESP32. Quando notei que o artigo que havia escrito era pra ESP8266, resolvi escrever esse artigo adicional para completar a série, que ainda fica faltando o UART wakeup funcional.
Da série, precedem esse artigo:
Recomendo a leitura da série completa para definir o melhor modo para seu projeto.
Se não leu a série, pode ser que fique na dúvida, apesar do nome ser um forte indicativo do processo. No modem sleep desabilitamos o bluetooth e WiFi, o que economiza horrores! Nesse modo, meros 3mA sustentam o ESP32 com clock de 80MHz. Aliás, já citei como definir o clock em 80, 160 ou 240MHz, mas vou citar novamente mais adiante.
No modem sleep, deixamos o rádio desligado e reabilitamos quando necessário enviar algum dado. Se pretende utilizar esse modo no ESP8266, leia o artigo "Desativar WiFi no ESP8266 (e reativar)".
Apesar de ser um processo simples, precisa ser planejado. Suponhamos que haja a necessidade de envios periódicos de telemetria para um broker MQTT. Quando iniciamos o serviço MQTT, ele ficará em execução contínua em um loop ou então em uma task, como normalmente descrevo nos artigos sobre MQTT com ESP32. Se desligarmos o rádio, o que acontecerá com a conexão MQTT? Normalmente implemento um callback de mensagem e de reconexão. Se falhar a comunicação, o processo tentará restabelecer a conexão indefinidamente, ou talvez faça o ESP32 reiniciar, ou sabe-se lá o quê. Portanto, para implementar o Modem Sleep é necessário considerar o tratamento de todos os processos que façam uso da RF: MQTT, webserver, NTP, DNS etc.
Para configurar o Modem Sleep, criei algumas funções básicas:
void send_and_sleep(){
rf_on();
xTaskCreatePinnedToCore(vMQTT, "vMQTT", 10000, NULL, 0, &mqttConn, 0);
vTaskDelay(pdMS_TO_TICKS(10000));
rf_off();
}
Essa é a função "macro". Quando chamada, ligará o RF, iniciará a task do MQTT (que é executada de forma assíncrona, pois é uma task) e, enquanto aguardamos a finalização da task, pausamos a execução dessa função macro por 10 segundos. Passados os 10 segundos, certamente (com uma gorda margem) a tarefa do MQTT estará cumprida, então podemos desligar novamente o RF. Essa task já é famosa nos artigos relacionados ao MQTT, mas algumas modificações foram necessárias também.
void rf_on(){
//Inicializa o WiFi
bool bye = WiFi.setSleep(false);
WiFi.mode(WIFI_STA);
vTaskDelay(pdMS_TO_TICKS(30));
WiFi.begin(wifiConfig.ssid, wifiConfig.passwd);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("Connected to WiFi");
}
Para ligar é moleza. A função setSleep() retorna um boolean. O retorno está sendo pego, mas não usado. Em seguida, colocamos o WiFi no modo STA, com um gigantesco delay de 30ms, apenas para garantir que tudo estará configurado para o próximo passo. Feito isso, iniciamos o processo normal de conexão, que normalmente colocamos na função setup().
void rf_off(){
bool bye = WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);
btStop();
bye = WiFi.setSleep(true); //recebe beacons apenas
vTaskDelay(pdMS_TO_TICKS(100));
}
Do mesmo modo, estou pegando o retorno da desconexão do WiFi e lá embaixo, o retorno da função setSleep(). A sequência é simples: desconecta do WiFi, muda o modo para WIFI_OFF (ou WIFI_MODE_NULL, que é a mesma coisa), pára o bluetooth, coloca em sleep. Nesse modo, apenas beacons deveriam ser recebidos, mas lembre-se de que desconectamos e desabilitamos o WiFi.
Isso é tudo o que precisamos fazer. Lembre-se de tratar todas as coisas que usem a conexão WiFi, senão os problemas podem ser diversos e não adianta me culpar.
O resultado de um teste é semelhante ao desse vídeo, onde fiz o processo com um ESP8266.
Revisão: Ricardo Amaral de Andrade
Inscreva-se no nosso canal Manual do Maker no YouTube.
Também estamos no Instagram.
Autor do blog "Do bit Ao Byte / Manual do Maker".
Viciado em embarcados desde 2006.
LinuxUser 158.760, desde 1997.