2023年2月5日 星期日

ESP32 取得網路時間並顯示於OLED

本實作使用 WeMos LoLin32 開發板配合U8g2程式庫於OLED中顯示訊息。直接將 WeMos LoLin32 以 USB 線連接到開發電腦進行程式編譯上傳即可。使用Arduino IDE 編譯 ESP32 程式前請先確認已經正確選定開發板規格。

ESP32 與 OLED 接腳設定
1. 電源接線:
【ESP32】3.3V →【OLED】VCC
【ESP32】GND →【OLED】GND
2. 信號接線:
【ESP32】22→【ESP-01】SCL
【ESP32】21→【ESP-01】SDA

時間是軟硬體系統與設備中的重要資訊,特別是需要和外部進行資訊交換時更有個校準的標準時間。目前的IOT設備因為都能連上網路,因此都可以藉由網路從網路時間伺服器(NTP)上獲取標準時間,本實作的主角ESP32亦是如此。

使用ESP32獲取網路時間伺服器(NTP)上的標準時間,步驟如下: 
 1. 使用WiFi 模組以STA或ETH模式連上網。
 2. 使用下列函數從網路時間伺服器上獲取並設置時間:
void configTime(long gmtOffset_sec, int daylightOffset_sec,
const char* server1, const char* server2 = nullptr, const char* server3 = nullptr)
  • gmtOffset 參數用來修正時區,比如台灣地區(UTC/GMT+08:00)參數就需填寫28800( 8 * 3600)。 
  • daylightOffset 參數是夏令時間設置,使用夏令時 daylightOffset_sec 就填寫3600,否則就填寫0,台灣地區就是填0。 
  • Server參數為網路時間伺服器,最常用的主機為 pool.ntp.org。
3. 如果順利連上網路時間伺服器請取回時間資訊,即可使用下面函數讀取當前時間:
bool getLocalTime(struct tm * info, uint32_t ms = 5000)
  • ms 為該操作逾時時間,逾時操作回傳false。 
  • info 是一個 struct tm 結構物件,用於接收當前時間。
撰寫實驗程式如下:
#include <WiFi.h>
#include <time.h>
#include <U8g2lib.h> //引入OLED程式庫

U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);

const char ssid[]="HUAWEI_B316_5803"; //Wifi基地台ID
const char psw[]="justin12200713";   //Wifi連線密碼

const char ntpServer[] = "pool.ntp.org";
const uint16_t utcOffest = 28800;  // UTC+8偏移量
const uint8_t daylightOffset = 0;   // 夏令時間

void setup() {
  Serial.begin(115200);
   u8g2.begin(); //初始顯示器物件
   u8g2.setFont(u8g2_font_t0_22b_te); //指定字型
  WiFi.begin(ssid, psw); //指定連線資訊
  
  //嘗試間隔0.5秒連線一次,直到連線成功
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print("WIFI連線中 \n");
    delay(500);
  }
  
  Serial.print("IP位址:");
  Serial.println(WiFi.localIP());

  //取回網路標準時間
  configTime(utcOffest, daylightOffset, ntpServer); //UCT偏移量,夏日時間,時間伺服器
  delay(1000);
}

void loop() {
   struct tm now; // 建立時間結構變數
  if(!getLocalTime(&now)){          // 測試是否取得本地時間
    u8g2.clearBuffer(); //清除暫存區
    u8g2.drawStr(5, 55, "ERROR!!");
    u8g2.sendBuffer(); //送出繪製內容
    return;
  }
  
  //在OLED中顯示日期時間
   u8g2.firstPage();
  do {
    u8g2.setCursor(5, 20);
    u8g2.print(&now, "%Y/%m/%d"); //列印日期
    u8g2.setCursor(15, 62);
    u8g2.print(&now, "%H:%M:%S");  //列印時間
  } while ( u8g2.nextPage() );
 delay(1000);
}
順利連上WiFi後,在序列埠顯示目前的本地端IP:
在OLED中顯示即時日期時間:

沒有留言:

張貼留言