CUSTOMELECTRONICS.RU
Информационно-учебный блог о разработке электроники
Эл. почта: info@customelectronics.ru

BCD. Двоично-десятичные часы на Arduino с RTC

Представляем вашему вниманию очень простую конструкцию, которая выполняет достаточно интересную функцию. А именно, отображает информацию о времени в двоичном коде.

Назначение

Двоично-десятичный код предполагает поразрядную запись двоичных чисел в двоичном виде. Например, число 25 в двоичном виде имеет вид 0b11001, но в двоично-десятичном виде это число записывается как два двоичных числа 0b10 0b101. Такой вид удобен в логических схемах и часто умение считать в двоичном виде помогает программировать контроллеры. Поэтому мы решили сделать свою оригинальную конструкцию часов, которые отображают текущее время в двоичном коде.
Выглядит это следующим образом:

BCD gif-animation

BCD в работе

То есть в анимации на часах отображается время 17 часов, 27 минут.

Материалы и комплектующие

  1. Плата Arduino Nano
  2. Часы реального времени DS3231
  3. Адресуемые RGB-светодиоды WS2812B

Обратите внимание, что очень важно, чтобы светодиоды именно меняли цвет в процессе счета, а не загорались и гасли. Иначе информация считывается очень затруднительно. Также адресуемые светодиоды очень удобны при подключении — все их можно подключить "друг за другом".
Также повысить читаемость нам позволил корпус из оргстекла с прорезанными отверстиями для светодиодов нам позволил корпус из оргстекла с прорезанными отверстиями под светодиоды и светорассеивающая пленка, наклеенная на корпус.

Схема

Подключается все очень просто. Часы реального времени должны подключены по протоколу I2C, то есть к выводам A4 и A5. Вся гирлянда светодиодов подключена к шестому выводу Arduino. Особенность адресуемых светодиодов в том, что их необходимо подключать друг за другом и подвести к ним питание. Дальше в программе достаточно будет просто по специальному протоколу сообщить какому светодиоду и как необходимо светить. Более подробную информацию можно найти в даташите.

Схема двоично-десятичных часов

Схема двоично-десятичных часов

На схеме мы расположили светодиоды так, как они должны быть расположены физически, для взгляда человека. Крайний левый разряд — десятки часов, затем идут единицы часов, десятки минут, единицы минут, десятки секунд и, в самом правом столбце, единицы секунд. В нижней строке находится младший разряд, то есть "1", вто второй строке "2", далее "4" и самый старший разряд — "8". Таким образом достаточно легко сложить весовые коэффициенты разрядов и перевести значение в десятичную систему исчисления. Видео с таким отображением времени есть в начале статьи.

Сборка устройства

Есть много вариантов сборки
Можно купить готовые модули и просто соединить все проводами.
Мы сделали платы с линейками светодиодов и корпус из оргстекла. Светодиоды вставляются в отверстия в лицевой панели. Сами платы со светодиодами держатся на двухстороннем скотче. Для создания относительно ровно засвеченных кругов, на лицевую панель наклеена светоотражающая пленка.

Часы с лицевой стороны

Часы с лицевой стороны

Часы с обратной стороны

Часы с обратной стороны

Программа

Для написания программы использованы библиотеки Adafruit_NeoPixel и iarduino_RTC.
Мы никак не реализовали в устройстве настройку текущего времени. Чтобы установить время необходимо указать текущее время в заголовке файла (HOUR, MIN, SEC) и раскомментировать строку time.settime(SEC,MIN,HOUR); , установить текущее время и перепрошить. А затем снова закомментировать и прошить. После этих манипуляций в часах сохранится актуальное время и оно не будет сбрасываться при перезапуске устройства.

/*  H   H   M   M   S   S
8       5       12      19
4       4   6   11  13  18
2   0   3   7   10  14  17
1   1   2   8   9   15  16*/

#include <Adafruit_NeoPixel.h>
#include <iarduino_RTC.h>

#define LED_COUNT 30
#define LED_PIN 6
#define BLUE 50
#define RED 250
#define HOUR 3
#define MIN 32
#define SEC 0

iarduino_RTC time(RTC_DS3231,A5,A4);
Adafruit_NeoPixel strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

uint8_t seconds = 0;

void Show_Seconds(uint8_t data) {
  for(int i=0; i<4; i++){
    if( (data%10)&(1<<i)) strip.setPixelColor(16+i, strip.Color(RED, 0, 0));
    else strip.setPixelColor(16+i, strip.Color(0, 0, BLUE));
    strip.show();
  }
  for(int i=0; i<3; i++){
    if( (data/10)&(1<<i)) strip.setPixelColor(15-i, strip.Color(RED, 0, 0));
    else strip.setPixelColor(15-i, strip.Color(0, 0, BLUE));
    strip.show();
  }
}

void Show_Minutes(uint8_t data) {
  for(int i=0; i<4; i++){
    if( (data%10)&(1<<i)) strip.setPixelColor(9+i, strip.Color(RED, 0, 0));
    else strip.setPixelColor(9+i, strip.Color(0, 0, BLUE));
    strip.show();
  }
  for(int i=0; i<3; i++){
    if( (data/10)&(1<<i)) strip.setPixelColor(8-i, strip.Color(RED, 0, 0));
    else strip.setPixelColor(8-i, strip.Color(0, 0, BLUE));
    strip.show();
  }
}

void Show_Hours(uint8_t data) {
  for(int i=0; i<4; i++){
    if( (data%10)&(1<<i)) strip.setPixelColor(2+i, strip.Color(RED, 0, 0));
    else strip.setPixelColor(2+i, strip.Color(0, 0, BLUE));
    strip.show();
  }
  for(int i=0; i<3; i++){
    if( (data/10)&(1<<i)) strip.setPixelColor(1-i, strip.Color(RED, 0, 0));
    else strip.setPixelColor(1-i, strip.Color(0, 0, BLUE));
    strip.show();
  }
}

void setup() {
  strip.begin();
  time.begin();
  //time.settime(SEC,MIN,HOUR); 
}
 
void loop(){
  time.gettime("H:i:s" );
  if (seconds != time.seconds) {
    seconds = time.seconds;
    Show_Seconds(time.seconds);
    Show_Minutes(time.minutes);
    Show_Hours(time.hours);
  }
}

Вот как-то так.
Мы будем очень рады, если вы поддержите наш ресурс и посетите магазин наших товаров shop.customelectronics.ru.

Метки: , , , , , Просмотров: 6029