這是一款簡單的ESP8266手表,具有多個位置的 WiFi 連接、NTP 時間服務器同步和比較功能。
背景
你可以買一塊現成的智能手表,它有很多花哨的功能,但實質上你并沒有改變任何東西。或者你可以買一個類似蒸汽朋克的開發工具包手表,自己編寫你感興趣的功能。
這款手表實際上不是手表,而是一個設計為掃描 WiFi 網絡、阻止選定連接、創建數十個網絡和混淆 WiFi 掃描儀的設備。之前有人開發了類似的軟件,里面有很多有趣的功能,但就是沒有真正的時間顯示。造成這種情況的一個原因可能是該設備不包含實時時鐘 (RTC)。這意味著每次重新啟動設備時都會丟失時間設置。但是該設備有一個 WiFi 芯片,因此只需要使用正確的代碼之后,您就可以從時間服務器獲取時間了。
NTP
我對 WiFi 攻擊不感興趣,但對如何實現時間服務器功能感興趣。網絡時間協議(NTP) 是一種基于網絡的時鐘同步協議。espressive ESP SDK提供了訪問 NTP 服務器和輕松轉換時間的功能。讓您無需擔心 UDP 連接和數據交換。只需包含庫Time.h ,定義 NTP 服務器名稱,從服務器創建時間變量,配置通信并獲取時間:
通過這種簡單的方式,您可以從時間服務器獲取當前時間(以秒為單位)。此值(NTP 時間戳)編碼為自 1900 年 1 月 1 日 00:00:00 以來的秒數,也稱為“紀元”。例如,值1587775785對應于以下日期:Saturday, 25. April 2020 00:49:45
要將 epoch 值轉換為可管理的值,庫中提供了函數localtime_r() 。此函數將紀元轉換為結構,以便您可以直接處理分鐘、秒、小時和日期值:
// the tm structure contains the following data:
//
// int tm_sec; --> 0 .. 59
// int tm_min; --> 0 .. 59
// int tm_hour; --> 0 .. 23
// int tm_mday; --> 1 .. 31
// int tm_mon; --> 0 .. 11 (0 = January)
// int tm_year; --> years since 1900
// int tm_wday; --> 0 .. 6 (0 = Sunday)
// int tm_yday; --> 0 .. 365
// int tm_isdst; --> Daylight Saving Time flag
//
tm dateTime;
void loop() {
// time() fetch the actual time from the NTP server
// and store it as epoch into the variable
time(&NTPTime);
// localtime_r() converts the epoch into the tm-structure
localtime_r(&NTPTime, &dateTime);
Serial.print(dateTime.tm_hour);
Serial.print(':');
Serial.print(dateTime.tm_min);
Serial.print(':');
Serial.println(dateTime.tm_sec);
delay(1000);
}
注意:月份 ( tm_mon ) 和星期幾 ( tm_wday ) 的值:它們從 0 開始,而不是從 1!要獲得正確的年份值,您只需將值tm_year添加 1900 。
手表
為了保持代碼簡單、干凈和可讀,我為手表編寫了一個類,它封裝了 LED、按鈕和顯示屏。Watch-object 需要在開始時進行初始化。然后您可以輕松訪問 LED、顯示屏或按鈕,而無需任何進一步的初始化。
該庫需要以下庫:
確保它們已安裝。最簡單的方法是在 Platformio.ini 文件中輸入 lib 依賴項:
還可以看到,我選擇了標準的espressif8266平臺和nodemcuv2作為板定義,這可以使上傳工作正常,無需任何進一步的調整。
時間漂移
由于手表沒有實時時鐘(RTC),因此必須使用處理器時鐘來計算時間。sysTime_now ()函數返回自系統啟動以來經過的秒數。該值也是一個紀元,因此可以使用函數localtime_r()進行轉換。但這還不是全部:您還可以簡單地為其添加一個紀元并獲得一個新的時間值。這正是我在代碼中所做的,以使系統時間與 NTP 時間同步。啟動時系統時間為零,即 01.01.1970。按下導航按鈕,從時間服務器檢索當前時間信息。然后將此信息添加到系統時間。因此,系統時間具有當前時間,并且每次調用該函數sysTime_now()實際時間被計數。再次向上按下按鈕可從時間服務器檢索當前時間值。但是現在當前系統時間值只與時間服務器值進行比較。時間本身沒有改變。如果處理器時鐘非常準確,那么即使在較長一段時間內也不會出現可測量的偏差。
時區
時間服務器的返回值始終為 UTC。但是有一種非常簡單的方法可以自動將時間轉換為所需的時區:您只需通過設置TZ環境變量來指定時區:
現在,無論何時調用localtime_r()函數,值都會根據配置的時區自動轉換。時區字符串看起來很奇怪,但這里有一個時區字符串列表,可以簡單地復制您需要的字符串。最理想的情況是在字符串中也定義了夏令時,因此切換的同時也會自動變換。唯一需要注意的是電池始終處于充電狀態。根據使用情況,它可能會持續大約 7 小時左右。
其他版本
該固件“開箱即用”也適用于舊版手表和“DSTIKE WiFi Deauther OLED V6”板:
故障排除
例:使用最新版本的顯示驅動程序時,屏幕不再工作,并且屏幕顯示黑色。
為此,必須編輯 platformio.ini 文件中的 lib-deps:
然后用這些命令
-
WIFI
+關注
關注
81文章
5297瀏覽量
203717 -
智能手表
+關注
關注
36文章
3286瀏覽量
114070 -
ESP8266
+關注
關注
50文章
962瀏覽量
45008
發布評論請先 登錄
相關推薦
評論