Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* D. Lam's Alarm Clock
- Sources:
- http://staticjolt.com/shift-registers-arduino-tutorial/
- http://www.circuitbasics.com/how-to-set-up-an-lcd-display-on-an-arduino/
- http://www.instructables.com/id/Musical-Snow-Globe/?ALLSTEPS
- https://learn.adafruit.com/ds1307-real-time-clock-breakout-board-kit/understanding-the-code
- https://www.arduino.cc/en/Tutorial/Switch
- */
- // include the library code:
- #include <LiquidCrystal.h>
- #include "pitches.h"
- #include "RTClib.h"
- #include <Wire.h>
- RTC_DS1307 RTC;
- // initialize the library with the numbers of the interface pins
- LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
- int AM_PM[12] = {1,2,3,4,5,6,7,8,9,10,11,12};
- int speaker = 7;
- int DS_pin = 8;
- int STCP_pin = 9;
- int SHCP_pin = 10;
- int switch_mode = A0; //button 1
- int switch_direction = A1; //button 2
- int switch_change = A2; //button 3
- int alarm = 0;
- int alarm_hour = 0;
- int alarm_minute = 0;
- int state = HIGH;
- int reading;
- int previous = LOW;
- long time = 0;
- long debounce = 200;
- // notes in the snow man melody:
- int snowman[] = {
- NOTE_DS4, NOTE_DS4, NOTE_DS4, NOTE_AS3, NOTE_DS4, NOTE_G4, NOTE_F4, NOTE_G4, 0, 0,
- 0, 0, NOTE_DS4, NOTE_DS4,NOTE_AS3, NOTE_DS4, NOTE_G4, NOTE_F4, 0, 0, 0, 0, 0,
- NOTE_DS4, NOTE_DS4, NOTE_AS3, NOTE_DS4, NOTE_G4, NOTE_GS4, NOTE_G4, NOTE_DS4, 0, NOTE_C4, NOTE_GS4, NOTE_G4,
- NOTE_DS4, 0, NOTE_DS4, NOTE_DS4, NOTE_AS3, NOTE_DS4, NOTE_G4, NOTE_B3, 0
- };
- // note durations: 4 = quarter note, 8 = eighth note, etc.:
- int snowmanDurations[] = {
- 8, 8, 8, 8, 8, 8, 4, 2, 4, 8,
- 4, 8, 8, 8, 8, 8, 8, 2, 4, 4, 8, 4, 8,
- 8, 8, 8, 8, 8, 8, 8, 4, 8, 8, 8, 8,
- 4, 8, 8, 8, 8, 8, 8, 4, 4
- };
- void play_snowmanMelody(){
- while(digitalRead(switch_direction) && digitalRead(switch_change)){
- for (int thisNote = 0; thisNote < (sizeof(snowmanDurations)/2); thisNote++) {
- long random_led = random(0, 8);
- // to calculate the note duration, take one second
- // divided by the note type.
- //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
- int snowmanDuration = 1500/snowmanDurations[thisNote];
- tone(speaker, snowman[thisNote], snowmanDuration);
- // to distinguish the notes, set a minimum time between them.
- // the note's duration + 30% seems to work well:
- int pauseBetweenNotes = snowmanDuration * 1.30;
- if(snowman[thisNote] != 0){
- setRegisterPin(random_led, HIGH);
- }
- delay(pauseBetweenNotes/2);
- if(!digitalRead(switch_direction) || !digitalRead(switch_change)){
- clearreg();
- writereg();
- break;
- }
- delay(pauseBetweenNotes/2);
- if(!digitalRead(switch_direction) || !digitalRead(switch_change)){
- clearreg();
- writereg();
- break;
- }
- setRegisterPin(random_led, LOW);
- // stop the tone playing:
- noTone(speaker);
- }
- }
- }
- void setup() {
- lcd.begin(16, 2);
- default_display();
- Wire.begin();
- RTC.begin();
- //RTC.adjust(DateTime(__DATE__,__TIME__));
- pinMode(speaker, OUTPUT);
- pinMode(DS_pin,OUTPUT);
- pinMode(STCP_pin,OUTPUT);
- pinMode(SHCP_pin,OUTPUT);
- pinMode(switch_mode, INPUT);
- pinMode(switch_direction, INPUT);
- pinMode(switch_change, INPUT);
- clearreg();
- writereg();
- randomSeed(analogRead(3));
- //play_snowmanMelody();
- }
- boolean registers[8];
- void writereg(){
- digitalWrite(STCP_pin, LOW);
- for (int i = 7; i>=0; i--){
- digitalWrite(SHCP_pin, LOW);
- digitalWrite(DS_pin, registers[i]);
- digitalWrite(SHCP_pin, HIGH);
- }
- digitalWrite(STCP_pin, HIGH);
- }
- void clearreg(){
- for(int i = 7; i >= 0; i--){
- registers[i] = LOW;
- }
- }
- void setRegisterPin(int index, int value){
- registers[index] = value;
- writereg();
- delay(50);
- }
- void led_sequence(){
- for(int i = 0; i < 8; i++){
- if(!i){
- setRegisterPin(i, HIGH);
- }
- else{
- setRegisterPin(i, HIGH);
- setRegisterPin(i - 1, LOW);
- }
- }
- for(int i = 6; i >= 0; i--){
- setRegisterPin(i, HIGH);
- setRegisterPin(i + 1, LOW);
- }
- setRegisterPin(0, LOW);
- }
- void led_blink(){
- for(int i = 0; i < 8; i++){
- setRegisterPin(i, HIGH);
- }
- delay(200);
- for(int i = 7; i >= 0; i--){
- setRegisterPin(i, LOW);
- }
- delay(200);
- for(int i = 7; i >= 0; i--){
- setRegisterPin(i, HIGH);
- }
- delay(200);
- for(int i = 0; i < 8; i++){
- setRegisterPin(i, LOW);
- }
- }
- void check_switch_mode(){
- reading = digitalRead(switch_mode);
- if (reading == HIGH && previous == LOW && millis() - time > debounce) {
- if (state == HIGH)
- state = LOW;
- else
- state = HIGH;
- time = millis();
- }
- previous = reading;
- }
- void edit_time(){
- delay(500);
- int cursor_position = 1;
- lcd.setCursor(7,1);
- while(1){
- lcd.blink();
- if(!digitalRead(switch_direction)){
- cursor_position++;
- if(cursor_position > 2){
- lcd.noBlink();
- led_sequence();
- return;
- }
- switch(cursor_position){
- case 1:
- lcd.setCursor(7,1);
- break;
- case 2:
- lcd.setCursor(10,1);
- break;
- }
- delay(500);
- }
- if(!digitalRead(switch_change)){
- DateTime now = RTC.now();
- int new_hour = now.hour();
- int new_minute = now.minute();
- switch(cursor_position){
- case 1:
- if((now.hour() + 1) > 23){
- new_hour = 0;
- }
- else new_hour = (now.hour() + 1);
- RTC.adjust(DateTime(now.year(), now.month(), now.day(), new_hour, now.minute(), 0));
- lcd.setCursor(0,1);
- display_time();
- lcd.setCursor(7,1);
- break;
- case 2:
- if((now.minute() + 1) > 59){
- new_minute = 0;
- }
- else new_minute = (now.minute() + 1);
- RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), new_minute, 0));
- lcd.setCursor(0,1);
- display_time();
- lcd.setCursor(10,1);
- break;
- }
- delay(500);
- }
- }
- }
- void edit_alarm(){
- int cursor_position = 1;
- lcd.clear();
- lcd.setCursor(0,0);
- lcd.print("Alarm: ");
- if(alarm) lcd.print("ON");
- else lcd.print("OFF");
- lcd.setCursor(0,1);
- display_alarm();
- lcd.setCursor(7,0);
- while(state == LOW){
- check_switch_mode();
- lcd.blink();
- if(!digitalRead(switch_direction)){ //2nd button
- cursor_position++;
- if(cursor_position > 3) cursor_position = 1;
- switch(cursor_position){
- case 1: //Alarm on or off
- lcd.setCursor(7,0);
- break;
- case 2: //hours
- lcd.setCursor(1,1);
- break;
- case 3: //minutes
- lcd.setCursor(4,1);
- break;
- }
- delay(500);
- }
- if(!digitalRead(switch_change)){ //3rd button
- switch(cursor_position){
- case 1:
- if(!alarm) alarm = 1;
- else alarm = 0;
- if(alarm) lcd.print("ON ");
- else lcd.print("OFF");
- lcd.setCursor(7,0);
- break;
- case 2:
- alarm_hour++;
- if(alarm_hour > 23) alarm_hour = 0;
- lcd.setCursor(0,1);
- display_alarm_hour();
- lcd.setCursor(6,1);
- if(alarm_hour < 12) lcd.print("AM");
- else lcd.print("PM");
- lcd.setCursor(1,1);
- break;
- case 3:
- alarm_minute++;
- if(alarm_minute > 59) alarm_minute = 0;
- lcd.setCursor(3,1);
- display_alarm_minute();
- lcd.setCursor(4,1);
- break;
- }
- delay(200);
- }
- }
- }
- void default_display(){
- lcd.clear();
- lcd.setCursor(0,0);
- lcd.print("Alarm Clock");
- lcd.print(" ");
- if(alarm) lcd.print("ON");
- else lcd.print("OFF");
- lcd.noBlink();
- }
- void display_time(){
- DateTime now = RTC.now();
- lcd.print(now.month(), DEC);
- lcd.print('/');
- lcd.print(now.day(), DEC);
- lcd.setCursor(6,1);
- if(now.hour() > 12 && now.hour() < 22){ //1 PM - 9 PM
- lcd.print(' ');
- lcd.print(AM_PM[now.hour() - 13]);
- }
- else if(now.hour() > 21){ // 10 PM - 12 AM
- lcd.print(AM_PM[now.hour() - 13]);
- }
- else if(now.hour() == 0){ // 12 AM
- lcd.print(AM_PM[now.hour() + 11]);
- }
- else if(now.hour() > 0 && now.hour() < 10){ //1 AM - 9 AM
- lcd.print(' ');
- lcd.print(now.hour(), DEC);
- }
- else{ //10 AM - 12 PM
- lcd.print(now.hour(), DEC);
- }
- lcd.print(':');
- if(now.minute() < 10){
- lcd.print('0');
- lcd.print(now.minute(), DEC);
- }
- else{
- lcd.print(now.minute(), DEC);
- }
- lcd.print(' ');
- if(now.hour() < 12) lcd.print("AM");
- else lcd.print("PM");
- }
- void display_alarm_hour(){
- if(alarm_hour > 12 && alarm_hour < 22){ //1 PM - 9 PM
- lcd.print(' ');
- lcd.print(AM_PM[alarm_hour - 13]);
- }
- else if(alarm_hour > 21){ // 10 PM - 12 AM
- lcd.print(AM_PM[alarm_hour - 13]);
- }
- else if(alarm_hour == 0){ // 12 AM
- lcd.print(AM_PM[alarm_hour + 11]);
- }
- else if(alarm_hour > 0 && alarm_hour < 10){ //1 AM - 9 AM
- lcd.print(' ');
- lcd.print(alarm_hour);
- }
- else{ //10 AM - 12 PM
- lcd.print(alarm_hour);
- }
- }
- void display_alarm_minute(){
- if(alarm_minute < 10){
- lcd.print('0');
- lcd.print(alarm_minute);
- }
- else{
- lcd.print(alarm_minute);
- }
- }
- void display_alarm(){
- display_alarm_hour();
- lcd.print(':');
- display_alarm_minute();
- lcd.print(' ');
- if(alarm_hour < 12) lcd.print("AM");
- else lcd.print("PM");
- }
- void check_alarm(){
- DateTime now = RTC.now();
- int current_hour = now.hour();
- int current_minute = now.minute();
- if(alarm_hour == current_hour && alarm_minute == current_minute && alarm){
- play_snowmanMelody();
- alarm = 0;
- led_blink();
- default_display();
- }
- }
- void loop(){
- noTone(speaker);
- lcd.setCursor(0, 1);
- display_time();
- check_alarm();
- check_switch_mode();
- if(state == LOW){
- edit_alarm();
- led_sequence();
- default_display();
- }
- if(!digitalRead(switch_direction)){
- edit_time();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement