Exemplo WebRTC com ESP32 - Tutorial da Interface de Relógio de Tempo Real

Visão Geral

O exemplo WebRTC oferece uma interface completa de relógio de tempo real para os seus projetos com ESP32. Feito para a plataforma educacional ESP32, com recursos de RTC integrados, gerenciamento de horário aprimorado e integração perfeita com o ecossistema educacional. Você pode exibir as informações do relógio de tempo real, sincronizar o horário do navegador com o Arduino e monitorar as diferenças de horário por meio de uma interface web intuitiva.

Arduino WebRTC Example - Real-Time Clock Interface Tutorial

Recursos

  • Exibição do Relógio de Tempo Real: mostra o horário atual do RTC do ESP32 com atualização automática
  • Comparação com o Horário do Dispositivo: exibe o horário do navegador/dispositivo ao lado do horário do ESP32
  • Sincronização de Horário com Um Clique: sincroniza o RTC do ESP32 com o horário do navegador na hora
  • Indicador Visual de Diferença de Horário: mostra o desvio de horário entre os dispositivos em minutos
  • Formato de Horário em Duas Linhas: formato de 12 horas AM/PM com a data completa
  • Interface Moderna com Gradiente: layout em cartões com design responsivo
  • Comunicação WebSocket: atualizações bidirecionais em tempo real, sem recarregar a página
  • Sincronização com Fuso Horário: usa o horário local do dispositivo para uma sincronização precisa
  • Monitoramento do Status da Conexão: indicadores visuais do estado da conexão WebSocket
  • Solicitação Automática de Horário: pede o horário atual do ESP32 ao carregar a página

Diagrama de Ligação

The wiring diagram between ESP32 Real-Time Clock DS3231

This image is created using Fritzing. Click to enlarge image

Se você não sabe como alimentar o ESP32 e outros componentes, veja as instruções no tutorial a seguir: Como alimentar o ESP32.

ESP32 - Módulo RTC DS3231

Módulo RTC DS1307 ESP32
Vin 3.3V
GND GND
SDA GPIO21
SCL GPIO22

Passos Rápidos

Siga estas instruções passo a passo:

  • Se esta é a primeira vez que você usa o ESP32, consulte o tutorial sobre como configurar o ambiente do ESP32 na Arduino IDE.
  • Conecte a placa ESP32 ao seu computador usando um cabo USB.
  • Abra a Arduino IDE no seu computador.
  • Selecione a placa ESP32 correta (por exemplo, ESP32 Dev Module) e a porta COM.
  • Vá até o ícone Libraries na barra esquerda da Arduino IDE.
  • Pesquise "DIYables ESP32 WebApps" e encontre a biblioteca DIYables ESP32 WebApps da DIYables
  • Clique no botão Install para instalar a biblioteca.
DIYables ESP32 WebApps Library
  • Será pedido que você instale algumas outras dependências da biblioteca
  • Clique no botão Install All para instalar todas as dependências.
DIYables ESP32 WebApps dependency
  • Pesquise “RTClib” e encontre a biblioteca RTC da Adafruit
  • Clique no botão Install para instalar a biblioteca RTC.
ESP32 RTC library
  • Pode ser que a Arduino IDE peça para instalar as dependências da biblioteca
  • Instale todas as dependências da biblioteca clicando no botão Install All.
ESP32 Adafruit BusIO library
  • Na Arduino IDE, vá em File Examples DIYables ESP32 WebApps WebRTC, ou copie o código acima e cole no editor da Arduino IDE
/* * DIYables WebApp Library - Web RTC Example * * This example demonstrates the Web RTC feature: * - Real-time clock display for both ESP32 and client device * - One-click time synchronization from web browser to ESP32 * - Hardware RTC integration for persistent timekeeping * - Visual time difference monitoring * * Hardware Required: * - ESP32 development board * - DS3231 RTC module (connected via I2C) * * Required Libraries: * - RTClib library (install via Library Manager) * * Setup: * 1. Connect DS3231 RTC module to ESP32 I2C pins (SDA/SCL) * 2. Install RTClib library in Arduino IDE * 3. Update WiFi credentials below * 4. Upload the sketch to your ESP32 * 5. Open Serial Monitor to see the IP address * 6. Navigate to http://[IP_ADDRESS]/web-rtc */ #include <DIYables_ESP32_Platform.h> #include <DIYablesWebApps.h> #include <RTClib.h> // RTC object RTC_DS3231 rtc; char daysOfWeek[7][12] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; // WiFi credentials - UPDATE THESE WITH YOUR NETWORK const char WIFI_SSID[] = "YOUR_WIFI_SSID"; const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD"; // Create WebApp server and page instances ESP32ServerFactory serverFactory; DIYablesWebAppServer webAppsServer(serverFactory, 80, 81); DIYablesHomePage homePage; DIYablesWebRTCPage webRTCPage; void setup() { Serial.begin(9600); delay(1000); Serial.println("DIYables ESP32 WebApp - Web RTC Example"); // Initialize RTC if (!rtc.begin()) { Serial.println("RTC module is NOT found"); Serial.flush(); while (1); } // Check if RTC lost power and if so, set the time if (rtc.lostPower()) { Serial.println("RTC lost power, setting time!"); // When time needs to be set on a new device, or after a power loss, the // following line sets the RTC to the date & time this sketch was compiled rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // This line sets the RTC with an explicit date & time, for example to set // January 21, 2021 at 3am you would call: // rtc.adjust(DateTime(2021, 1, 21, 3, 0, 0)); } // Print initial RTC time DateTime initialTime = rtc.now(); Serial.print("Initial RTC Time: "); Serial.print(initialTime.year(), DEC); Serial.print("/"); Serial.print(initialTime.month(), DEC); Serial.print("/"); Serial.print(initialTime.day(), DEC); Serial.print(" ("); Serial.print(daysOfWeek[initialTime.dayOfTheWeek()]); Serial.print(") "); if (initialTime.hour() < 10) Serial.print("0"); Serial.print(initialTime.hour(), DEC); Serial.print(":"); if (initialTime.minute() < 10) Serial.print("0"); Serial.print(initialTime.minute(), DEC); Serial.print(":"); if (initialTime.second() < 10) Serial.print("0"); Serial.print(initialTime.second(), DEC); Serial.println(); // Add pages to server webAppsServer.addApp(&homePage); webAppsServer.addApp(&webRTCPage); // Optional: Add 404 page for better user experience webAppsServer.setNotFoundPage(DIYablesNotFoundPage()); // Set callback for time sync from web webRTCPage.onTimeSyncFromWeb(onTimeSyncReceived); // Set callback for time request from web webRTCPage.onTimeRequestToWeb(onTimeRequested); // Start the WebApp server if (!webAppsServer.begin(WIFI_SSID, WIFI_PASSWORD)) { while (1) { Serial.println("Failed to connect to WiFi"); delay(1000); } } } void loop() { // Handle web server webAppsServer.loop(); // Send current time to web clients and print to Serial every 1 second static unsigned long lastUpdate = 0; if (millis() - lastUpdate >= 1000) { lastUpdate = millis(); // Get current RTC time DateTime currentTime = rtc.now(); // Send time to web clients in human readable format webRTCPage.sendTimeToWeb(currentTime.year(), currentTime.month(), currentTime.day(), currentTime.hour(), currentTime.minute(), currentTime.second()); // Print time to Serial Monitor Serial.print("RTC Time: "); Serial.print(currentTime.year(), DEC); Serial.print("/"); Serial.print(currentTime.month(), DEC); Serial.print("/"); Serial.print(currentTime.day(), DEC); Serial.print(" ("); Serial.print(daysOfWeek[currentTime.dayOfTheWeek()]); Serial.print(") "); if (currentTime.hour() < 10) Serial.print("0"); Serial.print(currentTime.hour(), DEC); Serial.print(":"); if (currentTime.minute() < 10) Serial.print("0"); Serial.print(currentTime.minute(), DEC); Serial.print(":"); if (currentTime.second() < 10) Serial.print("0"); Serial.print(currentTime.second(), DEC); Serial.println(); } delay(10); } // Callback function called when web client sends time sync command void onTimeSyncReceived(unsigned long unixTimestamp) { Serial.print("Time sync received: "); Serial.println(unixTimestamp); // Convert Unix timestamp to DateTime and set RTC time DateTime newTime(unixTimestamp); rtc.adjust(newTime); Serial.println("ESP32 RTC synchronized!"); } // Callback function called when web client requests current ESP32 time void onTimeRequested() { // Get current RTC time and send to web in human readable format DateTime currentTime = rtc.now(); webRTCPage.sendTimeToWeb(currentTime.year(), currentTime.month(), currentTime.day(), currentTime.hour(), currentTime.minute(), currentTime.second()); }
  • Configure as credenciais do WiFi no código atualizando estas linhas:
const char WIFI_SSID[] = "YOUR_WIFI_NETWORK"; const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD";
  • Clique no botão Upload da Arduino IDE para enviar o código ao Arduino.
  • Abra o Serial Monitor na Arduino IDE
  • Aguarde a conexão com o WiFi e a impressão das informações do WiFi no Serial Monitor.
  • Confira o resultado no Serial Monitor. Ele fica parecido com o abaixo
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32 Dev Module' on 'COM15')
New Line
9600 baud
DIYables ESP32 WebApp - Web RTC Example Initial RTC Time: 2025/8/28 (Thursday) 12:00:08 INFO: Added app / INFO: Added app /web-rtc DIYables WebApp Library Platform: ESP32 Network connected! IP address: 192.168.0.2 HTTP server started on port 80 Configuring WebSocket server callbacks... WebSocket server started on port 81 WebSocket URL: ws://192.168.0.2:81 WebSocket server started on port 81 ========================================== DIYables WebApp Ready! ========================================== 📱 Web Interface: http://192.168.0.2 🔗 WebSocket: ws://192.168.0.2:81 📋 Available Applications: 🏠 Home Page: http://192.168.0.2/ 🕐 Web RTC: http://192.168.0.2/web-rtc ==========================================
Ln 11, Col 1
ESP32 Dev Module on COM15
2
  • Se você não vir nada, reinicie a placa ESP32.

Usando a Interface Web

  • Abra um navegador no seu computador ou celular conectado à mesma rede WiFi
  • Digite no navegador o endereço IP mostrado no Serial Monitor
  • Exemplo: http://192.168.1.100
  • Você verá a página inicial como na imagem abaixo:
ESP32 DIYables WebApp Home page with Web RTC app
  • Clique no link Web RTC e você verá a interface do app Web RTC como abaixo:
ESP32 DIYables WebApp Web RTC app
  • Você também pode acessar a página diretamente pelo endereço IP seguido de /web-rtc. Por exemplo: http://192.168.1.100/web-rtc
  • Você verá a interface Web RTC mostrando:
    • Arduino Time: horário atual do RTC do Arduino
    • Your Device Time: horário atual do seu navegador/dispositivo
    • Time Difference: diferença entre os dois horários em minutos
    • Sync ESP32 Time Button: clique para sincronizar o horário do ESP32 com o do seu dispositivo

Sincronização de Horário

  • Clique no botão "Sync ESP32 Time" para sincronizar o RTC do Arduino com o horário local do seu dispositivo
ESP32 DIYables WebApp Web RTC app
  • O processo de sincronização:
    1. Obtém o horário local atual do seu dispositivo (não o UTC)
    2. Ajusta o deslocamento de fuso horário para garantir uma sincronização correta do horário local
    3. Envia o timestamp ao Arduino por WebSocket
    4. O Arduino atualiza o seu RTC com o horário recebido
    5. A interface web é atualizada para mostrar o horário sincronizado
  • Depois da sincronização, a diferença de horário deve ser mínima (geralmente 0-1 minuto)
  • O ESP32 mantém o horário correto mesmo depois que a interface web é fechada
  • Explicação do Código

    Componentes Principais

    #include <DIYablesWebApps.h> #include <RTClib.h> // Initialize RTC object and web server RTC_DS3231 rtc; DIYablesWebAppServer server; DIYablesWebRTCPage rtcPage; // Days of week array for display char daysOfWeek[7][12] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };

    Função Setup

    void setup() { Serial.begin(9600); // Initialize DS3231 RTC module if (!rtc.begin()) { Serial.println("RTC module is NOT found"); Serial.flush(); while (1); } // Check if RTC lost power and set time if needed if (rtc.lostPower()) { Serial.println("RTC lost power, setting time!"); rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); } // Setup WiFi connection server.setupWiFi(WIFI_SSID, WIFI_PASSWORD); // Add RTC page to server server.addWebApp(rtcPage); // Set up callback functions rtcPage.onTimeSyncFromWeb(onTimeSyncReceived); rtcPage.onTimeRequestToWeb(onTimeRequested); // Start the server server.begin(); }

    Funções de Callback

    Callback de Sincronização de Horário:

    // Called when web interface sends time sync command void onTimeSyncReceived(unsigned long unixTimestamp) { Serial.print("Time sync received: "); Serial.println(unixTimestamp); // Convert Unix timestamp to DateTime and set RTC time DateTime newTime(unixTimestamp); rtc.adjust(newTime); Serial.println("ESP32 RTC synchronized!"); }

    Callback de Solicitação de Horário:

    // Called when web interface requests current ESP32 time void onTimeRequested() { DateTime currentTime = rtc.now(); // Send current time to web interface rtcPage.sendTimeToWeb( currentTime.year(), currentTime.month(), currentTime.day(), currentTime.hour(), currentTime.minute(), currentTime.second() ); }

    Loop Principal

    void loop() { server.handleClient(); // Send current time to web clients every 1 second static unsigned long lastUpdate = 0; if (millis() - lastUpdate >= 1000) { lastUpdate = millis(); DateTime currentTime = rtc.now(); // Send time to web clients rtcPage.sendTimeToWeb(currentTime.year(), currentTime.month(), currentTime.day(), currentTime.hour(), currentTime.minute(), currentTime.second()); // Print time to Serial Monitor Serial.print("RTC Time: "); Serial.print(currentTime.year(), DEC); Serial.print("/"); Serial.print(currentTime.month(), DEC); Serial.print("/"); Serial.print(currentTime.day(), DEC); Serial.print(" ("); Serial.print(daysOfWeek[currentTime.dayOfTheWeek()]); Serial.print(") "); if (currentTime.hour() < 10) Serial.print("0"); Serial.print(currentTime.hour(), DEC); Serial.print(":"); if (currentTime.minute() < 10) Serial.print("0"); Serial.print(currentTime.minute(), DEC); Serial.print(":"); if (currentTime.second() < 10) Serial.print("0"); Serial.print(currentTime.second(), DEC); Serial.println(); } delay(10); }

    Métodos da API

    Métodos da Classe DIYablesWebRTCPage

    onTimeSyncFromWeb(callback)

    • Define a função de callback que trata a sincronização de horário vinda do navegador
    • Parâmetro: void (*callback)(unsigned long unixTimestamp)
    • Uso: chamada quando o usuário clica no botão "Sync ESP32 Time"

    onTimeRequestToWeb(callback)

    • Define a função de callback que trata as solicitações de horário vindas do navegador
    • Parâmetro: void (*callback)()
    • Uso: chamada quando a interface web solicita o horário atual do ESP32

    sendTimeToWeb(year, month, day, hour, minute, second)

    • Envia o horário atual do ESP32 para a interface web
    • Parâmetros:
      • year: ano atual (por exemplo, 2025)
      • month: mês atual (1-12)
      • day: dia atual do mês (1-31)
      • hour: hora atual (0-23)
      • minute: minuto atual (0-59)
      • second: segundo atual (0-59)

    Comunicação WebSocket

    Mensagens da Web para o Arduino

    • RTC:GET_TIME - solicita o horário atual do ESP32
    • RTC:SYNC:[timestamp] - sincroniza o horário do ESP32 com um timestamp Unix

    Mensagens do ESP32 para a Web

    • DATETIME:YYYY,MM,DD,HH,MM,SS - envia os componentes do horário atual do ESP32

    Solução de Problemas

    Problemas Comuns

    1. Diferença de Várias Horas no Horário

    • Problema: o ESP32 mostra um horário com várias horas de diferença do horário do dispositivo
    • Causa: normalmente um problema de fuso horário ou RTC não inicializado corretamente
    • Solução:
      • Clique no botão "Sync ESP32 Time" para sincronizar de novo
      • Verifique se o RTC é inicializado corretamente no setup()
      • Confirme que a conexão WiFi está estável

      2. Erro "RTC module is NOT found"

      • Problema: o módulo RTC não é detectado durante a inicialização
      • Causa: módulo DS3231 mal conectado ou com defeito
      • Solução:
        • Confira a ligação I2C (SDA no GPIO 21, SCL no GPIO 22)
        • Verifique as conexões de alimentação (VCC em 3.3V/5V, GND no GND)
        • Teste com um I2C scanner para detectar o endereço do módulo
        • Tente outro módulo DS3231, se tiver

        3. Erro "Not connected to Arduino"

        • Problema: erro ao clicar no botão de sincronizar
        • Causa: falha na conexão WebSocket
        • Solução:
          • Verifique se o endereço IP do ESP32 está correto
          • Atualize a página web
          • Confirme que o ESP32 está conectado à mesma rede WiFi
          • Verifique as configurações do firewall

          3. O Horário Para de Atualizar

          • Problema: a exibição do horário congela ou não atualiza
          • Causa: conexão WebSocket perdida ou RTC parou
          • Solução:
            • Atualize a página web
            • Verifique o status da conexão WebSocket
            • Reinicie o ESP32 se o RTC parar de responder

            4. Grandes Diferenças de Horário (Dias/Meses)

            • Problema: a diferença de horário mostra milhares de minutos
            • Causa: o RTC não foi acertado corretamente ou desviou muito
            • Solução: clique no botão de sincronizar várias vezes e verifique as funções de callback

            Dicas de Depuração

            Ative a Depuração pela Serial:

            void onTimeSyncReceived(unsigned long unixTimestamp) { Serial.print("Time sync received: "); Serial.println(unixTimestamp); // ... rest of function } void onTimeRequested() { Serial.println("Time request received from web"); // ... rest of function }

            Verifique a Inicialização do RTC:

            void setup() { // ... other setup code if (!rtc.begin()) { Serial.println("RTC module is NOT found"); Serial.println("Check I2C wiring:"); Serial.println("SDA -> GPIO 21"); Serial.println("SCL -> GPIO 22"); Serial.println("VCC -> 3.3V or 5V"); Serial.println("GND -> GND"); while (1); } Serial.println("DS3231 RTC initialized successfully"); if (rtc.lostPower()) { Serial.println("RTC lost power, will set to compile time"); rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); } }

    Uso Avançado

    Registro de Dados com Timestamps

    void logSensorData(float temperature, float humidity) { DateTime currentTime = rtc.now(); String logEntry = String(currentTime.year()) + "-" + String(currentTime.month()) + "-" + String(currentTime.day()) + " " + String(currentTime.hour()) + ":" + String(currentTime.minute()) + ":" + String(currentTime.second()) + " (" + String(daysOfWeek[currentTime.dayOfTheWeek()]) + ") - " + "Temp: " + String(temperature) + "°C, " + "Humidity: " + String(humidity) + "%"; Serial.println(logEntry); // Save to SD card, send to database, etc. }

    Ações Agendadas

    void checkScheduledActions() { DateTime currentTime = rtc.now(); // Turn on LED every day at 6:00 AM if (currentTime.hour() == 6 && currentTime.minute() == 0 && currentTime.second() == 0) { digitalWrite(LED_BUILTIN, HIGH); Serial.print("Morning LED activated! Time: "); Serial.print(daysOfWeek[currentTime.dayOfTheWeek()]); Serial.print(" "); Serial.print(currentTime.hour()); Serial.print(":"); Serial.println(currentTime.minute()); } // Turn off LED every day at 10:00 PM if (currentTime.hour() == 22 && currentTime.minute() == 0 && currentTime.second() == 0) { digitalWrite(LED_BUILTIN, LOW); Serial.println("Evening LED deactivated!"); } }

    Integração com Vários Web Apps

    // Combine WebRTC with other web apps server.addWebApp(rtcPage); // Real-time clock server.addWebApp(monitorPage); // Serial monitor with timestamps server.addWebApp(plotterPage); // Data plotting with time axis

    Aplicações e Casos de Uso

    Projetos Educacionais

    • Aprendizado de Gerenciamento de Tempo: ensine os alunos sobre RTC, marcação de tempo e sincronização
    • Conceitos de Tempo em IoT: demonstre a sincronização de horário em rede em sistemas IoT
    • Projetos de Registro de Dados: adicione timestamps às leituras de sensores e aos experimentos
    • Sistemas de Agendamento: crie sistemas de automação e controle baseados em horário

    Aplicações no Mundo Real

    • Automação Residencial: agende luzes, irrigação ou outros dispositivos
    • Aquisição de Dados: marque as leituras de sensores com horário para análise
    • Registro de Eventos: registre quando eventos específicos ocorrem, com horário preciso
    • Monitoramento Remoto: verifique remotamente o status do dispositivo e os horários da última atualização

    Benefícios para o Ensino de STEM

    • Conceitos de Fuso Horário: entenda a diferença entre horário local e UTC e como tratar fusos horários
    • Comunicação em Rede: aprenda a comunicação WebSocket e as atualizações em tempo real
    • Integração de Hardware: combine interfaces web com a funcionalidade de RTC em hardware
    • Resolução de Problemas: depure problemas de horário e de sincronização

    Especificações Técnicas

    Uso de Memória

    • Memória Flash: ~8KB para a funcionalidade WebRTC
    • SRAM: ~2KB durante a operação
    • Buffer WebSocket: ~1KB para o tratamento de mensagens

    Características de Desempenho

    • Frequência de Atualização: atualizações em tempo real via WebSocket
    • Precisão da Sincronização: normalmente dentro de 1-2 segundos
    • Sobrecarga de Rede: ~50 bytes por mensagem de atualização de horário
    • Tempo de Resposta: <100ms para as operações de sincronização de horário

    Compatibilidade

    • Placas ESP32: ESP32, ESP32 Web Apps
    • Navegadores: todos os navegadores modernos com suporte a WebSocket
    • Dispositivos: computadores, tablets e celulares
    • Redes: redes WiFi com acesso à internet

    Tutorial em Vídeo

    O vídeo de demonstração abaixo usa o código abaixo:

    /* * Este código de ESP32 foi desenvolvido por pt.newbiely.com * Este código de ESP32 é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/esp32/diyables-esp32-web-apps-web-rtc */ /** * @file SmartPillReminder_ESP32.ino * @brief IoT Medication Reminder System using ESP32 and an external I2C DS3231 RTC module. * * This firmware integrates an asynchronous Web Server for RTC synchronization, * a MAX7219 8x32 LED Matrix driven via SPI, and a discrete GPIO active buzzer peripheral. * Memory safety is enforced via static char buffer allocation to prevent runtime heap corruption. * * Hardware Connections: * - DS3231 SDA -> ESP32 GPIO 21 (Default I2C SDA pin) * - DS3231 SCL -> ESP32 GPIO 22 (Default I2C SCL pin) * - MAX7219 VCC -> 5V * - MAX7219 GND -> GND * - MAX7219 DIN -> ESP32 MOSI (Default GPIO 23) * - MAX7219 CLK -> ESP32 SCK (Default GPIO 18) * - MAX7219 CS -> GPIO 25 (Configured SPI Chip Select pin) * - Active Buzzer -> GPIO 15 (Configured Digital Output pin) */ #include <DIYables_ESP32_Platform.h> #include <DIYablesWebApps.h> #include <RTClib.h> #include <MD_Parola.h> #include <MD_MAX72xx.h> // --- PERIPHERAL INSTANTIATION --- RTC_DS3231 rtc; // --- NETWORK CONFIGURATION --- const char WIFI_SSID[] = "YOUR_WIFI_SSID"; const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD"; // --- WEB SERVER ROUTING ENGINE --- ESP32ServerFactory serverFactory; DIYablesWebAppServer webAppsServer(serverFactory, 80, 81); DIYablesHomePage homePage; DIYablesWebRTCPage webRTCPage; // --- DISPLAY SUBSYSTEM CONFIGURATION --- #define HARDWARE_TYPE MD_MAX72XX::FC16_HW // Hardware register layout variant for physical modules #define MAX_DEVICES 4 // Number of cascaded 8x8 matrix blocks #define CS_PIN 25 // SPI Chip Select active-low hardware pin MD_Parola ledMatrix = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES); // --- ALARM SUBSYSTEM ARCHITECTURE --- const int BUZZER_PIN = 15; bool isAlarming = false; // State flag to prevent redundant re-initialization of display buffers typedef struct { int hour; int minute; } AlarmTime; // Scheduled alarm arrays for validation const int TOTAL_ALARMS = 3; AlarmTime medicationAlarms[TOTAL_ALARMS] = { {9, 9}, // Slot 1 {9, 11}, // Slot 2 {9, 12} // Slot 3 }; // Fixed-size static allocation to prevent dangling pointers during stack deallocation char AlertMsg[50] = ""; char daysOfWeek[7][12] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; // --- CALLBACK FUNCTION PROTOTYPES --- void onTimeSyncReceived(unsigned long unixTimestamp); void onTimeRequested(); /** * @brief Hardware initialization routine. */ void setup() { Serial.begin(115200); // Updated to match default ESP32 bootloader speed to eliminate garbage text delay(1000); // Configure GPIO peripherals pinMode(BUZZER_PIN, OUTPUT); digitalWrite(BUZZER_PIN, LOW); // Initialize SPI-driven LED Matrix ledMatrix.begin(); ledMatrix.setIntensity(8); // Brightness optimization register value to prevent camera sensor overexposure ledMatrix.displayClear(); // Set initial boot token into display queue ledMatrix.displayText("Medicine Reminder System READY", PA_LEFT, 60, 2000, PA_SCROLL_LEFT, PA_SCROLL_LEFT); Serial.println("[SYS] Starting firmware initialization pipeline..."); // Initialize I2C clock communication bus if (!rtc.begin()) { Serial.println("[ERR] Fatal: DS3231 hardware module not detected on I2C bus."); Serial.flush(); while (1); } // Verify internal register state; apply fallback parameters if compile parameters mismatch if (rtc.lostPower()) { Serial.println("[RTC] Power down event detected. Aligning internal clock parameters to compile time."); rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); } // Construct Web App HTTP server routing layers webAppsServer.addApp(&homePage); webAppsServer.addApp(&webRTCPage); webAppsServer.setNotFoundPage(DIYablesNotFoundPage()); // Attach synchronization service event hooks webRTCPage.onTimeSyncFromWeb(onTimeSyncReceived); webRTCPage.onTimeRequestToWeb(onTimeRequested); // Initialize network link layer socket connection if (!webAppsServer.begin(WIFI_SSID, WIFI_PASSWORD)) { while (1) { Serial.println("[NET] Fatal: Network connection timed out."); delay(1000); } } Serial.print("[NET] Infrastructure active. Resource path accessible via: http://"); Serial.println(WiFi.localIP()); } /** * @brief Infinite loop processing task pipelines. */ void loop() { // Service inbound network sockets and data frame handshakes webAppsServer.loop(); // Non-blocking shift engine: Calculates next step pixel translations on every pass if (ledMatrix.displayAnimate()) { ledMatrix.displayReset(); } // Time-sliced task execution block running at a strict 1000ms polling interval static unsigned long lastUpdate = 0; if (millis() - lastUpdate >= 1000) { lastUpdate = millis(); // Query immediate system states from the DS3231 tracking registers DateTime currentTime = rtc.now(); int currentH = currentTime.hour(); int currentM = currentTime.minute(); int currentS = currentTime.second(); // Output status parameters to local tracking stream Serial.print("[LOG] Time Status: "); Serial.print(currentH); Serial.print(":"); Serial.print(currentM); Serial.print(":"); Serial.println(currentS); // SEQUENTIAL SEARCH SCAN ACROSS ACTIVE ALARM VECTORS for (int i = 0; i < TOTAL_ALARMS; i++) { if (currentH == medicationAlarms[i].hour && currentM == medicationAlarms[i].minute && currentS == 0) { // Conditional block protecting display memory boundaries from re-entrant override bugs if (!isAlarming) { isAlarming = true; // Print safe formatted characters straight to locked char index slots // %02d ensures leading zeros are preserved flawlessly (e.g. [23:43]) sprintf(AlertMsg, "TAKE MEDICATION ! [%02d:%02d] ", currentH, currentM); ledMatrix.displayClear(); // Link structural char reference space to the active render queue ledMatrix.displayText(AlertMsg, PA_LEFT, 60, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT); Serial.print("[ALARM] Trigger event confirmed at slot ID: "); Serial.println(i + 1); } } } // Auto-timeout block: Clears active alert metrics after 20 elapsed seconds if (currentS >= 20 && isAlarming) { isAlarming = false; ledMatrix.displayClear(); ledMatrix.displayText("Medicine Reminder System With WEB RTC", PA_LEFT, 60, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT); Serial.println("[ALARM] Trigger window expired. Display registers reset to default state."); } // Synchronize network clock states with browser clients (Executed at bottom to shield SPI lines) webRTCPage.sendTimeToWeb(currentTime.year(), currentTime.month(), currentTime.day(), currentH, currentM, currentS); } // Asynchronous Active Buzzer Duty Cycle Control (50% duty cycle, 1Hz rate square-wave generator) if (isAlarming) { static unsigned long lastBuzzerToggle = 0; if (millis() - lastBuzzerToggle >= 500) { lastBuzzerToggle = millis(); digitalWrite(BUZZER_PIN, !digitalRead(BUZZER_PIN)); // Invert state logic } } else { digitalWrite(BUZZER_PIN, LOW); // Enforce noise suppression when system state is idle } delay(10); // System cycle stabilizer trashing delay } /** * @brief Processes epoch update queries coming down from external browser UI sync commands. * @param unixTimestamp Incoming epoch time tracking token. */ void onTimeSyncReceived(unsigned long unixTimestamp) { Serial.print("[NET] Inbound synchronization frame detected: "); Serial.println(unixTimestamp); DateTime newTime(unixTimestamp); rtc.adjust(newTime); // Write updated parameters straight to external RTC register cells Serial.println("[RTC] External DS3231 synchronization routine complete."); } /** * @brief Processes outbound interface frame payload requests from polling web hosts. */ void onTimeRequested() { DateTime currentTime = rtc.now(); webRTCPage.sendTimeToWeb(currentTime.year(), currentTime.month(), currentTime.day(), currentTime.hour(), currentTime.minute(), currentTime.second()); }

    Resumo

    O exemplo WebRTC mostra como:

    • Criar uma interface web de relógio de tempo real
    • Sincronizar o RTC do ESP32 com o horário do navegador
    • Exibir as informações de horário em um formato fácil de entender
    • Monitorar as diferenças de horário e o status da conexão
    • Integrar a função de horário com outros aplicativos web
    • Criar projetos educacionais de IoT com recursos de gerenciamento de tempo

    Este exemplo é ideal para projetos que exigem marcação de tempo precisa, registro de dados com timestamps, automação agendada e demonstrações educacionais de conceitos de sincronização de horário em sistemas IoT.

    ※ NOSSAS MENSAGENS

    • Fique à vontade para compartilhar o link deste tutorial. Porém, por favor, não use nosso conteúdo em outros sites. Investimos muito esforço e tempo para criar este conteúdo, por favor respeite nosso trabalho!