Utilizar uma determinada hora do dia para ativar o controle de um sistema, será uma das tarefas mais simples e corriqueiras em placas ESP32. Adicionar o horário padrão de um determinado país a uma programação amplia a capacidade operacional de qualquer projeto, afinal, imagine um circuito capaz de seguir uma rotina diária, iniciando e encerrando suas atividades em certo momento do dia. Ou seja, proporciona a execução de um sistema automatizado, com maior economia no consumo de energia, e sem a necessidade de um monitoramento constante. Este tutorial irá explorar a adição do relógio padrão brasileiro em programações via Arduino IDE, como ferramenta no controle de projetos que utilizem a conexão com a internet.



Componentes

          Para concluir as atividades desse post, tenha em mãos os seguintes componentes:

          Você pode compra-los clicando nos links acima ou visitando nosso site: www.curtocircuito.com.br.


Conectando ao Wi-Fi

          Adicionar a hora certa de um determinado país a um ESP32 requer conexão com a internet, pois, assim como qualquer computador, será necessário sincronizar o horário da placa com algum servidor on-line. Antes de iniciar a comunicação com qualquer servidor, procure testar o funcionamento da conexão Wi-Fi do ESP32, e como obter informações referentes à rede local. Na própria IDE do Arduino, encontra-se a biblioteca WiFi.h, essa opção irá simplificar o desenvolvimento de projetos que envolvam interações com a internet. A programação apresentada abaixo, irá indicar quando houver conexão com a rede, através do LED D2 (o componente encontra-se embutino no próprio ESP32). Lembre-se de configurar as opções ssid e passaword, com o nome e a senha da rede que deseja conectar-se.

/* Projeto Curto Circuito – ESP32:Conectando ao Wi-Fi */

#include <WiFi.h>
/*-------- Configurações de Wi-fi----------- */
const char* ssid = "NOME_DA_REDE";  /* Substitua pelo nome da rede */
const char* password =  "SENHA";         /* Substitua pela senha */
int led = 2;                                                /* led D2 ESP32 ; */

void setup()
{
  pinMode(led, OUTPUT);
  Serial.begin(115200);
  /*---- Tenta conectar ao Wi-Fi e a senha ---- */
  WiFi.begin(ssid, password);
  /*---- Enquanto estiver conectando ---- */
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);                                 /* Aguarda meio segundo */
    Serial.println("Conectando ao WiFi..");     /* Conectando */
  }
  Serial.println("Conectado"); /* Conectado */
}

void loop()
{
  if (WiFi.status() == WL_CONNECTED)
  { /* Se o ESP estiver conectado */
    digitalWrite(led, 1);                /* Liga */
    
  }

  else
  { /* Se estiver desconectado */
    digitalWrite(led, 0);                /* Desliga */

  }
}

          A comunicação com a internet será estabelecida de forma simples, através da função WiFi.begin(ssid, password), que irá conectar-se a rede de acordo com as informações inseridas nas variáveis const char* ssid e const char* password. Ao abrir o monitor serial, o comando while (WiFi.status() != WL_CONNECTED), será responsável por indicar o status do módulo, exibindo as tentativas de conexão com a mensagem "Conectando ao WiFi..". Por fim, o Serial.println(WiFi.localIP()) irá exibir o endereço de IP, enquanto  if (WiFi.status() == WL_CONNECTED) acionará o LED D2, quando o ESP32 estiver conectado a rede.

O Pino D2 possui conexão com um doa LED embutidos na própria placa ESP32.




NTP – Protocolo de tempo

          Alguns sistemas necessitam de um controle programado com base em certos períodos do dia, acionar ou desligar um componente em um horário pré-determinado. O protocolo de comunicação NTP conecta o ESP32 a um servidor externo, sincronizando o relógio da placa de acordo com a configuração de uma determinada região. O funcionamento da programação irá depender da biblioteca NTPClient.h, portanto, procure instala-la antes de transferir a programação.

/* Projeto Curto Circuito – ESP32: Protocolo NTP */

#include <NTPClient.h> /* https://github.com/arduino-libraries/NTPClient */
#include <WiFi.h> /* Biblioteca do WiFi. */

/*-------- Configurações de Wi-fi----------- */
const char* ssid = "NOME_DA_REDE"; /* Substitua pelo nome da rede */
const char* password = "SENHA";    /* Substitua pela senha */
/* -------- Configurações de relógio on-line----------- */
WiFiUDP udp;
NTPClient ntp(udp, "a.st1.ntp.br", -3 * 3600, 60000);/* Cria um objeto "NTP" com as configurações.utilizada no Brasil */
String hora;            /* Variável que armazena */

void setup()
{
  Serial.begin(9600);
  WiFi.begin(ssid, password);
  delay(2000);               /* Espera a conexão. */
  ntp.begin();               /* Inicia o protocolo */
  ntp.forceUpdate();    /* Atualização */
}
void loop()
{
  /* Armazena na variável hora, o horário atual. */
  hora = ntp.getFormattedTime(); 
  Serial.println(hora);     /* Escreve a hora no monitor serial. */
  delay(1000);              /* Espera 1 segundo. */
}

          Após transferir a programação abra o monitor serial do Arduino IDE, e visualize se o horário adicionado ao ESP32 será compatível com o fuso de sua região, no caso desse exemplo, estamos sincronizando a placa com o horário de Brasília.

O protocolo NTP irá adicionar o horário real a uma programação qualquer.

 


          Para compreender o funcionamento da programação, será necessário avaliar a variável NTPClient, que será utilizada como ponte na comunicação entre o servidor externo e o microcontrolador, ajustando o relógio de acordo com o valor fornecido pelo servidor.

NTPClient ntp(udp, "a.st1.ntp.br", -3 * 3600, 60000);

 

NTPClient: Função que configura o fuso horário
ntp: Armazena os valores configurados;
udp:Estabelece uma comunicação entre o ESP32 e um cliente externo, no caso desse exemplo, o NTP.
a.st1.ntp.br: Endereço on-line utilizado na coleta da hora correta no servidor.
-3 : Fuso brasileiro segundo o Meridiano de Greenwich.
3600 : Multiplica pelo fuso formatando a leitura em segundos. 
60000: Intervalo entre cada atualização (1 minuto)

          As funções ntp.forceUpdate() e  ntp.begin() serão responsáveis por manter a leitura ativa e atualizada, enquanto o ntp.getFormattedTime() ajusta o formato do horário em hora/minuto/segundo (00:00:00 ).



Acionamento Programado ESP32

          Como foi dito inicialmente, utilizaro protocolo NTP no acionamento de um componente será uma tarefa relativamente simples, para isso, utilizaremos como base a mesma programação demonstrada anteriormente, adicionando determinados períodos com a função de ligar ou desligar um LED.

 

/* Projeto Curto Circuito – ESP32: Acionamento Programado */

#include <NTPClient.h> /* Biblioteca do NTP. */
#include <WiFi.h> /* Biblioteca do WiFi. */

/* -------- Configurações de Wi-fi----------- */
const char* ssid = "NOME_DA_REDE";
const char* password = "SENHA";
/* -------- Configurações de relógio on-line----------- */
WiFiUDP udp;
NTPClient ntp(udp, "a.st1.ntp.br", -3 * 3600, 60000);/* Cria um objeto "NTP" com as configurações. */
#define led 2 /*  Define o LED ao pino D4.*/
String horario;            /* Variável que armazenara a hora */

void setup()
{
  Serial.begin(9600);
  pinMode(led, OUTPUT);      /* Define o pino como saída. */
  digitalWrite(led, 0);      /* Apaga o LED. */
  WiFi.begin(ssid, password);
  delay(2000);               /* Espera a conexão. */
  ntp.begin();               /* Inicia o NTP. */
  ntp.forceUpdate();         /* Força o Update. */
}
void loop()
{
  /* Armazena na variável HORA, o horário atual. */
  horario = ntp.getFormattedTime();
  Serial.println(horario);     /* Escreve a hora no monitor serial. */
  if (horario == "16:50:30")
  { /* Ao atingir o período definido */
    digitalWrite(led, 1);   /* O LED Acende */
  }
  if (horario == "16:55:30")
  { /*  Ao atingir o período definido */
    digitalWrite(led, 0);   /* O LED Apaga */
  }
  delay(1000);              /* Espera 1 segundo. */
}

          O LED D2 declarado na programação encontra-se acoplado a própria placa, procure ajustar as funções "if" com pequenos intervalos de tempo, apenas para testar o funcionamneto da programação inicialmente.Com a adição de poucas linhas, construimos o controle automatizado de um componente, tornando possível a aplicação de uma rotina diária no funcionamento do LED.



NTP e ULP

          O Ultra Low Power (ULP), presente em placas ESP32, possibilita um controle de funções com baixo consumo de energia, visto que coloca em modo de hibernação alguns dos principais componentes internos. Associar o protocolo NTP a comandos como o Deep Sleep permitirá a programação de um horário para o descanso de sistemas placa. Com base nos exemplos apresentados anteriormente, esse exemplo terá como objetivo desligar o ESP em um determinado período, e retomar as atividades ao pressionar o sensor capacitivo.

/* Projeto Curto Circuito – ESP32: NTP e ULP */

/* -------- Bibliotecas----------- */
#include <NTPClient.h> /* https://github.com/arduino-libraries/NTPClient */
#include <WiFi.h> /* Biblioteca Wi-Fi. */
#include <esp_deepsleep.h>
/* -------- Wi-Fi ----------- */
const char* ssid = "NOME_DA_REDE";
const char* password = "SENHA";
/* -------- Protocolo NTP ----------- */
WiFiUDP udp;
NTPClient ntp(udp, "a.st1.ntp.br", -3 * 3600, 60000);
/* -------- Sensor Capacitivo ----------- */
#define Threshold 40 /* Define a sensibilidade do sensor. */
touch_pad_t touchPin;
/*-------- LED-----------*/
#define led 23 /* Define o LED no pino D23 do ESP32 */


String hora;/*Armazenara o horário na memória RTC. */


void wakeup_touchpad()
{
  touch_pad_t pin;
  touchPin = esp_sleep_get_touchpad_wakeup_status();
}

void callback() {}
void setup()
{
  Serial.begin(9600);     /* Inicia a comunicação serial. */
  wakeup_touchpad();
  pinMode(led, OUTPUT);   /* Define o pino como saida. */
  digitalWrite(led, 0);   /* Apaga o LED. */
  WiFi.begin(ssid, password);
  touchAttachInterrupt(T0, callback, Threshold);
  Serial.printf("\nsetup() em core: %d", xPortGetCoreID()); /* Mostra no monitor em qual core o setup() foi chamado */
  xTaskCreatePinnedToCore(loop2, "loop2", 8192, NULL, 1, NULL, 0); /*Cria a tarefa "loop2()" com prioridade 1, atribuída ao core 0 */
  esp_sleep_enable_touchpad_wakeup();
  delay(2000);/* Espera a conexão. */
  ntp.begin();/* Inicia o NTP */
  ntp.forceUpdate();/* Força o Update */

}

void loop() {
  temp();
  if (hora == "14:39:30")
  { /* Se hora for igual ao valor definido */
    digitalWrite(led, 1);    /* LED Acende */
    delay(1000);
    esp_deep_sleep_start();
  }
  Serial.printf("\n Tempo corrido: ", hora);
  delay(1000);  /* Mantem o processador 1 em estado ocioso por 1seg */
}
void temp()
{
  hora = ntp.getFormattedTime();/* Armazena na váriavel HORA, o horario atual. */
  Serial.println(hora);/* Printa a hora já formatada no monitor */
}
void loop2(void*z)
{
  Serial.printf("\nloop2() em core: %d", xPortGetCoreID());/* Mostra no monitor em qual core o loop2() foi chamado */
  while (1)/*Pisca o led infinitamente */
  {
    digitalWrite(led, !digitalRead(led));
    delay(100);
  }
}

          O void wakeup_touchpad será utilizado na configuração de um sensore capacitivo, como forma de despertar o ESP32 . As funções touch_pad_t e esp_sleep_get_touchpad_wakeup_status, irão construir variáveis de leitura referentes ao ajuste do pino capacitivo, determinando que o toque no devido pino irá influenciar diretamente no status de hibernação. O touchAttachInterrupt() configura o pino T0 como um interruptor no processo de despertar da placa, utilizando o valor da variável Threshold na configuração de sensibilidade do sensor.

          A programação separa as funções através do multiprocessamento da placa, sendo o núcleo 1 responsável por transmitir o horário, e o núcleo 0 piscar de um LED continuamente. Para isso, será necessário utilizar funções Task, que são comando de acesso do Sistema Operacional em Tempo Real, capaz de executar múltiplas tarefas de forma simultânea. A função xTaskCreatePinnedToCore, funcionará da seguinte forma: 

 Configure um core para separar o processamento de funções específicas.

 

loop2: será um indicativo da Função, direcionando a leitura do núcleo (core) ao loop2;
"loop2": cria uma função do tipo String;
8192: quantidade de variáveis a serem tratadas, com valor em bytes;
NULL: Parâmetros de execução de tarefas pré-definidas, no caso desse exemplo será Nulo;
1: A prioridade será definida por ordem crescente;
NULL: manipulador qie referenciar a tarefa;
0: Define o processador (0 ou 1).



          E por fim, ao atingir o horário determinado em hora == "14:39:30", a função esp_deep_sleep_start() irá acionar o modo de hibernação do ESP, desligando os processadores e outras funções como Wi-Fi e Bluetooth,  mantendo apenas o coprocessador ativo para interpretar a leitura do pino T0, e despertar as funções novamente. 

A leitura do sensor capacitivo será utilizada para acionar o despertar da placa.

Considerações Finais

          Protocolos e comunicação como o NTP tendem a transformar uma automação complexa em algo simples, afinal, tarefas manuais como desligar um sistema, ou acionar componentes em certa hora de um dia, serão substituídos por horários, aplicando uma rotina diária ao controle do circuito. Mas, como foi dito até então, o funcionamento deste protocolo irá depender exclusivamente da conexão entre o ESP32 e uma rede Wi-Fi, portanto, não será possível configurar uma determinada hora para despertá-lo da placa, afinal, todos os modos de comunicação sem fio serão desligados ao entrar em hibernação.