Protocolo de tempo NTP com ESP
Protocolo de tempo NTP com ESP
É comum que em projetos de automação e robótica seja necessário saber a hora correta, para marcar a hora em que uma ação ocorreu ou até para ativar sensores em certo horário. Vamos aprender a adicionar um RTC (Real Time Clock - Relógio de tempo Real) ao ESP sem precisar de um hardware externo, como por exemplo um DS1307 ou do DS3231. Para isso, usaremos o NTP que só precisa de uma conexão com a internet o que é facilmente resolvido quando o assunto é projetos com ESP e IoT.
Sobre o NTP
Do Wikipédia:
O NTP é um protocolo para sincronização dos relógios dos computadores baseado no protocolo UDP sob a porta 123, para sincronização do relógio de um conjunto de computadores em redes de dados com latência variável. O NTP permite manter o relógio de um computador com a hora sempre certa e com grande exatidão.
O NTP serve tanto para atualizar e também manter os horários e datas sincronizadas entre dispositivos. Não há muitas explicações sobre isto, porém caso queira aprender mais sobre o NTP, clique AQUI ou AQUI.
Digamos que você tem uma rede de sensores, e precisa que eles liguem as 20h da noite, as melhores alternativas para isto, são um RTC externo/interno ou até o NTP caso haja conexão com a internet. Para o exemplo deste tutorial, acenderemos o LED Onboard de acordo com o horário que iremos definir. Com o NTP, também é possível arrumar a data e hora de um RTC externo que esteja errado!
Neste GIF, é mostrado o funcionamento do exemplo deste tutorial, no qual o LED foi acionado as 19:23:30.
Mãos à obra
Componentes necessários
Montando o projeto
Nesse projeto usaremos apenas a placa NodeMCU. Usaremos o LED que já vem na placa ligado ao Pino D4 para fazer nossa experiência. Também funciona com ESP32.
Código do projeto
Não se esqueça de alterar as credenciais do WiFi e usar o fuso horário correto. Também altere para o horário que desejar, como o tutorial foi feito as 19:23, usamos este valor.
#include <NTPClient.h>//Biblioteca do NTP. #include <WiFiUDP.h>//Biblioteca do UDP. #include <ESP8266WiFi.h>//Biblioteca do WiFi. WiFiUDP udp;//Cria um objeto "UDP". NTPClient ntp(udp, "a.st1.ntp.br", -3 * 3600, 60000);//Cria um objeto "NTP" com as configurações. #define led D4//Define o LED ao pino D4. String hora;//Váriavel que armazenara o horario do NTP. void setup() { Serial.begin(9600);//Inicia a comunicação serial. pinMode(led, OUTPUT);//Define o pino como saida. digitalWrite(led, 1);//Apaga o LED. WiFi.mode(WIFI_STA); WiFi.begin("SUA REDE", "SUA SENHA");//Conecta ao WiFi. delay(2000);//Espera a conexão. ntp.begin();//Inicia o NTP. ntp.forceUpdate();//Força o Update. } void loop() { hora = ntp.getFormattedTime();//Armazena na váriavel HORA, o horario atual. Serial.println(hora);//Printa a hora já formatada no monitor. if (hora == "19:23:30")//Se a hora atual for igual à que definimos, irá acender o led. { digitalWrite(led, 0);//Acende } delay(1000);//Espera 1 segundo. }
Entendendo a fundo
Software
-Declarando o objeto
NTPClient ntp(udp, "a.st1.ntp.br", -3 * 3600, 60000);//Cria um objeto "NTP" com as configurações.
Aqui é criado o objeto NTP com os seguintes parâmetros:
- Objeto UDP.
- Servidor do NTP, Acesse ESTE link para ver os servidores brasileiros disponíveis.
- Fuso horário multiplicado por segundos, apenas altere o fuso horário se for necessário.
- intervalo de updates para atualização da hora, é necessário para manter a hora correta. O padrão é 1 Minuto.
-Função NTPClient::begin() e forceUpdate()
ntp.begin();//Inicia o NTP. ntp.forceUpdate();//Força o Update.
Iniciamos o NTP e também forçamos o update para certificar de que a hora esteja certa.
-Salvando a hora atual
hora = ntp.getFormattedTime();//Armazena na váriavel HORA, o horario atual.
Esta função ntp.getFormattedTime() retorna uma string com a hora atual, contendo HH:MM:SS. Salvamos isto na nossa String hora
Também é possível pegar os dados separados ou até o dia. Veja as funções da biblioteca!
-Acionando o LED com a hora
if (hora == "19:23:30")//Se a hora atual for igual à que definimos, irá acender o led. { digitalWrite(led, 0);//Acende }
Caso a variável que contem a hora atual seja igual à definida, neste caso é 19:23:30, acenderá o LED.
Desafio
O desafio desta vez, é manter o LED aceso entre intervalos de tempo, por exemplo das 13h até as 16h. Para isto, pode-se usar a boa e velha lógica booleana ou a função constrain() do arduino. Boa sorte!
Considerações finais
A implementação deste simples protocolo pode ser de grande ajuda e utilidade em seus projetos que tenham conexão com a Internet. Dúvidas? Sugestões? Críticas? Comente abaixo!