Menu
CoddyTech

Đồng hồ NeoPixel: đặt giờ

Thuộc phần Dự án trong hành trình Arduino của Coddy. Bài học 24 trên 24.

Đồng hồ luôn bắt đầu ở 10:24:50, thời điểm này chỉ đúng một lần mỗi ngày. Hai nút giúp chỉnh giờ: nút đỏ trên chân 2 đẩy đồng hồ tiến thêm một giờ, nút xanh trên chân 3 đẩy thêm 5 phút, tương đương một pixel trên kim phút.

Thời gian là một con số, nên để chỉnh giờ, ta cộng thêm số giây. Lưu số giây mà các nút đã cộng vào một biến, rồi đưa nó vào tổng:

unsigned long adjust = 0;   // số giây tăng thêm khi nhấn các nút

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

Một giờ có 3600 giây và 5 phút có 300 giây. Chỉ tính mỗi lần nhấn một lần, khi nút được nhấn xuống: LOW lúc này và HIGH ở lần trước. Nếu cộng thêm mỗi lần lặp trong lúc nút vẫn được giữ, đồng hồ sẽ quay liên tục. Các nút này không bị nảy.

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

Mỗi kim đều lấy giá trị từ now, nên tất cả đều chuyển động theo. Phần dư giúp giờ quay vòng sau 11 và phút quay vòng sau 55.

challenge icon

Thử thách

Trung bình

Cho phép đặt thời gian:

  • chân 2 và 3 dùng INPUT_PULLUP
  • mỗi lần nhấn chân 2 thì cộng 3600 giây, nhấn chân 3 thì cộng 300 giây, mỗi lần chỉ tính một lần khi nút được nhấn xuống
  • cộng số giây đó vào now

Nhấn Run và đặt đồng hồ theo giờ của bạn, rồi nhấn Check.

Tự làm thử

#include <Adafruit_NeoPixel.h>

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

// Thời điểm đồng hồ bắt đầu, tính bằng giây kể từ nửa đêm: 10:24:50
const unsigned long startTime = 10 * 3600UL + 24 * 60 + 50;

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

void loop() {
  unsigned long now = startTime + millis() / 1000;  // thời gian trong ngày, tính bằng giây
  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;

  // Mỗi pixel nhận màu đỏ từ kim giờ, màu xanh lá từ kim phút
  // và màu xanh dương từ kim giây, nên màu của các kim trùng trên một pixel sẽ hòa vào nhau.
  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);  // vẽ lại mười lần mỗi giây
}
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Dự án

Tự luyện tập: Playground Arduino