DS1302 RTCとArduino UNOで作る信頼性の高い目覚まし時計
部品と材料
| 部品 | 数量 |
|---|---|
| DS1302 RTCモジュール (リアルタイムクロック) | 1 |
| ブザーモジュール (または2ピン圧電ブザー) | 1 |
| Adafruit標準LCD 16×2 (白文字/青背景) ※I2Cタイプ推奨 | 1 |
| Arduino UNO | 1 |
| 4×4マトリックスキーパッドモジュール | 1 |
プロジェクト概要
Arduino UNOで簡単な目覚まし時計を作ります。以前に個別に学習したモジュール (RTC、キーパッド、LCD、ブザー) を組み合わせたプロジェクトです。各モジュールで躓いた場合は、個別のチュートリアルを参照してください。
必要なモジュール
- Arduino UNOボード (互換ボードでも可)
- DS1302 RTCモジュール
- 4×4マトリックスキーパッドモジュール
- LCD I2Cスクリーン
- ブザーモジュール (または2ピン圧電ブザー)
参考チュートリアル
- DS1302 RTC + キーパッド + Arduino + LCD のセットアップ
- DS1302 RTC + Arduino + LCD の基本使用法
- Arduino LCD I2C の基本使用法とシリアルモニタからの直接書き込み
- Arduino UNO + 4×4キーパッドマトリックス + LCD I2C
- Arduinoでブザー/圧電スピーカーを使う方法
配線図

ライブラリとコード
以下のライブラリが必要です (Arduino IDEのライブラリマネージャからインストール可能):
- LCD I2Cライブラリ
- Keypadライブラリ
- RTC DS1302 virtuabotixライブラリ
コードの動作
配線完了後、「*」キーでDS1302 RTCの日時設定モードに入り、現在の日時が表示されます。「A」キーでアラーム時刻 (時/分) を設定、「B」キーでアラーム無効化、アラーム鳴動中は任意のキーで停止できます。
コード
// DS1302 RTC + 4x4 Keypad + LCD I2C + Arduino + Buzzer
// 配線後、LCDにデフォルトまたは設定済みの日時を表示
// キーパッドからRTCを設定し、画面表示、アラーム設定が可能
// 詳細はSurtrtech.comまたはSurtrTech YouTubeチャンネルを参照
#include <Keypad.h>
#include <Wire.h>
#include <virtuabotixRTC.h>
#include <LiquidCrystal_I2C.h>
#define I2C_ADDR 0x27
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
LiquidCrystal_I2C lcd(I2C_ADDR, En_pin, Rw_pin, Rs_pin, D4_pin, D5_pin, D6_pin, D7_pin);
virtuabotixRTC myRTC(2, 3, 4); // RTC配線: CLK, DAT, RST (変更時はここも修正)
const byte numRows = 4;
const byte numCols = 4;
char keymap[numRows][numCols] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[numRows] = {12, 11, 10, 9};
byte colPins[numCols] = {8, 7, 6, 5};
int i1,i2,i3,i4;
char c1,c2,c3,c4;
char keypressed, keypressedx;
int A_hour = NULL;
int A_minute = NULL;
int AlarmIsActive = NULL;
int buzzer = 13;
Keypad myKeypad = Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);
void setup() {
Serial.begin(9600);
lcd.begin(16, 2);
lcd.setBacklightPin(BACKLIGHT_PIN, POSITIVE);
lcd.setBacklight(HIGH);
lcd.home();
}
void loop() {
while (keypressed == NO_KEY) {
keypressed = myKeypad.getKey();
lcd.clear();
myRTC.updateTime();
// アラーム判定 (秒0-2の間に鳴動)
if (myRTC.hours == A_hour && myRTC.minutes == A_minute && AlarmIsActive == 1 && myRTC.seconds >= 0 && myRTC.seconds <= 2) {
while (keypressedx == NO_KEY) {
tone(buzzer, 1000); delay(100);
tone(buzzer, 2000); delay(100);
lcd.clear();
lcd.print("Get up !!!");
keypressedx = myKeypad.getKey();
}
}
keypressedx = NO_KEY;
noTone(buzzer);
// 日時表示
lcd.setCursor(0, 0);
lcd.print(myRTC.dayofmonth); lcd.print("/");
lcd.print(myRTC.month); lcd.print("/");
lcd.print(myRTC.year);
lcd.setCursor(0, 1);
lcd.print(myRTC.hours); lcd.print(":");
lcd.print(myRTC.minutes); lcd.print(":");
lcd.print(myRTC.seconds);
delay(100);
}
// 日時設定モード (*キー)
if (keypressed == '*') {
lcd.clear(); lcd.print(" Setup"); delay(1000);
lcd.clear(); lcd.print("Setup year");
// 年(4桁)入力
char keypressed2 = myKeypad.waitForKey();
if (validKey(keypressed2)) { c1 = keypressed2; lcd.setCursor(0,1); lcd.print(c1); }
char keypressed3 = myKeypad.waitForKey();
if (validKey(keypressed3)) { c2 = keypressed3; lcd.setCursor(1,1); lcd.print(c2); }
char keypressed4 = myKeypad.waitForKey();
if (validKey(keypressed4)) { c3 = keypressed4; lcd.setCursor(2,1); lcd.print(c3); }
char keypressed5 = myKeypad.waitForKey();
if (validKey(keypressed5)) { c4 = keypressed5; lcd.setCursor(3,1); lcd.print(c4); }
i1 = (c1-48)*1000; i2 = (c2-48)*100; i3 = (c3-48)*10; i4 = c4-48;
int N_year = i1+i2+i3+i4; delay(500);
// 月(2桁)入力
lcd.clear(); lcd.print("Setup month");
char keypressed6 = myKeypad.waitForKey();
if (validKey(keypressed6)) { c1 = keypressed6; lcd.setCursor(0,1); lcd.print(c1); }
char keypressed7 = myKeypad.waitForKey();
if (validKey(keypressed7)) { c2 = keypressed7; lcd.setCursor(1,1); lcd.print(c2); }
i1 = (c1-48)*10; i2 = c2-48; int N_month = i1+i2; delay(500);
// 日(2桁)入力
lcd.clear(); lcd.print("Setup Day");
char keypressed8 = myKeypad.waitForKey();
if (validKey(keypressed8)) { c1 = keypressed8; lcd.setCursor(0,1); lcd.print(c1); }
char keypressed9 = myKeypad.waitForKey();
if (validKey(keypressed9)) { c2 = keypressed9; lcd.setCursor(1,1); lcd.print(c2); }
i1 = (c1-48)*10; i2 = c2-48; int N_day = i1+i2; delay(500);
// 時(2桁)入力
lcd.clear(); lcd.print("Setup hour");
char keypressed10 = myKeypad.waitForKey();
if (validKey(keypressed10)) { c1 = keypressed10; lcd.setCursor(0,1); lcd.print(c1); }
char keypressed11 = myKeypad.waitForKey();
if (validKey(keypressed11)) { c2 = keypressed11; lcd.setCursor(1,1); lcd.print(c2); }
i1 = (c1-48)*10; i2 = c2-48; int N_hour = i1+i2; delay(500);
// 分(2桁)入力
lcd.clear(); lcd.print("Setup minutes");
char keypressed12 = myKeypad.waitForKey();
if (validKey(keypressed12)) { c1 = keypressed12; lcd.setCursor(0,1); lcd.print(c1); }
char keypressed13 = myKeypad.waitForKey();
if (validKey(keypressed13)) { c2 = keypressed13; lcd.setCursor(1,1); lcd.print(c2); }
i1 = (c1-48)*10; i2 = c2-48; int N_minutes = i1+i2; delay(500);
// RTCに書き込み (秒=22, 曜日=1 固定)
lcd.clear();
myRTC.setDS1302Time(22, N_minutes, N_hour, 1, N_day, N_month, N_year);
keypressed = NO_KEY;
}
// アラーム設定 (Aキー)
if (keypressed == 'A') {
lcd.clear(); lcd.print(" Alarm setup "); delay(1000);
lcd.clear(); lcd.print("Set alarm hour");
char keypressed14 = myKeypad.waitForKey();
if (validKey(keypressed14)) { c1 = keypressed14; lcd.setCursor(0,1); lcd.print(c1); }
char keypressed15 = myKeypad.waitForKey();
if (validKey(keypressed15)) { c2 = keypressed15; lcd.setCursor(1,1); lcd.print(c2); }
i1 = (c1-48)*10; i2 = c2-48; A_hour = i1+i2; delay(500);
lcd.clear(); lcd.print("Set alarm minutes");
char keypressed16 = myKeypad.waitForKey();
if (validKey(keypressed16)) { c1 = keypressed16; lcd.setCursor(0,1); lcd.print(c1); }
char keypressed17 = myKeypad.waitForKey();
if (validKey(keypressed17)) { c2 = keypressed17; lcd.setCursor(1,1); lcd.print(c2); }
i1 = (c1-48)*10; i2 = c2-48; A_minute = i1+i2; delay(500);
lcd.clear(); AlarmIsActive = 1; keypressed = NO_KEY;
}
// アラーム無効化 (Bキー)
if (keypressed == 'B') {
lcd.clear(); lcd.print("Alarm deactivated");
AlarmIsActive = 0; keypressed = NO_KEY; delay(500);
} else {
myRTC.updateTime();
keypressed = NO_KEY;
}
}
// 有効な数字キーか判定
bool validKey(char k) {
return (k != NO_KEY && k != '*' && k != '#' && k != 'A' && k != 'B' && k != 'C' && k != 'D');
}
回路図

製造プロセス
- Arduino Nano 33 IoT製 フライトシミュレーター2020用コックピットパネル - LCD&CDI表示
- Arduino POVクロック:残像効果で浮かび上がるLED時計を自作する
- Arduinoで作るレトロNumitron管時計:シンプル、信頼性高く、省エネ
- DIY Arduinoワードクロック – 文字で時刻を表示する洗練されたリアルタイムクロック
- Arduino で作るイスラム教礼拝時刻付きリアルタイムクロック
- 12メートル先から見える大型LEDマスタークロック(アラーム機能付き)を自作しよう
- Arduino Dueと3.2インチTFTで作る温度監視付きリアルタイムクロック
- Arduinoでシンプルな障害物センサーを自作 – IR LEDとフォトダイオード入門
- TM1637デジタル時計:時刻設定・アラーム機能付き Arduino Nano試作版
- Arduino UNOで1.17インチTFT LCDに画像を表示する方法
- Arduino Nanoとロータリーエンコーダーで作る高精度測定ホイール