옵토-아이솔레이션 칩으로 아두이노(5V)가 닉시관(150V)을 제어합니다. 매트릭스 연결 방식을 사용해 아두이노 16개 출력으로 6개 닉시관의 60개 세그먼트를 제어합니다. DS3231 RTC 모듈은 I2C로 아두이노와 통신하며 전원 차단 시에도 시간을 유지합니다. 아두이노가 실시간을 읽고 높은 주파수로 닉시관 세그먼트를 순차 점등해 사람의 눈에는 6자리 숫자가 계속 보이는 것처럼 보이게 합니다(다이나믹 점등/멀티플렉싱).
2단계: 아두이노 코드
// Youtube channel: engineer2you
#include <Wire.h>
#include "DS3231.h"
RTClib RTC;
DS3231 Clock;
int hour, minute, second;
const int nixie_0 = 2; const int nixie_1 = 3; const int nixie_2 = 4;
const int nixie_3 = 5; const int nixie_4 = 6; const int nixie_5 = 7;
const int nixie_6 = 8; const int nixie_7 = 9; const int nixie_8 = 10;
const int nixie_9 = 11;
const int row_1 = 0; const int row_2 = 1; const int row_3 = 14;
const int row_4 = 15; const int row_5 = 16; const int row_6 = 17;
const int time_on = 2;
void setup() {
pinMode(nixie_0, OUTPUT); pinMode(nixie_1, OUTPUT); pinMode(nixie_2, OUTPUT);
pinMode(nixie_3, OUTPUT); pinMode(nixie_4, OUTPUT); pinMode(nixie_5, OUTPUT);
pinMode(nixie_6, OUTPUT); pinMode(nixie_7, OUTPUT); pinMode(nixie_8, OUTPUT);
pinMode(nixie_9, OUTPUT);
pinMode(row_1, OUTPUT); pinMode(row_2, OUTPUT); pinMode(row_3, OUTPUT);
pinMode(row_4, OUTPUT); pinMode(row_5, OUTPUT); pinMode(row_6, OUTPUT);
// Serial.begin(9600); // 시리얼 사용 시 D0, D1 핀에 영향 있음
Wire.begin();
}
void loop() {
// 시간 읽기
DateTime now = RTC.now();
hour = now.hour(); minute = now.minute(); second = now.second();
// 초 표시 (두 자리)
int j = second / 10; int k = second % 10;
off_all(); on_number(0, k+2); delay(time_on);
off_all(); on_number(1, j+2); delay(time_on);
// 분 표시
j = minute / 10; k = minute % 10;
off_all(); on_number(14, k+2); delay(time_on);
off_all(); on_number(15, j+2); delay(time_on);
// 시 표시
j = hour / 10; k = hour % 10;
off_all(); on_number(16, k+2); delay(time_on);
off_all(); on_number(17, j+2); delay(time_on);
}
void on_number(int row, int nixie) {
digitalWrite(row, HIGH);
digitalWrite(nixie, HIGH);
}
void off_all() {
digitalWrite(row_1, LOW); digitalWrite(row_2, LOW); digitalWrite(row_3, LOW);
digitalWrite(row_4, LOW); digitalWrite(row_5, LOW); digitalWrite(row_6, LOW);
digitalWrite(nixie_0, LOW); digitalWrite(nixie_1, LOW); digitalWrite(nixie_2, LOW);
digitalWrite(nixie_3, LOW); digitalWrite(nixie_4, LOW); digitalWrite(nixie_5, LOW);
digitalWrite(nixie_6, LOW); digitalWrite(nixie_7, LOW); digitalWrite(nixie_8, LOW);
digitalWrite(nixie_9, LOW);
delayMicroseconds(400); // 고스트 현상 방지
}
기본적으로 DS3231에서 시간을 읽어 옵토커플러를 통해 6개 닉시관에 표시합니다.
3단계: 회로 조립
브레드보드로 실험 삼아 만들었는데 첫 시도부터 문제없이 작동했습니다. 다음 단계로는 MDF 케이스에 예쁘게 장착해 방에 둘 예정입니다.
코드
전체 코드 (C/C++)
//Youtube channel: engineer2you
#include <Wire.h>
#include "DS3231.h"
RTClib RTC;
DS3231 Clock;
int hour, minute, second;
const int nixie_0 = 2; const int nixie_1 = 3; const int nixie_2 = 4;
const int nixie_3 = 5; const int nixie_4 = 6; const int nixie_5 = 7;
const int nixie_6 = 8; const int nixie_7 = 9; const int nixie_8 = 10;
const int nixie_9 = 11;
const int row_1 = 0; const int row_2 = 1; const int row_3 = 14;
const int row_4 = 15; const int row_5 = 16; const int row_6 = 17;
const int time_on = 2;
void setup() {
pinMode(nixie_0, OUTPUT); pinMode(nixie_1, OUTPUT); pinMode(nixie_2, OUTPUT);
pinMode(nixie_3, OUTPUT); pinMode(nixie_4, OUTPUT); pinMode(nixie_5, OUTPUT);
pinMode(nixie_6, OUTPUT); pinMode(nixie_7, OUTPUT); pinMode(nixie_8, OUTPUT);
pinMode(nixie_9, OUTPUT);
pinMode(row_1, OUTPUT); pinMode(row_2, OUTPUT); pinMode(row_3, OUTPUT);
pinMode(row_4, OUTPUT); pinMode(row_5, OUTPUT); pinMode(row_6, OUTPUT);
Wire.begin();
}
void loop() {
DateTime now = RTC.now();
hour = now.hour(); minute = now.minute(); second = now.second();
int j = second / 10; int k = second % 10;
off_all(); on_number(0, k+2); delay(time_on);
off_all(); on_number(1, j+2); delay(time_on);
j = minute / 10; k = minute % 10;
off_all(); on_number(14, k+2); delay(time_on);
off_all(); on_number(15, j+2); delay(time_on);
j = hour / 10; k = hour % 10;
off_all(); on_number(16, k+2); delay(time_on);
off_all(); on_number(17, j+2); delay(time_on);
}
void on_number(int row, int nixie) {
digitalWrite(row, HIGH);
digitalWrite(nixie, HIGH);
}
void off_all() {
digitalWrite(row_1, LOW); digitalWrite(row_2, LOW); digitalWrite(row_3, LOW);
digitalWrite(row_4, LOW); digitalWrite(row_5, LOW); digitalWrite(row_6, LOW);
digitalWrite(nixie_0, LOW); digitalWrite(nixie_1, LOW); digitalWrite(nixie_2, LOW);
digitalWrite(nixie_3, LOW); digitalWrite(nixie_4, LOW); digitalWrite(nixie_5, LOW);
digitalWrite(nixie_6, LOW); digitalWrite(nixie_7, LOW); digitalWrite(nixie_8, LOW);
digitalWrite(nixie_9, LOW);
delayMicroseconds(400);
}