如何利用ESP8266和Neopixel Ring实现时钟的彩色显示

描述

本文将介绍一个基于 ESP8266(从 NTP 服务器获取时间)和 Neopixel Ring 的简单时钟,以彩色显示小时、分钟和秒。

介绍
为了做出这个简单的时钟,我买了一个 24 LED Neopixel Ring 。我最初计划将它用于 Cheerlights 项目,但在制作了 Cheerlight 之后,我认为这是对 Neopixel Ring的严重浪费。因此,在一周后我下定了决心。我最终决定用 Ring 制作一个时钟。

你需要什么
ESP8266 与 wifi 一样非常适合此功能,因此可以通过 WiFi 获取时间,并且还可以控制 Neopixel Ring。我使用 Wemos D1 Mini,因为它们非常易于使用,具有用于电源和数据的微型 USB 连接,只需几美元,并且可以很容易地与 Arduino IDE 一起使用。这是一个非常简单的项目,代码简单,电路方式不多。

Neopixel 环有 3 个连接:5v、接地和数据。您需要做的就是将 3 根电线焊接到环上的这 3 个焊盘上。D1 Mini 上的 VCC 和 Gnd 连接到 5v 和接地,数据引脚可以连接到任何输出引脚。

时钟

对于代码,您将需要 3 个库:

时钟

Adafruit_NeoPixel库可以从https://github.com/adafruit/Adafruit_NeoPixel下载

TimeClient库是 Squix 气象站代码的一部分,可以从https://github.com/squix78/esp8266-weather-station下载

只需将TimeClient.cpp和 TimeClient.h 文件复制到您的草图文件夹中。

TimeClient 库通过 WiFi 连接到互联网并访问www.google.com来工作。然后它会抓取网页的标题以从标题中获取时间和日期。

当您将 ESP8266 安装为可识别的板时,ESP8266WiFi库随 Arduino IDE 一起提供。在开始项目之前,不要忘记使用 Arduino IDE Boards Manager 安装 ESP8266 文件。

第 1 步
我们将使用 D1 Mini 上的 Pin 5 作为数据线。

#define PIN D5

我们需要在我们的代码中跟踪最后一次来自互联网的时间更新是什么时候发生的,以及自一秒前以来已经过了多长时间(以跟踪秒数)。

long lastUpdate = millis();
long lastSecond = millis();

小时、分钟和秒存储在字符串变量中。

String hours, minutes, seconds;

以及我们跟踪的当前秒、分和小时。

int currentSecond, currentMinute, currentHour;

字符数组用于存储您的 WiFi SSID 和密码。在此处输入您自己的详细信息:

char ssid[] = "xxxxxxx";  //  your network SSID (name)
char pass[] = "xxxxxxx";       // your network password

我住在伦敦,所以我与 UTC 有 0 小时的偏移,但夏令时除外,它是 1 小时。为您自己的时区设置偏移量。

const float UTC_OFFSET = 0;

我们创建一个 timeClient 对象并将 UTC 偏移量传递给它。

TimeClient timeClient(UTC_OFFSET);

然后创建一个 NeoPixel 对象,将其命名为“strip”,并将 LED 的数量和我们用于数据线的引脚传递给它。

Adafruit_NeoPixel strip = Adafruit_NeoPixel(24, PIN);

第 2 步
在设置功能中,我们将首先打开串行通信以进行调试。

void setup()
{
 Serial.begin(115200);

然后需要初始化 NeoPixel 环,我们将亮度设置为 50%

strip.begin();
strip.setBrightness(128);

在我们执行 .show 命令之前,环上什么都不会发生。

strip.show();

接下来我们连接到您的 WiFi:

WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {

然后从 timeClient 库中更新时间。

 timeClient.updateTime();

接下来我们运行我们自己的函数 updateTime(); 它调用库函数来获取当前的小时、分钟和秒。

updateTime() ;

最后,在主循环之前,我们检索并存储 millis() 的当前值,以便我们可以跟踪自上次从互联网更新时间以来已经过去了多长时间,并且还可以跟踪经过的秒数,因此第二个可以更新。

lastUpdate = millis();
 lastSecond = millis();
}

第 3 步
设置功能完成。接下来主循环函数将运行。

void loop()
{

如果距离我们上次更新时间已经过去了 1,800,000 毫秒(30 分钟),我们将再次从 Internet 更新时间。

if ((millis() - lastUpdate) > 1800000) updateTime();

显示器上的小时、分钟和秒每秒都会更新一次,因此我们需要检查自上次更新显示器以来是否经过了 1000 毫秒。如果是,则执行 if 语句中的代码。

 if ((millis() - lastSecond) > 1000)
 {

第 4 步
“手”的颜色是:

红色 = 小时

绿色 = 分钟

蓝色 = 秒

.setPixelColor 命令用于设置“手”的颜色。我使用的戒指有 24 个 RGB LED,因此秒和分钟除以 2.5,因此它们显示在戒指的正确象限上,小时(24 小时格式)除以 2。在时间更改之前,我们设置当前'hands' 到 OFF 以清除最后的位置。

strip.setPixelColor(currentSecond / 2.5, 0, 0, 0);
strip.setPixelColor(currentMinute / 2.5, 0, 0, 0);
strip.setPixelColor(currentHour * 2, 0, 0, 0);
strip.show();

现在存储 millis() 的当前值。

 lastSecond = millis();

接下来,存储在 currentSecond 中的值增加 1。然后我们检查秒数是否超过 59,如果是,则将它们设置回 0。发生这种情况时,我们还将分钟数增加 1 并执行相同的检查。如果分钟超过 59,那么我们也将小时增加 1。

currentSecond++;
   if (currentSecond > 59)
   { currentSecond = 0;
     currentMinute++;
     if (currentMinute > 59) {
       currentMinute = 0;
       currentHour++;
       if (currentHour > 12) currentHour = 0;
     }
   }

虽然没有必要,但我将当前时间打印到串行监视器窗口以进行调试。我使用 String 对象来生成时间字符串。

String currentTime = String(currentHour) + ':' + String(currentMinute) + ':' + String(currentSecond);
   Serial.println(currentTime);

现在已经更新了秒、分和小时,我们可以将相关的“指针”设置为它们各自的 RGB 值。

strip.setPixelColor(currentSecond / 2.5, 0, 0, 255);
   strip.setPixelColor(currentMinute / 2.5, 0, 255, 0);
   strip.setPixelColor(currentHour * 2, 255, 0, 0);
   strip.show();

最后,我们创建了自己的函数 updateTime()。这会在开始时更新,然后每 30 分钟更新一次,以保持准确的时间。

void updateTime() 
{

我们从 timeClient 库中获取小时、分钟和秒。

 hours = timeClient.getHours();
 minutes = timeClient.getMinutes();
 seconds = timeClient.getSeconds();

并将这些值存储为整数(它们从 timeClient 库作为字符串返回)。24 小时转换为 12 小时格式。

currentHour = hours.toInt();
 if (currentHour > 12) currentHour = currentHour - 12;
 currentMinute = minutes.toInt();
 currentSecond = seconds.toInt();

最后,我们希望能够检查自上次更新以来是否已经过去了 30 分钟,因此我们再次存储 millis() 的当前值。

 lastUpdate = millis();

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

全部0条评论

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

×
20
完善资料,
赚取积分