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