/* Alarm Clock
by smi1100 - 06/06/2019
My first project. The following components are needed:
- Arduino Uno
- DS3231 real time clock
- 20x4 I2C Display
- buzzer
- 5 buttons
- 5 resistors 10k Ohm
- bread board
- casing
/* modul 0 - I2C Bus
- I2C adresses
- LCD 0x27
- real time clock
RTC DS3231 0x68
EEPROM AT24C32 0x57 (not in use)
*/
#include <Wire.h>
/* modul 1 - DS3231 real time clock
- connections (from right side) - GND, VCC, SDA, SCL
- RTClib.h is required
- I2C connection
*/
#include "RTClib.h"
RTC_DS1307 rtc;
char weekday[7][12] = {"Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerst.", "Freitag", "Samstag"};
// in english char weekday[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
/* modul 2 - Joy-IT SBC-LCD 20x4 display
- 4 rows, 20 characters
- connections (from right side) - GND, VCC, SDA, SCL
- LiquidCrystal_I2C.h is required
- I2C connection
*/
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4); // adress 0x27
//LiquidCrystal_I2C lcd(0x3F,20,4); // if the lcd is not working, change adress to 0x3F
/* modul 3 - buttons to adjust the alarm time and button for the buzzer
*/
int buzzer = 4;
int buttonhourup = A3;
int buttonhourdown = A2;
int buttonminuteup = A1;
int buttonminutedown = A0;
int readbuttonhourup;
int readbuttonhourdown;
int readbuttonminuteup;
int readbuttonminutedown;
// alarmtime
int alarmtimehour;
int alarmtimeminute;
/* modul 4 - switch for alarm on/off
- OneButton.h is required
- see internet resource https://www.makerblog.at/2015/01/arduino-und-pushbuttons-drucktaster-einbinden-mit-der-onebutton-library/
*/
#include "OneButton.h"
int buttonalarm = 5;
OneButton button(buttonalarm, false);
int alarmstate = 1; // equal to alarm is on
int alarmtimeequaltime = 0; // active when alarm time is equal to time
/* modul 5 - EEPROM - backup of alarmtime in the EEPROM
- EEPROM.h is required
*/
#include "EEPROM.h"
/* code 1 - summer or winter time
- see internet resource https://kaufma.net/blog/article/2016/08/24/sommerzeit-im-microcontroller/
- see internet resource https://electronicfreakblog.wordpress.com/2014/03/06/die-zeit-im-sommer-und-im-winter/
DST = Daylight Saving Time, equal to summer time
*/
int DST;
/* code 2 - changing buzzer sound
*/
unsigned long previousMillis = 0;
const long interval = 1000;
void setup ()
{
Serial.begin(9600);
// read alarmtime from EEPROM
alarmtimehour = EEPROM.read(0);
alarmtimeminute = EEPROM.read(1);
// initialize DS3231 RTC
Serial.begin(9600);
while (!Serial); // for Leonardo/Micro/Zero
if (! rtc.begin())
{
Serial.println("Couldn't find RTC");
while (1);
}
if (! rtc.isrunning())
{
// define format once
Serial.println("RTC is NOT running!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
Serial.println("RTC adjusted!");
}
// initialize display
lcd.init();
lcd.backlight();
// initialize buttons and buzzer
pinMode(buttonhourup, INPUT);
pinMode(buttonhourdown, INPUT);
pinMode(buttonminuteup, INPUT);
pinMode(buttonminutedown, INPUT);
pinMode(buzzer, OUTPUT);
// initialize button as a switch
pinMode(buttonalarm, INPUT);
button.attachClick(clickedIt);
}
void loop ()
{
//determine summer or winter time
int DST;
DateTime now = rtc.now();
if (now.month() == 3 && now.day() > 24 && now.dayOfTheWeek() == 1 && now.hour() >= 2 || //exakter Tag Beginn
now.month() == 3 && now.day() + 8 - now.dayOfTheWeek() > 31 && now.dayOfTheWeek() != 1 || // restlichen Tage des Mrz
now.month() > 3 && now.month() < 10 || //April bis September
now.month() == 10 && now.day() + 8 - now.dayOfTheWeek() < 32 || //Oktober bis Tag vor letztem Sonntag
now.month() == 10 && now.day() > 24 && now.dayOfTheWeek() == 1 && now.hour() <= 3) //letzter Sonntag
{
DST = 1;
Serial.print("summertime - ");
Serial.print("time: ");
Serial.println(now.hour()+DST);
}
else
{
DST = 0;
Serial.print("wintertime - ");
Serial.print("time: ");
Serial.println(now.hour());
}
// button as a switch
button.tick();
delay(10);
// shown data on the LCD
lcd.setCursor(1, 0);
lcd.print(weekday[now.dayOfTheWeek()]);
lcd.print(" ");
lcd.setCursor(13, 0);
if (now.day() < 10) lcd.print("0"); // less than 10 -> add 0 before it
lcd.print(now.day(), DEC);
lcd.print(".");
if (now.month() < 10) lcd.print("0"); // less than 10 -> add 0 before it
lcd.print(now.month(), DEC);
//lcd.print(".");
//lcd.print(now.year(), DEC);
lcd.setCursor(0, 1);
lcd.print(" Zeit Alarm");
// in english lcd.print(" time alarm");
lcd.setCursor(0, 2);
lcd.print(" ");
if ((now.hour() + DST) < 10) lcd.print("0"); // less than 10 -> add 0 before it
lcd.print((now.hour() + DST), DEC);
lcd.print(":");
if (now.minute() < 10) lcd.print("0"); // less than 10 -> add 0 before it
lcd.print(now.minute(), DEC);
lcd.print(":");
if (now.second() < 10) lcd.print("0"); // less than 10 -> add 0 before it
lcd.print(now.second(), DEC);
lcd.print(" ");
if (alarmtimehour < 10) lcd.print("0"); // less than 10 -> add 0 before it
lcd.print(alarmtimehour, DEC);
lcd.print(':');
if (alarmtimeminute < 10) lcd.print("0"); // less than 10 -> add 0 before it
lcd.print(alarmtimeminute, DEC);
lcd.setCursor(14, 3);
if (alarmstate == 1)lcd.print("EIN");
else lcd.print("AUS");
/* in english if (alarmstate == 1)lcd.print("ON");
else lcd.print("OFF");
*/
// adjust the alarm time (hour)
readbuttonhourup = digitalRead(buttonhourup);
if (readbuttonhourup == HIGH)
{
delay(100);
if (alarmtimehour >= 23) alarmtimehour = 0;
else alarmtimehour ++;
}
readbuttonhourdown = digitalRead(buttonhourdown);
if (readbuttonhourdown == HIGH)
{
delay(100);
if (alarmtimehour <= 0) alarmtimehour = 23;
else alarmtimehour --;
}
// adjust the alarm time (minute)
readbuttonminuteup = digitalRead(buttonminuteup);
if (readbuttonminuteup == HIGH)
{
delay(100);
if (alarmtimeminute >= 59) alarmtimeminute = 0;
else alarmtimeminute ++;
}
readbuttonminutedown = digitalRead(buttonminutedown);
if (readbuttonminutedown == HIGH)
{
delay(100);
if (alarmtimeminute <= 0) alarmtimeminute = 59;
else alarmtimeminute --;
}
// write alarmtime to EEPROM
EEPROM.write(0, alarmtimehour); // first character = position, second character = value
EEPROM.write(1, alarmtimeminute);
// check alarm time
if ((now.hour() + DST) == alarmtimehour && now.minute() == alarmtimeminute && now.second() == 0 && alarmstate == 1)
{
alarmtimeequaltime = 1;
}
// activate alarm
if (alarmtimeequaltime == 1 && alarmstate == 1)
// it is not possible to use the command "delay" - the display of the seconds will stop
{
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval)
{
tone(buzzer, 1000);
if (currentMillis - previousMillis >= 2*interval)
{
previousMillis = currentMillis;
}
}
else
{
tone(buzzer, 300);
}
}
if (alarmtimeequaltime == 1 && alarmstate == 0)
{
noTone(buzzer);
alarmtimeequaltime = 0;
}
}
void clickedIt()
{
alarmstate = !alarmstate;
}
Comments
Please log in or sign up to comment.