如何利用ESP8266实现智能手表的设计

描述

  这是一款简单的ESP8266手表,具有多个位置的 WiFi 连接、NTP 时间服务器同步和比较功能。

  背景

  你可以买一块现成的智能手表,它有很多花哨的功能,但实质上你并没有改变任何东西。或者你可以买一个类似蒸汽朋克的开发工具包手表,自己编写你感兴趣的功能。

  这款手表实际上不是手表,而是一个设计为扫描 WiFi 网络、阻止选定连接、创建数十个网络和混淆 WiFi 扫描仪的设备。之前有人开发了类似的软件,里面有很多有趣的功能,但就是没有真正的时间显示。造成这种情况的一个原因可能是该设备不包含实时时钟 (RTC)。这意味着每次重新启动设备时都会丢失时间设置。但是该设备有一个 WiFi 芯片,因此只需要使用正确的代码之后,您就可以从时间服务器获取时间了。

  NTP

  我对 WiFi 攻击不感兴趣,但对如何实现时间服务器功能感兴趣。网络时间协议(NTP) 是一种基于网络的时钟同步协议。espressive ESP SDK提供了访问 NTP 服务器和轻松转换时间的功能。让您无需担心 UDP 连接和数据交换。只需包含库Time.h ,定义 NTP 服务器名称,从服务器创建时间变量,配置通信并获取时间:

  

WIFI

  通过这种简单的方式,您可以从时间服务器获取当前时间(以秒为单位)。此值(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、显示屏或按钮,而无需任何进一步的初始化。

  

WIFI

  该库需要以下库:

  

WIFI

  确保它们已安装。最简单的方法是在 Platformio.ini 文件中输入 lib 依赖项:

  

WIFI

  还可以看到,我选择了标准的espressif8266平台和nodemcuv2作为板定义,这可以使上传工作正常,无需任何进一步的调整。

  时间漂移

  由于手表没有实时时钟(RTC),因此必须使用处理器时钟来计算时间。sysTime_now ()函数返回自系统启动以来经过的秒数。该值也是一个纪元,因此可以使用函数localtime_r()进行转换。但这还不是全部:您还可以简单地为其添加一个纪元并获得一个新的时间值。这正是我在代码中所做的,以使系统时间与 NTP 时间同步。启动时系统时间为零,即 01.01.1970。按下导航按钮,从时间服务器检索当前时间信息。然后将此信息添加到系统时间。因此,系统时间具有当前时间,并且每次调用该函数sysTime_now()实际时间被计数。再次向上按下按钮可从时间服务器检索当前时间值。但是现在当前系统时间值只与时间服务器值进行比较。时间本身没有改变。如果处理器时钟非常准确,那么即使在较长一段时间内也不会出现可测量的偏差。

  时区

  时间服务器的返回值始终为 UTC。但是有一种非常简单的方法可以自动将时间转换为所需的时区:您只需通过设置TZ环境变量来指定时区:

  

WIFI

  现在,无论何时调用localtime_r()函数,值都会根据配置的时区自动转换。时区字符串看起来很奇怪,但这里有一个时区字符串列表,可以简单地复制您需要的字符串。最理想的情况是在字符串中也定义了夏令时,因此切换的同时也会自动变换。唯一需要注意的是电池始终处于充电状态。根据使用情况,它可能会持续大约 7 小时左右。

  其他版本

  该固件“开箱即用”也适用于旧版手表和“DSTIKE WiFi Deauther OLED V6”板:

  

WIFI

  故障排除

  例:使用最新版本的显示驱动程序时,屏幕不再工作,并且屏幕显示黑色。

  为此,必须编辑 platformio.ini 文件中的 lib-deps:

  

WIFI

  然后用这些命令

  

WIFI
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分