Arduino Nano RTC時計:DS1307で精密な時刻管理と7セグメント表示
必要な部品と材料
| 部品 | 数量 | 備考 |
|---|---|---|
| Arduino Nano R3 | 1 | メイン制御ボード |
| RTCモジュール(DS1307ベース) | 1 | 電池バックアップで停電時も時刻保持。自作も可能 |
| 4桁7セグメントLED表示器(共通アノード) | 1 | 時刻表示用 |
| メスヘッダー(シングルロウ) | 3 | モジュール接続用 |
| 穴あき基板(ユニバーサル基板) | 1 | 半田付けして綺麗に仕上げる場合。ブレッドボード型配線のものが作業しやすい |
| ジャンパーワイヤー | 25本 | 配線用 |
| オスヘッダー 40ピン | 1 | 基板取り付け用 |
必要な工具
| 工具 | 備考 |
|---|---|
| 半田ごて | 基板への半田付け用 |
| マルチメーター | 全プロジェクト必須。標準的なものを購入すれば4年以上使用可能。半田付けの導通確認や電流測定に必要 |
使用するアプリとオンラインサービス
- Arduino IDE
- Arduino Fritzing(回路図作成用)
プロジェクト概要
RTC DS1307 ICを使用した、組み立て簡単なデジタル時計です。4桁7セグメントディスプレイに時刻を表示します。コードを少し修正すればアラーム機能なども容易に追加可能。より高度なプロジェクトへの足がかりとして、また部屋に飾るかっこいい時計が欲しくて製作しました。
半田付け時のトラブルとその解決法を含め、あらゆる詳細を解説します。
ステップ1: コンポーネント詳細
RTCモジュール(DS1307)
DS1307チップは電源オフ時も時刻を保持できる優れもの。Arduinoとのインターフェースも簡単で、豊富なライブラリが利用可能です。I2Cプロトコルで通信し、Arduino Nanoでは以下のピンを使用します:
- SDA - A4
- SCL - A5
※DSピンは本プロジェクトでは不使用
注意点: 精度はそこまで高くなく、温度変化によりタイムドリフト(時刻ズレ)が生じやすいです。
重要: GNDとVCCの極性を間違えないでください。モジュール上ではVCCピンがGNDピンより手前にあります。逆極性で接続すると瞬時に発熱します。コイン電池に触れながら通電し、熱を感じたら即座に電源を切ってください。
シフトレジスタ(74HC595)
- 「多重化(マルチプレクシング)」技術を可能にするキーコンポーネント。初心者の方も恐れず挑戦してください。習得すれば必ず役立ちます。
- 16ピンICで、2個使用して4桁7セグ表示器を制御します。
- 1個目:セグメント(a-g, dp)の点灯制御
- 2個目:どの桁(D1-D4)を点灯させるかの選択
- 多重化により桁の切り替えが高速で行われ、あたかも全桁同時点灯のように見えます。
経験談: これらのチップは比較的信頼性が高いですが、いくつか不良品に当たりました。Q0/Q1が動作しない、Q3が内部でGNDにショートしている、Q7が不良など。マルチメーターの導通モードでピンチェックすることをお勧めします。すべて学びの過程です。
4桁7セグメントディスプレイ
汎用の共通アノードタイプを使用。12ピンで、左下から反時計回りに番号が振られています。各セグメントは数字と小数点を表示可能。デジタル時計典型のコロン(:)がないため、2桁目の小数点をコロン代わりに使用しています。数字表示が主目的なら最適な表示器です。
注意: セグメントa-gの配列が一直線でないため初心者には少し厄介です。電流制限抵抗なしで5Vに直結しないでください。
回路図も掲載していますが、使用した表示器とピン配置が異なるため、シフトレジスタからセグメントへの接続表を以下に示します:
| セグメント | 表示器ピン番号 | シフトレジスタピン |
|---|---|---|
| A | 11 | 15(1個目) |
| B | 7 | 1(1個目) |
| C | 4 | 2(1個目) |
| D | 2 | 3(1個目) |
| E | 1 | 4(1個目) |
| F | 10 | 5(1個目) |
| G | 5 | 6(1個目) |
| 小数点 | 3 | 7(1個目) |
| D1(桁1) | 12 | 15(2個目) |
| D2(桁2) | 9 | 1(2個目) |
| D3(桁3) | 8 | 2(2個目) |
| D4(桁4) | 6 | 3(2個目) |
このプロジェクトは低コストで簡単ですが、基板への半田付けまでやるなら少しの忍耐と根気が必要です(ブレッドボード上での動作確認だけなら2時間程度)。
改善点や不明点があればフィードバックをお願いします。
プログラムコード
メインクロックコード(Arduino)
RTCライブラリとI2Cライブラリ(Wire.h)が必要です。共通アノード型表示器用のプログラムです。
#include <Wire.h>
#include <EEPROM.h>
#include <RTClib.h>
RTC_DS1307 RTC;
int temp, inc, hours1, minut, add = 11;
int HOUR, MINUT, SECOND;
int latchPin = 3; // 595のピン12
int dataPin = 4; // 595のピン14
int clockPin = 2; // 595のピン11
int shift = 256;
int units, tens, hundreds, thousands;
int x, y;
const int alarmHour = 17;
const int alarmMinute = 26;
void setup() {
Serial.begin(9600);
pinMode(latchPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(13, OUTPUT); // アラーム用LED
Wire.begin();
RTC.begin();
if (!RTC.isrunning()) {
RTC.adjust(DateTime(__DATE__, __TIME__)); // コンパイル時刻で初期化
}
}
void loop() {
DateTime now = RTC.now();
HOUR = now.hour();
MINUT = now.minute();
// 時刻を各桁に分解
if (HOUR < 10) {
hundreds = HOUR; thousands = HOUR / 10;
} else {
hundreds = HOUR % 10; thousands = HOUR / 10;
}
if (MINUT <= 9) {
units = MINUT; tens = MINUT / 10;
} else {
units = MINUT % 10; tens = MINUT / 10;
}
// 各桁を多重化表示(コード簡略化のため関数化推奨)
displayDigit(units, shift * 8, 192); // 1の位(分)
delay(1);
displayDigit(tens, shift * 4, 192); // 10の位(分)
delay(1);
displayDigit(hundreds, shift * 2, 64); // 1の位(時)
delay(1);
displayDigit(thousands, shift, 192); // 10の位(時)
delay(1);
// アラーム機能
if (HOUR == alarmHour && MINUT == alarmMinute) {
digitalWrite(13, HIGH);
} else {
digitalWrite(13, LOW);
}
}
// セグメントパターン送信ヘルパー関数(元コードのswitch文を関数化)
void displayDigit(int digit, int shiftMul, int digitSelect) {
static const uint16_t patterns[10] = {
192, 249, 164, 176, 153, 146, 130, 248, 128, 144
};
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, (shiftMul >> 8));
shiftOut(dataPin, clockPin, MSBFIRST, shiftMul + patterns[digit]);
digitalWrite(latchPin, HIGH);
}
時刻設定用スケッチ(Arduino)
DS1307はドリフトしやすいため、シリアルモニターから時刻を設定するスケッチを用意しました。時刻がズレたらRTCモジュールをArduinoに接続し、このスケッチをアップロードしてシリアルモニターから日付・時刻を入力。その後メインのクロックコードを書き込めば正しい時刻が表示されます。
/* RealTimeClockDS1307ライブラリ使用例 */
#include <Wire.h>
#include <RealTimeClockDS1307.h>
#define DISPLAY_CLOCK_EVERY_N_SECONDS 1
#define DISPLAY_HELP_EVERY_N_SECONDS 25
RealTimeClockDS1307 RTC;
int count = 0;
char formatted[] = "00-00-00 00:00:00x";
void setup() {
Serial.begin(9600);
}
void loop() {
if (Serial.available()) processCommand();
delay(1000);
RTC.readClock();
count++;
if (count % DISPLAY_CLOCK_EVERY_N_SECONDS == 0) {
Serial.print(count); Serial.print(": ");
RTC.getFormatted(formatted);
Serial.println(formatted);
}
if (count % DISPLAY_HELP_EVERY_N_SECONDS == 0) {
Serial.println("Send ? for command list.");
}
}
// コマンド処理(h=時刻設定, i=分設定, s=秒設定, y=年, m=月, d=日, w=曜日, t=12/24h切替, a/p=AM/PM等)
void processCommand() { /* 実装は本文参照 */ }
ライブラリファイル
以下のライブラリファイルをArduinoのlibrariesフォルダにインストールしてください:
RealTimeClockDS1307ライブラリ(クリックで展開)
RealTimeClockDS1307.h- ヘッダーファイルRealTimeClockDS1307.cpp- 実装ファイルkeywords.txt- シンタックスハイライト用README- 説明書
フォルダ名「RealTimeClockDS1307」を作成し、これらを配置。Arduino IDEの「スケッチ」→「ライブラリをインクルード」→「.ZIP形式のライブラリをインストール」で追加可能。
RTClibライブラリ(Adafruit/JeeLabsフォーク)(クリックで展開)
RTClib.h/RTClib.cpp- メインライブラリ(DS1307, DS3231, PCF8523等対応)README.md- 互換性表付き詳細ドキュメントlibrary.properties- ライブラリマネージャー用
フォルダ名「RTClib」で同様にインストール。より多機能でメンテナンスされているライブラリです。
回路図
プロジェクトの回路図(Fritzingファイル)
7segmentClock.fzz
製造プロセス
- アイロン台の製造:設計、素材、生産プロセス
- 鳩時計:歴史、職人技、現代への進化
- プリント基板:設計、製造、未来トレンド
- サーフボードの構造とデザイン:ポリネシアのルーツから現代の革新まで
- Raspberry Pi と Arduino を連携させてロボットを自作:ステップバイステップガイド
- RasPiRobot Board V2:Raspberry Pi を強力なロボットコントローラーに拡張
- Arduino POVクロック:残像効果で浮かび上がるLED時計を自作する
- DIY Arduinoワードクロック – 文字で時刻を表示する洗練されたリアルタイムクロック
- インフィニティミラー時計:終わりなき美しさと正確な時刻の融合
- エンジン配置・構成の総合ガイド:タイプと特徴
- 完璧なプリント基板の重要性