这是一款简单的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浏览量
203778 -
智能手表
+关注
关注
36文章
3291浏览量
114111 -
ESP8266
+关注
关注
50文章
962浏览量
45045
发布评论请先 登录
相关推荐
评论