Menu
CoddyTech

Часы на NeoPixel: устанавливаем время

Часть раздела Проекты путешествия по Arduino на Coddy. Урок 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

Нажмите Run и установите на часах нужное вам время, затем нажмите Check.

Попробуйте сами

#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);  // перерисовывать десять раз в секунду
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Проекты

Потренируйтесь самостоятельно: Песочница Arduino