Arduinoで作るレトロNumitron管時計:シンプル、信頼性高く、省エネ
部品と材料
| 部品 | 数量 | 備考 |
|---|---|---|
| Arduino Nano R3 | 1 | |
| Maxim DS3231M(±5ppm、I²C RTC) | 1 | |
| TPIC6C595シフトレジスタ(ハイカレントドライバー) | 4 | |
| IV9 Numitron管(4桁表示) | 4 | |
| 汎用LED(秒表示用) | 2 | |
| コンデンサー 100nF(デカップリング) | 4 | |
| 1N4007ダイオード(高耐圧・大電流) | 2 | |
| スライドスイッチ(電源/輝度切替) | 1 | |
| 抵抗 1kΩ(電流制限) | 1 |
必要な工具と機器
- はんだごて(汎用)
- 鉛フリーはんだ
アプリとオンラインサービス
- Arduino IDE
プロジェクト概要
Arduino Nano、DS3231リアルタイムクロックモジュール、TPIC6C595シフトレジスタで駆動するスタイリッシュなNumitron管時計の製作ガイドです。発熱が少なく信頼性の高い表示で、時刻、日付、年、周囲温度を30秒ごとに表示します。
元ネタはこのGitHubリポジトリ。初回製作時にいくつかの問題に直面しました:74HC595シフトレジスタが総電流消費で70mA定格を超えて過熱し、プログラムがブロッキング遅延を使用していたためRTC読み取りが分に1回しか行われませんでした。
ハイカレント対応のTPIC6C595ドライバーへの切り替えと、millis()を用いたノンブロッキングタイミングへのファームウェア改修により、リアルタイム更新、Numitron管の低温動作、さらにはディスプレイを薄暗く点灯する省電力モードを実現しました。
主な特長:
- IV9 Numitron管4本とTPIC6C595ドライバー4個のみで構成
- DS3231が高精度時刻保持と温度センサーを兼ね、外付け温度計不要
- スライドスイッチでLED秒表示のON/OFFと表示輝度調整が可能
- 全パーツが安価で入手容易、DIY愛好家に最適
回路組み立てとコード書き込み後、装飾的なケースに収めれば、あらゆるワークショップやディスプレイケースで会話の種になる逸品です。
コード
- Arduinoコード
Arduinoコード
#include <RTClib.h> // DS3231用温度付きRTC
RTC_DS3231 rtc;
#include <Wire.h> // I2C配線
#include <TimeLib.h> // 時間関数
#include <Time.h> // 時間ライブラリ
#include <DS1307RTC.h> // 追加RTCサポート
#include <SPI.h>
#define led 7
const int latchPin = 13; // TPIC6C595ラッチピン
const int clockPin = 10; // クロックピン
const int dataPin = 11; // データピン
unsigned long previousMillis = 0; // 最後の表示更新
unsigned long previousMillisDiode = 0; // 最後のLEDトグル
const long interval = 30000; // 表示更新間隔(30秒)
const long intervalDiode = 500; // LED点滅間隔
// Numitron管セグメントパターン
const int nums[12] = {
0b10111110, // 0
0b00000110, // 1
0b01111010, // 2
0b01101110, // 3
0b11000110, // 4
0b11101100, // 5
0b11111100, // 6
0b00001110, // 7
0b11111110, // 8
0b11101110, // 9
0b11001010, // °C表示用
0b10111000 // °C小数点用
};
// パース済み時刻・温度保持変数
int hour1, hour2, minute1, minute2, day1, day2, month1, month2, year1, year2, year3, year4, temp1, temp2;
int hourDecimal, minuteDecimal, dayDecimal, monthDecimal, year70, tempDecimal;
void setup() {
pinMode(led, OUTPUT);
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
Serial.begin(9600);
SPI.begin();
digitalWrite(clockPin, LOW); // クロック開始時Low
}
void loop() {
tmElements_t tm; // DS1307RTCライブラリ構造体
RTC.read(tm); // 現在時刻と温度を読み取り
// 桁ごとに分解
hourDecimal = tm.Hour / 10;
hour1 = hourDecimal;
hour2 = tm.Hour - 10 * hourDecimal;
minuteDecimal = tm.Minute / 10;
minute1 = minuteDecimal;
minute2 = tm.Minute - 10 * minuteDecimal;
dayDecimal = tm.Day / 10;
day1 = dayDecimal;
day2 = tm.Day - 10 * dayDecimal;
monthDecimal = tm.Month / 10;
month1 = monthDecimal;
month2 = tm.Month - 10 * monthDecimal;
year70 = tm.Year - 30;
year1 = 2;
year2 = 0;
year3 = year70 / 10;
year4 = year70 - 10 * year3;
tempDecimal = rtc.getTemperature() / 10;
temp1 = tempDecimal;
temp2 = rtc.getTemperature() - 10 * tempDecimal;
// 秒LEDトグル
if (millis() - previousMillisDiode >= intervalDiode) {
previousMillisDiode = millis();
digitalWrite(led, !digitalRead(led));
}
// 30秒ごとに日付/年/温度をローテーション表示
if (millis() - previousMillis >= interval) {
previousMillis = millis();
// クリア(ブリージング効果)
digitalWrite(clockPin, LOW);
SPI.transfer(0b00000000);
SPI.transfer(0b00000000);
SPI.transfer(0b00000000);
SPI.transfer(0b00000000);
digitalWrite(clockPin, HIGH);
delay(500);
// 日付表示(月/日)
digitalWrite(clockPin, LOW);
SPI.transfer(nums[month2]);
SPI.transfer(nums[month1]);
SPI.transfer(nums[day2]);
SPI.transfer(nums[day1]);
digitalWrite(clockPin, HIGH);
delay(1500);
// クリア
digitalWrite(clockPin, LOW);
SPI.transfer(0b00000000);
SPI.transfer(0b00000000);
SPI.transfer(0b00000000);
SPI.transfer(0b00000000);
digitalWrite(clockPin, HIGH);
delay(500);
// 年表示(下2桁)
digitalWrite(clockPin, LOW);
SPI.transfer(nums[year4]);
SPI.transfer(nums[year3]);
SPI.transfer(nums[year2]);
SPI.transfer(nums[year1]);
digitalWrite(clockPin, HIGH);
delay(1500);
// クリア
digitalWrite(clockPin, LOW);
SPI.transfer(0b00000000);
SPI.transfer(0b00000000);
SPI.transfer(0b00000000);
SPI.transfer(0b00000000);
digitalWrite(clockPin, HIGH);
delay(500);
// 温度表示(°C)
digitalWrite(clockPin, LOW);
SPI.transfer(0b10111000); // 小数点
SPI.transfer(0b11001010); // °C記号
SPI.transfer(nums[temp2]);
SPI.transfer(nums[temp1]);
digitalWrite(clockPin, HIGH);
delay(1500);
// 最終クリア
digitalWrite(clockPin, LOW);
SPI.transfer(0b00000000);
SPI.transfer(0b00000000);
SPI.transfer(0b00000000);
SPI.transfer(0b00000000);
digitalWrite(clockPin, HIGH);
delay(500);
} else {
// 通常時刻表示(HH:MM)
digitalWrite(clockPin, LOW);
SPI.transfer(nums[minute2]);
SPI.transfer(nums[minute1]);
SPI.transfer(nums[hour2]);
SPI.transfer(nums[hour1]);
digitalWrite(clockPin, HIGH);
}
}
回路図
製造プロセス
- Arduino NanoとMPU-6050で作るリアルタイムジャイロスコープゲーム
- Arduino で作るイスラム教礼拝時刻付きリアルタイムクロック
- 12メートル先から見える大型LEDマスタークロック(アラーム機能付き)を自作しよう
- Arduino Dueと3.2インチTFTで作る温度監視付きリアルタイムクロック
- ArduinoとNokia 5110ディスプレイで自作電圧計:ステップバイステップガイド
- MobBob:Arduino製ロボットをAndroidスマホでシームレスに制御
- Arduino Nanoとロータリーエンコーダーで作る高精度測定ホイール
- Arduino、Yaler、IFTTTでWeb対応IoTゲージを構築する
- Arduino Nanoで作る8×8 LEDマトリックスのフリップクロック - 自作リアルタイムクロック
- シャープGP2Y1010AU0Fセンサーで作る高精度空気質モニター
- DS1302 RTCとArduino UNOで作る信頼性の高い目覚まし時計