Arduinoで目覚まし時計を作る

できあがったのがこれです

自分で作ってなんですが、まるでお手製の時限爆弾のようです。
配線むき出しなのでいつかすべて内蔵にします。
使った材料はコレ

SODIAL(R)2004 20x4文字のLCDディスプレイモジュールブルーブラックライト

4桁のキャラクタディスプレイ550円 amazon購入

EasyWordMall 1602 LCD ブラック IIC/I2C/TWI/SPI シリアル インタフェース ボード モジュール

あれですな。LCDキャラクタディスプレイをI2C通信にしてしまうやつです。138円amazon購入

半田付け面倒くさいという人はコレ。最初からI2C変換のEasyWordMall 1602半田付けされてます  ただし1850円もするので上2つを半田付け(簡単です。)した方が安上がり。

サインスマート(SainSmart) LCD 20 x 4 モジュール for Arduino 青発光白文字


圧電スピーカー 秋月電子 2個入り100円

リアルタイムクロック Aliexpress 1個54セント 安!

あとはArduinoUNO互換機使いました


他プッシュボタン4個 ピンソケット メス、乾電池9Vとソケット等々
下記が回路図というほどの物でもないんですが。

悩んだのがI2CのEsyWordMallのチップが2種あるらしい。それによってアドレスが変わるので
LiquidCrystal_I2Cの設定が

LiquidCrystal_I2C lcd(0x3F,16,4);
LiquidCrystal_I2C lcd(0x27,16,4);
このどちらかになります。
見せるもはずかしい素人プログラムですが下記です。見事にテキトーなできあたりばったり素人作成プログラム

調べれば出てくると思いますが私が使ったライブラリも自分記憶用にダウンロードできるようにしておきます。
DS1302.h
および
LiquidCrystal_I2C.h



#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "Arduino.h" // WProgram.h
LiquidCrystal_I2C lcd(0x3F,16,4);
//LiquidCrystal_I2C lcd(0x27,16,4);

#include <DS1302.h>

#define PINNO 13 // 圧電スピーカを接続したピン番号
#define BEAT 300 // 音の長さを指定

int times = 0;
int PINNO2=2; //dicision
int PINNO3=3; //adjust
int PINNO5=5; //ALARM SET
int PINNO6=6; //adjust SET
int PINNO13=13; // 圧電スピーカを接続したピン番号

volatile int MNTi = 0,HORi=0,WEEKi=0,MONTi=1,DAYi=1;

int ALFLAG= 0,FLAG=0;
volatile unsigned long time_prev = 0, time_now;
unsigned long time_chat = 100;

// Set pins: CE, IO,CLK
DS1302 rtc(8, 9, 10);
// Init a Time-data structure
Time t;


void setup() {
// put your setup code here, to run once:
// Set the clock to run-mode, and disable the write protection
Serial.begin(57600);
rtc.halt(false);
rtc.writeProtect(false);

lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0,1);
lcd.print("HELLO");

//setTime(hr,min,sec,day,month,yr)
//setTime(01,05,00,24,12,2015);
}

void loop() {
//setSyncProvider(RTC.get); // the function to get the time from the RTC
// put your main code here, to run repeatedly:
char WEEKDAY[7][4] = {"SUN", "MON", "TUE","WED", "THU", "FRI", "SAT"};
//文字列の後には必ずNULLがあるため SUN\n=4文字扱いになる
char bufferTIME[20];
char bufferSET[20];

// Get data from the DS1302
t = rtc.getTime();


lcd.setCursor(0,0);
//lcd.print(t.hour, DEC);
//lcd.print(":");
//lcd.print(t.min, DEC);
//lcd.print(":");
//lcd.print(t.sec, DEC);
sprintf(bufferTIME,"%02d:%02d:%02d %2d/%2d %3s",\
t.hour,t.min,t.sec,t.mon,t.date,WEEKDAY[t.dow]);
lcd.print(bufferTIME);
lcd.print(" ");
//print2digits(month());
//lcd.print("/");
//lcd.print(t.date, DEC);
//lcd.print(t.dow);
//lcd.print("/");
//lcd.print(year());
ALARM_TIME();
lcd.setCursor(19,3);
if (ALFLAG==HIGH){

lcd.print("A");

if (t.hour == HORi && t.min ==MNTi){
tone(PINNO,262,BEAT) ; // ド
delay(BEAT) ;
tone(PINNO,294,BEAT) ; // レ
delay(BEAT) ;
delay(3000) ; // 3秒後に繰り返す
}
}
else{
lcd.print(" ");
}
Serial.print(t.hour);
CHANGE_TIME();

switch(times){
case 1:
CHANGE_HOUR();
break;
case 2:
CHANGE_MINT();
break;
case 3:
CHANGE_WEEK();
break;
case 4:
CHANGE_MONTH();
break;
case 5:
CHANGE_DAY();
break;
}
//セットのカウント
//1:時2:分3:曜日4:月5:日6:年
lcd.setCursor(19,0);
lcd.print(times);

lcd.setCursor(0,1);
sprintf( bufferSET, "%02d:%02d %2d/%2d %03s",\
HORi,MNTi,MONTi,DAYi,WEEKDAY[WEEKi]);
lcd.print(bufferSET);


//時間変更
CHANGE_SET();
if (FLAG ==1){
initTIME(HORi,MNTi,MONTi,DAYi,WEEKi);
}

}

void CHANGE_MINT()
{
//PINNO5 を押すと分変更
if (digitalRead(PINNO5)==HIGH){
time_now = millis();
if (time_now-time_prev>time_chat){
MNTi=MNTi+1;
if (MNTi==60){
lcd.clear();
MNTi=0;
}
}
time_prev= time_now;
}
}
void CHANGE_HOUR()
{
//PINNO5 を押すと時間変更
if (digitalRead(PINNO5)==HIGH){
time_now = millis();
if (time_now-time_prev>time_chat){
HORi=HORi+1;
if (HORi==24){
lcd.clear();
HORi=0;
}
}
time_prev= time_now;
}
}
void CHANGE_WEEK()
{
//PINNO5 を押すと曜日変更
if (digitalRead(PINNO5)==HIGH){
time_now = millis();
if (time_now-time_prev>time_chat){
WEEKi=WEEKi+1;
if (WEEKi==7){
lcd.clear();
WEEKi=0;
}
}
time_prev= time_now;
}
}
void CHANGE_MONTH()
{
//PINNO5 を押すと曜日変更
if (digitalRead(PINNO5)==HIGH){
time_now = millis();
if (time_now-time_prev>time_chat){
MONTi=MONTi+1;
if (MONTi==13){
lcd.clear();
MONTi=1;
}
}
time_prev= time_now;
}
}
void CHANGE_DAY()
{
//PINNO5 を押すと曜日変更
if (digitalRead(PINNO5)==HIGH){
time_now = millis();
if (time_now-time_prev>time_chat){
DAYi=DAYi+1;
if (DAYi==32){
lcd.clear();
DAYi=1;
}
}
time_prev= time_now;
}
}
void CHANGE_SET()
{
if (digitalRead(PINNO2)==HIGH){
time_now=millis();
if (time_now-time_prev>time_chat){
FLAG = !FLAG;
}
time_prev = time_now;
}


}
void CHANGE_TIME()
{
//PINNO6 を押すと変更 時間が設定される
if(digitalRead(PINNO6)==HIGH){
time_now = millis(); //現在の割り込み時刻を取得
if( time_now-time_prev > time_chat){
times=times+1;
}
time_prev = time_now; //現在の割り込み時刻を前回の割り込み時刻へコピー
}
if (times>5){
times =0;
}
}
void ALARM_TIME()
{
//PINNO3 を押すと変更 アラーム時間が設定される
if(digitalRead(PINNO3)==HIGH){
time_now = millis(); //現在の割り込み時刻を取得
if( time_now-time_prev > time_chat){
ALFLAG=!ALFLAG;
}
time_prev = time_now; //現在の割り込み時刻を前回の割り込み時刻へコピー
}

}
void initTIME(int HOUR,int MINT,int MONT,int DAY,int WEEK)
{
//setTime(hr,min,sec,day,month,yr)
rtc.setTime(HOUR,MINT,00);
rtc.setDate(DAY,MONT,2015);
rtc.setDOW(WEEK);
}