Devremizde Arduino Uno modülü, DS1302 zaman modülü, I2C&1602A LCD, 4 adet buton ve buzzer kullanıyoruz. Programın üzerinde ufak tefek türkçeleştirmeler yaptım. Ayrıca I2C modüllü LCD'ye göre ayarlamalar yaptım.
ARDUINO IDE KODLARI:
/*******************************************************************************
Arduino Clock with alarm function and DS1302 RTC module
Version 1.0
Copyright (C) 2018 One Transistor <https://www.onetransistor.eu>
More information at:
https://www.onetransistor.eu/2018/12/alarm-clock-with-ds1302-rtc.html
Developed on Arduino Uno compatible board (ATmega328p) with LCD, DS1302
module, active buzzer and 4 push buttons.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/
#define RTC_CLK 4 // clock
#define RTC_DAT 3 // data
#define RTC_RST 2 // enable
#define BTN_AL A0
#define BTN_DN A1
#define BTN_UP A2
#define BTN_SET A3
#define AL_BUZZ 11
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7);
unsigned long timeUpdate = 0;
unsigned long timeButton = 0;
unsigned long timeAlarm = 0;
bool buttonPress = false;
byte alarmOn = 0;
bool alarmSw = 1;
byte setMode = 0;
byte setAlarm = 0;
byte daysOfMonth[13] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const char* months[13] = {"---", "Oca", "Sub", "Mar", "Nis", "May", "Haz", "Tem", "Agu", "Eyl", "Eki", "Kas", "Ara"};
const char* wdays[8] = {"---", "Pts", "Sal", "Car", "Per", "Cum", "Cts", "Paz"};
byte hh, mm, ss; // hour, minute, second (saat, dakika, saniye)
byte dd, MM, yy; // day, month, year (gün, ay, yıl)
byte dw; // day of the week (haftanın kaçıncı günü)
byte ae, ah, am; // alarm: enabled, hour, minute (alarm: etkin, saat, dakika)
static byte bcd2bin (byte val) {
return val - 6 * (val >> 4);
}
static byte bin2bcd (byte val) {
return val + 6 * (val / 10);
}
// DS1302 communication from https://github.com/NeiroNx/RTCLib
void rtc_write(byte val) {
pinMode(RTC_DAT, OUTPUT);
shiftOut(RTC_DAT, RTC_CLK, LSBFIRST, val);
}
void rtc_write_reg(byte addr, byte val) {
digitalWrite(RTC_RST, HIGH);
rtc_write(addr);
rtc_write(val);
digitalWrite(RTC_RST, LOW);
}
byte rtc_read() {
pinMode(RTC_DAT, INPUT);
byte value = 0;
for (byte i = 0; i < 8; i++) {
value |= (digitalRead(RTC_DAT) << i);
digitalWrite(RTC_CLK, HIGH);
digitalWrite(RTC_CLK, LOW);
}
return value;
}
byte rtc_read_reg(byte addr) {
digitalWrite(RTC_RST, HIGH);
rtc_write(addr);
byte val = rtc_read();
digitalWrite(RTC_RST, LOW);
return val;
}
void rtc_read_time() {
digitalWrite(RTC_RST, HIGH);
rtc_write(0xBF); // veri bloğu okuma modu
byte ss_reg = rtc_read();
if (bitRead(ss_reg, 7)) {// saat durdu
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("RTC not running");
lcd.setCursor(0, 1);
lcd.print("Saati ayarla");
return; // TO DO
}
ss = bcd2bin(ss_reg & 0x7F);
mm = bcd2bin(rtc_read());
hh = bcd2bin(rtc_read());
dd = bcd2bin(rtc_read());
MM = bcd2bin(rtc_read());
dw = bcd2bin(rtc_read());
yy = bcd2bin(rtc_read());
digitalWrite(RTC_RST, LOW);
}
void initTimeDisplay() {
lcd.clear();
lcd.setCursor(6, 0); lcd.print(':');
lcd.setCursor(9, 0); lcd.print(':');
lcd.setCursor(2, 1); lcd.print('-');
lcd.setCursor(6, 1); lcd.print('-');
lcd.setCursor(11, 1); lcd.print(',');
}
void updateDisplay() {
rtc_read_time();
lcd.setCursor(7, 0);
if (mm < 10) lcd.print('0');
lcd.print(mm, DEC);
lcd.setCursor(4, 0);
if (hh < 10) lcd.print('0');
lcd.print(hh, DEC);
lcd.setCursor(0, 1);
if (dd < 9) lcd.print('0');
lcd.print(dd, DEC);
lcd.setCursor(13, 1);
lcd.print(wdays[dw]);
lcd.setCursor(3, 1);
lcd.print(months[MM]);
lcd.setCursor(7, 1);
lcd.print(yy + 2000, DEC);
lcd.setCursor(15, 0);
ae ? lcd.print('*') : lcd.print(' ');
}
void setVariable() { //zaman ayarları----------------------------------
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Ayar");
lcd.setCursor(0, 1);
lcd.print("< >");
rtc_write_reg(0x8E, 0x00);
switch (setMode) {
case 1: // year
lcd.setCursor(7, 0);
lcd.print("Yil");
lcd.setCursor(6, 1);
lcd.print(yy + 2000, DEC);
break;
case 2: // month
rtc_write_reg(0x8C, bin2bcd(yy));
lcd.setCursor(7, 0);
lcd.print("Ay");
lcd.setCursor(6, 1);
lcd.print(months[MM]);
break;
case 3: // day
rtc_write_reg(0x88, bin2bcd(MM));
lcd.setCursor(7, 0);
lcd.print("Gun");
lcd.setCursor(6, 1);
if (dd < 10) lcd.print('0');
lcd.print(dd, DEC);
break;
case 4: // day of week
rtc_write_reg(0x86, bin2bcd(dd));
lcd.setCursor(7, 0);
lcd.print("Haf.Gunu");
lcd.setCursor(6, 1);
lcd.print(wdays[dw]);
break;
case 5: // hour
rtc_write_reg(0x8A, bin2bcd(dw));
lcd.setCursor(7, 0);
lcd.print("Saat");
lcd.setCursor(6, 1);
if (hh < 10) lcd.print('0');
lcd.print(hh, DEC);
break;
case 6: // minutes
rtc_write_reg(0x84, bin2bcd(hh));
lcd.setCursor(7, 0);
lcd.print("Dakika");
lcd.setCursor(6, 1);
if (mm < 10) lcd.print('0');
lcd.print(mm, DEC);
break;
case 7:
rtc_write_reg(0x82, bin2bcd(mm));
rtc_write_reg(0x80, 0x00); // saatin durmadığından ve saniyeleri sıfırladığından emin ol
default:
setMode = 0;
rtc_write_reg(0x8E, 0x80); // yazma koruması
initTimeDisplay();
updateDisplay();
}
}
void adjustVariable(char a = 1) {
lcd.setCursor(6, 1);
lcd.print(" ");
lcd.setCursor(6, 1);
char t;
switch (setMode) {
case 1: // year
t = yy; t += a;
if ((t >= 0) && (t < 100)) yy = t;
lcd.print(yy + 2000, DEC);
break;
case 2: // month
t = MM; t += a;
if ((t > 0) && (t <= 12)) MM = t;
lcd.print(months[MM]);
break;
case 3: // day
t = dd; t += a;
if ((t > 0) && (t <= daysOfMonth[MM])) dd = t;
if (dd < 10) lcd.print('0');
lcd.print(dd, DEC);
break;
case 4: // day of week
t = dw; t += a;
if ((t > 0) && (t <= 7)) dw = t;
lcd.print(wdays[dw]);
break;
case 5: // hour
t = hh; t += a;
if ((t >= 0) && (t < 24)) hh = t;
if (hh < 10) lcd.print('0');
lcd.print(hh, DEC);
break;
case 6: // minutes
t = mm; t += a;
if ((t >= 0) && (t < 60)) mm = t;
if (mm < 10) lcd.print('0');
lcd.print(mm, DEC);
break;
}
switch (setAlarm) {
case 1: // enable
ae = 1 - ae;
ae ? lcd.print("Evet") : lcd.print("Hayir");
break;
case 2: // hour
t = ah; t += a;
if ((t >= 0) && (t < 24)) ah = t;
if (ah < 10) lcd.print('0');
lcd.print(ah, DEC);
break;
case 3: // minutes
t = am; t += a;
if ((t >= 0) && (t < 60)) am = t;
if (am < 10) lcd.print('0');
lcd.print(am, DEC);
break;
}
}
void setAlVariable() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Alarm");
lcd.setCursor(0, 1);
lcd.print("< >");
rtc_write_reg(0x8E, 0x00);
switch (setAlarm) {
case 1: // alarm enabled
lcd.setCursor(6, 0);
lcd.print("Etkin");
lcd.setCursor(6, 1);
ae ? lcd.print("Evet") : lcd.print("Hayir");
break;
case 2: // alarm hour
rtc_write_reg(0xC0, ae);
if (ae == 0) { // is disabled, do not ask for ah and am
setAlarm = 0;
rtc_write_reg(0x8E, 0x80); // yazma koruması
initTimeDisplay();
updateDisplay();
return;
}
lcd.setCursor(6, 0);
lcd.print("Saat");
lcd.setCursor(6, 1);
if (ah < 10) lcd.print('0');
lcd.print(ah, DEC);
break;
case 3: // alarm minute
rtc_write_reg(0xC2, ah);
lcd.setCursor(6, 0);
lcd.print("Dakika");
lcd.setCursor(6, 1);
if (am < 10) lcd.print('0');
lcd.print(am, DEC);
break;
case 4:
rtc_write_reg(0xC4, am);
default:
setAlarm = 0;
rtc_write_reg(0x8E, 0x80); // yazma koruması
initTimeDisplay();
updateDisplay();
}
}
void setup() {
pinMode(RTC_RST, OUTPUT);
pinMode(RTC_CLK, OUTPUT);
pinMode(RTC_DAT, INPUT);
digitalWrite(RTC_RST, LOW);
pinMode(BTN_AL, INPUT_PULLUP);
pinMode(BTN_DN, INPUT_PULLUP);
pinMode(BTN_UP, INPUT_PULLUP);
pinMode(BTN_SET, INPUT_PULLUP);
pinMode(AL_BUZZ, OUTPUT);
digitalWrite(AL_BUZZ, LOW);
delay(1000);
lcd.begin(16, 2);
lcd.setBacklightPin(3,POSITIVE);
lcd.setBacklight(HIGH);
// get alarm info
ae = rtc_read_reg(0xC1);
ah = rtc_read_reg(0xC3);
am = rtc_read_reg(0xC5);
if ((ah > 23) || (am > 59)) {
ae = 0;
ah = 0;
am = 0;
}
initTimeDisplay();
updateDisplay();
}
void loop() {
unsigned long current = millis();
if ((current >= timeUpdate + 1000) && (setMode + setAlarm == 0)) {
if (ss == 0) {
updateDisplay();
if (ae && (hh == ah) && (mm == am)) alarmOn = true;
else alarmOn = false;
}
// display seconds
lcd.setCursor(10, 0);
if (ss < 10) lcd.print('0');
lcd.print(ss, DEC);
// increment seconds
ss++;
if (ss == 60) ss = 0;
timeUpdate = current;
}
if (current >= timeButton + 10) {
if ((digitalRead(BTN_SET) == LOW) && (setAlarm == 0)) {
buttonPress = true;
setMode++;
setVariable();
}
if ((digitalRead(BTN_UP) == LOW) && (setMode || setAlarm)) {
buttonPress = true;
adjustVariable(1);
}
if ((digitalRead(BTN_DN) == LOW) && (setMode || setAlarm)) {
buttonPress = true;
adjustVariable(-1);
}
if ((digitalRead(BTN_AL) == LOW) && (setMode == 0)) {
buttonPress = true;
if (alarmOn) {
alarmOn = 0;
digitalWrite(AL_BUZZ, LOW);
lcd.setCursor(0, 0); lcd.print(" ");
lcd.setCursor(13, 0); lcd.print(" ");
}
else {
setAlarm++;
setAlVariable();
}
}
timeButton = current;
if (buttonPress) {
timeButton += 200; // 200 ms tuş basma araları
buttonPress = false;
}
}
if (current >= timeAlarm + 300) {
if (alarmOn) {
digitalWrite(AL_BUZZ, alarmSw);
lcd.setCursor(0, 0);
alarmSw ? lcd.print("<<<") : lcd.print(" ");
lcd.setCursor(13, 0);
alarmSw ? lcd.print(">>>") : lcd.print(" ");
alarmSw = 1 - alarmSw;
timeAlarm = current;
}
else
digitalWrite(AL_BUZZ, LOW);
}
}
KULLANILAN PROGRAMLAR: Arduino Ide 1.8.9

Hiç yorum yok:
Yorum Gönder