Szukaj kodu

Poradnik ESP32 53/55 - Zbuduj internetowy zegar LCD | Zestaw edukacyjny SunFounder ESP32 IoT

Poradnik ESP32 53/55 - Zbuduj internetowy zegar LCD | Zestaw edukacyjny SunFounder ESP32 IoT

W tym samouczku zbudujemy zegar LCD podłączony do Internetu, wykorzystując mikrokontroler ESP32 firmy SunFounder. Zegar ten będzie automatycznie synchronizował się z aktualnym czasem przez Internet, wyświetlając czas w formacie 12- lub 24-godzinnym, wraz z dniem tygodnia, datą i miesiącem. Zastosowanie protokołu NTP (Network Time Protocol) zapewnia, że zegar pozostaje dokładny bez ręcznych regulacji.

esp32-53-internet-clock-main

Ten projekt wykorzystuje wbudowane możliwości Wi-Fi modułu ESP32 do pobierania aktualnego czasu z serwera NTP. Do wyświetlania czasu użyjemy wyświetlacza ciekłokrystalicznego (LCD), który można sformatować zgodnie z preferencjami użytkownika. W celu dalszego wyjaśnienia poszczególnych kroków, zapoznaj się z filmem (na filmie w 00:30).

Omówienie sprzętu

Główne komponenty tego projektu to mikrokontroler ESP32, wyświetlacz LCD 20x4 oraz źródło zasilania. ESP32 to wydajny mikrokontroler z wbudowanym Wi-Fi i Bluetooth, co czyni go odpowiednim do projektów IoT. Wyświetlacz LCD służy do pokazywania czasu i daty i można go skonfigurować dla różnych rozmiarów wyświetlania.

Wyświetlacz LCD działa poprzez protokół I2C, który umożliwia komunikację za pomocą dwóch przewodów (SDA i SCL). Upraszcza to okablowanie i zmniejsza liczbę pinów potrzebnych na ESP32. Połączenie z serwerem NTP jest realizowane za pomocą funkcji Wi-Fi modułu ESP32, co umożliwia aktualizacje w czasie rzeczywistym.

 

  • Zapewnij prawidłowe napięcie zasilania (5 V).
  • Użyj kondensatorów odsprzęgających w pobliżu pinów zasilania dla stabilności.
  • Zachowaj ostrożność przy połączeniach I2C, aby uniknąć konfliktów na magistrali.
  • Zweryfikuj adres I2C wyświetlacza LCD (0x27 lub 0x3F).
  • Sprawdź dane logowania do Wi-Fi, aby zapewnić prawidłowe połączenie.
  • Uwzględnij zmiany czasu letniego/zimowego w swoim kodzie.
  • Użyj prawidłowego serwera NTP dla swojej lokalizacji geograficznej.
  • Zawsze czyść wyświetlacz LCD przed aktualizacją ekranu.

Instrukcje okablowania

ESP32-11_LCD-wiring

Aby podłączyć ESP32 do wyświetlacza LCD, zacznij od podłączenia pinów zasilania. Podłącz VCC wyświetlacza LCD do pinu 5V na ESP32, a pin GND wyświetlacza LCD do pinu GND na ESP32. Do komunikacji I2C podłącz pin SDA wyświetlacza LCD do GPIO 21 na ESP32, a pin SCL do GPIO 22. Upewnij się, że połączenia są pewne, aby uniknąć problemów z komunikacją.

Podczas konfigurowania okablowania użyj przewodów połączeniowych męsko-żeńskich, aby ułatwić podłączanie. Jeśli Twój wyświetlacz LCD ma inny adres I2C lub konfigurację pinów, odpowiednio dostosuj kod. W razie potrzeby zapoznaj się z filmem (na filmie w 05:30) w celu uzyskania alternatywnych opcji okablowania.

Przykłady kodu i omówienie

Kod inicjalizuje wyświetlacz LCD i konfiguruje połączenie Wi-Fi w celu pobierania danych czasu z serwera NTP. Kluczowe identyfikatory, takie jak ssid i password, służą do połączenia z siecią Wi-Fi, natomiast ntpServer1 i ntpServer2 określają serwery NTP do użycia.

const char* ssid = "dars";
const char* password = "llllllllllllll";
const char* ntpServer1 = "pool.ntp.org";
const char* ntpServer2 = "time.nist.gov";

Ten fragment pokazuje dane logowania do sieci i adresy serwerów. Upewnij się, że poprawnie wprowadziłeś swoją nazwę SSID i hasło Wi-Fi, ponieważ każdy błąd uniemożliwi ESP32 połączenie z Internetem.

W funkcji printLocalTime() bieżący czas jest formatowany do wyświetlenia. Struktura tm służy do przechowywania informacji o czasie, a strftime pomaga sformatować czas w czytelny ciąg znaków.

void printLocalTime() {
  struct tm timeinfo;
  if(!getLocalTime(&timeinfo)) {
    Serial.println("No time available (yet)");
    return;
  }
  char timeHour[5];
  strftime(timeHour, 5, "%H", &timeinfo);

Ten kod sprawdza, czy czas lokalny jest dostępny, i pobiera godzinę. Sformatowana godzina jest następnie używana do wyświetlania bieżącego czasu na wyświetlaczu LCD. Jeśli czas nie jest jeszcze dostępny, wypisuje komunikat w monitorze szeregowym.

Na koniec funkcja setup() inicjalizuje wyświetlacz LCD i łączy się z Wi-Fi. Konfiguruje również ustawienia serwera NTP i ustawia funkcję zwrotną do synchronizacji czasu.

void setup() {
  Serial.begin(115200);
  lcd.init(); // initialize the lcd 
  lcd.backlight(); // Turns on the LCD backlight.
  Serial.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);

Ten fragment inicjalizuje monitor szeregowy do debugowania, konfiguruje wyświetlacz LCD i próbuje połączyć się z określoną siecią Wi-Fi. Status połączenia zostanie wypisany w monitorze szeregowym, co pozwoli zweryfikować połączenie.

Demonstracja / Czego się spodziewać

Po pomyślnej konfiguracji wyświetlacz LCD pokaże bieżący czas, dzień tygodnia i datę. Możesz oczekiwać, że czas będzie aktualizowany co 5 sekund dzięki funkcji loop(). Jeśli połączenie z serwerem NTP nie powiedzie się, w monitorze szeregowym pojawi się komunikat informujący, że czas nie jest jeszcze dostępny (na filmie w 12:00).

Typowe problemy obejmują nieprawidłowe okablowanie, błędne adresy I2C i nieprawidłowe dane logowania do Wi-Fi. Upewnij się, że wszystkie połączenia są pewne i że serwer NTP jest osiągalny z Twojej sieci.

Znaczniki czasu w filmie

  • 00:00 Start
  • 2:10 Wprowadzenie
  • 5:15 Omówienie okablowania
  • 7:32 Omówienie kodu Arduino
  • 18:43 Wybór płytki ESP32 i portu COM w Arduino IDE
  • 20:27 Demonstracja zegara internetowego

Obrazy

ESP32-11_LCD-wiring
ESP32-11_LCD-wiring
ESP32-11_LCD-wiring-schematic
ESP32-11_LCD-wiring-schematic
esp32-53-internet-clock-main
esp32-53-internet-clock-main
854-ESP32 Tutorial 53/55- Internet Clock
Język: C++

/*
Internet Clock using SunFounder's IoT ESP32 Learning kit
Full video instruction https://youtu.be/0KnuNqfiVug
📚⬇️ Download and resource page https://robojax.com/RJT686
Internet Clock for ESP32
Written by Ahamd Shasmhiri on Dec 31, 2023 at 19:29
www.Robojax.com

*/
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
//SDA->21,SCL->22 
LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

const bool showSeconds = true;//set to "true" to show seconds and "false" to hide
const bool showShortMonth = false;//December = false, Dec=true
const bool show24Hours = true;//true to have 18:30 or false to have 6:30

#include <WiFi.h>
#include "time.h"
#include "sntp.h"
#include "TZ.h"
//TZ.h is taken from https://github.com/esp8266/Arduino/blob/master/cores/esp8266/TZ.h


const char* ssid       = "dars";
const char* password   = "llllllllllllll";

const char* ntpServer1 = "pool.ntp.org";
const char* ntpServer2 = "time.nist.gov";
const long  gmtOffset_sec = -5 * 3600;
const int   daylightOffset_sec = 3600;


const String months[][2] ={
            "January","Jan",
            "February","Feb",
            "March","Mar",
            "April","Apr",
            "May","May",
            "June","Jun",
            "July","Jul",
            "August","Aug",
            "September","Sep",
            "October","Oct",
            "November","Nov",
            "December","Dec"
      };


void printLocalTime()
{
  struct tm timeinfo;
  if(!getLocalTime(&timeinfo)){
    Serial.println("No time available (yet)");
    return;
  }


  //Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S 12Hours: %I:%M:%S");

    // get time format HH:MM
  char timeHour[5];
  strftime(timeHour,5, "%H", &timeinfo);
  String hourString = String(timeHour);//convert timeHour to string
  char timeMinute[3];
  strftime(timeMinute,3, "%M", &timeinfo); 
  String minuteString = String(timeMinute);  
  //Serial.println(hourString);
  if(!show24Hours)
  {
    if(hourString.toInt()  >= 12) 
    {
       minuteString =  minuteString + "PM";
    }else{
       minuteString =  minuteString + "AM";      
    }
 
  }



  char timeSeconds[3];
  strftime(timeSeconds,3, "%S", &timeinfo);  

  char timeDayofWeek[10];
  strftime(timeDayofWeek, 10 , "%A", &timeinfo);  

  char timeMonth[10];
  strftime(timeMonth, 10 , "%B", &timeinfo); 
  String Month = String(timeMonth);
  if(showShortMonth)
  {
  for(int m=0; m <12; m++)
  {

    if(Month == months[m][0] )
    {
      Month = months[m][1];
      //Serial.println(months[m][1]);
    }
  }
  }

  char timeDayofMonth[3];
  strftime(timeDayofMonth,3 , "%d", &timeinfo);   

  char timeYear[5];
  strftime(timeYear, 5 , "%Y", &timeinfo);   


  String time = String(timeHour) + ":" +  minuteString ;
  if(showSeconds) time = time +":" + String(timeSeconds);//add seconds if showSeconds=true
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(time);
  lcd.print(" ");
  lcd.print(String(timeDayofWeek));
  //
  lcd.setCursor(0, 1);
  lcd.print(timeDayofMonth);

  lcd.print(" ");
  lcd.print(Month);

  lcd.print(" ");
  lcd.print(timeYear);





}

// Callback function (get's called when time adjusts via NTP)
void timeavailable(struct timeval *t)
{
  Serial.println("Got time adjustment from NTP!");
  printLocalTime();
}

void setup()
{
  Serial.begin(115200);
  lcd.init();// initialize the lcd 
  lcd.backlight(); // Turns on the LCD backlight.
  lcd.print("Internet Clock"); 
  delay(3000);//waif 3 seconds
  // set notification call-back function
  sntp_set_time_sync_notification_cb( timeavailable );

  /**
   * NTP server address could be aquired via DHCP,
   *
   * NOTE: This call should be made BEFORE esp32 aquires IP address via DHCP,
   * otherwise SNTP option 42 would be rejected by default.
   * NOTE: configTime() function call if made AFTER DHCP-client run
   * will OVERRIDE aquired NTP server address
   */
  sntp_servermode_dhcp(1);    // (optional)

  /**
   * This will set configured ntp servers and constant TimeZone/daylightOffset
   * should be OK if your time zone does not need to adjust daylightOffset twice a year,
   * in such a case time adjustment won't be handled automagicaly.
   */
// configTime(gmtOffset_sec, daylightOffset_sec, ntpServer1, ntpServer2);

  /**
   * A more convenient approach to handle TimeZones with daylightOffset 
   * would be to specify a environmnet variable with TimeZone definition including daylight adjustmnet rules.
   * A list of rules for your zone could be obtained from https://github.com/esp8266/Arduino/blob/master/cores/esp8266/TZ.h
   */
   
  //configTzTime(TZ_America_Toronto, ntpServer1, ntpServer2);
  configTzTime(TZ_America_Toronto, ntpServer1, ntpServer2);  

  //connect to WiFi
  Serial.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
  }
  Serial.println(" CONNECTED");

}

void loop()
{
  delay(5000);
  printLocalTime();     // it will take some time to sync time :)
}

Rzeczy, których możesz potrzebować

Zasoby i odniesienia

Pliki📁

Wymagany plik (.h)