smi1100
Published © GPL3+

Never wake up too late - Alarm Clock with annoying tone

An Arduino-based alarm clock with a 3D printed casing.

IntermediateFull instructions provided1,886
Never wake up too late - Alarm Clock with annoying tone

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1
Real Time Clock (RTC)
Real Time Clock (RTC)
×1
Alphanumeric LCD, 20 x 4
Alphanumeric LCD, 20 x 4
×1
Buzzer
Buzzer
×1
Pushbutton switch 12mm
SparkFun Pushbutton switch 12mm
×5
Resistor 10k ohm
Resistor 10k ohm
×5
Breadboard (generic)
Breadboard (generic)
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
3D Printer (generic)
3D Printer (generic)

Story

Read more

Custom parts and enclosures

Case - Backside

Case - Frontside

Schematics

Fritzing

Code

Alarm Clock

Arduino
/* 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;
}

Credits

smi1100
3 projects • 2 followers
Contact

Comments

Please log in or sign up to comment.