Menu
CoddyTech

NeoPixel 时钟:设置时间

本课属于 Coddy Arduino 学习旅程的“项目”单元。第 24 课,共 24 课。

时钟总是从 10:24:50 开始,每天只有一次时间是正确的。两个按钮可以调整时间:连接到引脚 2 的红色按钮让时钟快进一小时,连接到引脚 3 的绿色按钮让时钟快进 5 分钟,也就是分钟指针移动一个像素。

时间是一个数字,所以设置时间就是增加秒数。用一个变量保存按钮增加的时间,并将它加到总和中:

unsigned long adjust = 0;   // 按钮增加的秒数

unsigned long now = startTime + adjust + millis() / 1000;

一小时是 3600 秒,5 分钟是 300 秒。每次按下按钮时只计数一次,也就是现在的状态是 LOW,上一次的状态是 HIGH。如果按钮按住时每次循环都增加时间,时钟就会飞快地转动。这些按钮不会抖动。

int hourState = digitalRead(hourButton);
if (hourState == LOW && lastHour == HIGH) {
  adjust = adjust + 3600;
}
lastHour = hourState;

所有指针都根据 now 计算,因此它们会同步移动。余数运算会让小时在 11 之后回到开头,让分钟在 55 之后回到开头。

challenge icon

挑战

中等

让时间可以设置:

  • 引脚 2 和 3 设置为 INPUT_PULLUP
  • 按下引脚 2 对应的按钮时增加 3600 秒,按下引脚 3 对应的按钮时增加 300 秒,每次按下按钮时只计数一次
  • 将这些秒数加到 now 上

按“运行”,把时钟设置为你要的时间,然后按“检查”。

亲手试试

#include <Adafruit_NeoPixel.h>

const int ringPin = 6;
const int pixelCount = 12;
Adafruit_NeoPixel ring(pixelCount, ringPin, NEO_GRB + NEO_KHZ800);

// 时钟的起始时间,以午夜起经过的秒数表示:10:24:50
const unsigned long startTime = 10 * 3600UL + 24 * 60 + 50;

void setup() {
  ring.begin();
}

void loop() {
  unsigned long now = startTime + millis() / 1000;  // 当天的时间,以秒为单位
  int seconds = now % 60;
  int minutes = (now / 60) % 60;
  int hours = (now / 3600) % 12;

  int secondPixel = seconds / 5;
  int minutePixel = minutes / 5;
  int hourPixel = hours;

  // 每个像素从时针获得红色,从分针获得绿色
  // 从秒针获得蓝色,因此重合在同一像素上的指针颜色会混合。
  for (int i = 0; i < pixelCount; i++) {
    int r = 0;
    int g = 0;
    int b = 0;
    if (i == hourPixel) {
      r = 255;
    }
    if (i == minutePixel) {
      g = 255;
    }
    if (i == secondPixel) {
      b = 255;
    }
    ring.setPixelColor(i, ring.Color(r, g, b));
  }
  ring.show();
  delay(100);  // 每秒重绘 10 次
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

项目中的所有课

自己练习: Arduino 在线编辑器