這是一款簡單的ESP8266手表,具有多個位置的 WiFi 連接、NTP 時間服務器同步和比較功能。
背景
你可以買一塊現(xiàn)成的智能手表,它有很多花哨的功能,但實質上你并沒有改變任何東西?;蛘吣憧梢再I一個類似蒸汽朋克的開發(fā)工具包手表,自己編寫你感興趣的功能。
這款手表實際上不是手表,而是一個設計為掃描 WiFi 網(wǎng)絡、阻止選定連接、創(chuàng)建數(shù)十個網(wǎng)絡和混淆 WiFi 掃描儀的設備。之前有人開發(fā)了類似的軟件,里面有很多有趣的功能,但就是沒有真正的時間顯示。造成這種情況的一個原因可能是該設備不包含實時時鐘 (RTC)。這意味著每次重新啟動設備時都會丟失時間設置。但是該設備有一個 WiFi 芯片,因此只需要使用正確的代碼之后,您就可以從時間服務器獲取時間了。
NTP
我對 WiFi 攻擊不感興趣,但對如何實現(xiàn)時間服務器功能感興趣。網(wǎng)絡時間協(xié)議(NTP) 是一種基于網(wǎng)絡的時鐘同步協(xié)議。espressive ESP SDK提供了訪問 NTP 服務器和輕松轉換時間的功能。讓您無需擔心 UDP 連接和數(shù)據(jù)交換。只需包含庫Time.h ,定義 NTP 服務器名稱,從服務器創(chuàng)建時間變量,配置通信并獲取時間:
通過這種簡單的方式,您可以從時間服務器獲取當前時間(以秒為單位)。此值(NTP 時間戳)編碼為自 1900 年 1 月 1 日 00:00:00 以來的秒數(shù),也稱為“紀元”。例如,值1587775785對應于以下日期:Saturday, 25. April 2020 00:49:45
要將 epoch 值轉換為可管理的值,庫中提供了函數(shù)localtime_r() 。此函數(shù)將紀元轉換為結構,以便您可以直接處理分鐘、秒、小時和日期值:
// 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 ()函數(shù)返回自系統(tǒng)啟動以來經過的秒數(shù)。該值也是一個紀元,因此可以使用函數(shù)localtime_r()進行轉換。但這還不是全部:您還可以簡單地為其添加一個紀元并獲得一個新的時間值。這正是我在代碼中所做的,以使系統(tǒng)時間與 NTP 時間同步。啟動時系統(tǒng)時間為零,即 01.01.1970。按下導航按鈕,從時間服務器檢索當前時間信息。然后將此信息添加到系統(tǒng)時間。因此,系統(tǒng)時間具有當前時間,并且每次調用該函數(shù)sysTime_now()實際時間被計數(shù)。再次向上按下按鈕可從時間服務器檢索當前時間值。但是現(xiàn)在當前系統(tǒng)時間值只與時間服務器值進行比較。時間本身沒有改變。如果處理器時鐘非常準確,那么即使在較長一段時間內也不會出現(xiàn)可測量的偏差。
時區(qū)
時間服務器的返回值始終為 UTC。但是有一種非常簡單的方法可以自動將時間轉換為所需的時區(qū):您只需通過設置TZ環(huán)境變量來指定時區(qū):
現(xiàn)在,無論何時調用localtime_r()函數(shù),值都會根據(jù)配置的時區(qū)自動轉換。時區(qū)字符串看起來很奇怪,但這里有一個時區(qū)字符串列表,可以簡單地復制您需要的字符串。最理想的情況是在字符串中也定義了夏令時,因此切換的同時也會自動變換。唯一需要注意的是電池始終處于充電狀態(tài)。根據(jù)使用情況,它可能會持續(xù)大約 7 小時左右。
其他版本
該固件“開箱即用”也適用于舊版手表和“DSTIKE WiFi Deauther OLED V6”板:
故障排除
例:使用最新版本的顯示驅動程序時,屏幕不再工作,并且屏幕顯示黑色。
為此,必須編輯 platformio.ini 文件中的 lib-deps:
然后用這些命令
-
WIFI
+關注
關注
81文章
5301瀏覽量
204205 -
智能手表
+關注
關注
36文章
3297瀏覽量
114409 -
ESP8266
+關注
關注
50文章
962瀏覽量
45170
發(fā)布評論請先 登錄
相關推薦
評論