Advertisement
Guest User

Arduino Alarm Clock

a guest
Jul 6th, 2015
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.12 KB | None | 0 0
  1. /* D. Lam's Alarm Clock
  2. Sources:
  3. http://staticjolt.com/shift-registers-arduino-tutorial/
  4. http://www.circuitbasics.com/how-to-set-up-an-lcd-display-on-an-arduino/
  5. http://www.instructables.com/id/Musical-Snow-Globe/?ALLSTEPS
  6. https://learn.adafruit.com/ds1307-real-time-clock-breakout-board-kit/understanding-the-code
  7. https://www.arduino.cc/en/Tutorial/Switch
  8. */
  9. // include the library code:
  10. #include <LiquidCrystal.h>
  11. #include "pitches.h"
  12. #include "RTClib.h"
  13. #include <Wire.h>
  14.  
  15. RTC_DS1307 RTC;
  16.  
  17. // initialize the library with the numbers of the interface pins
  18. LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
  19. int AM_PM[12] = {1,2,3,4,5,6,7,8,9,10,11,12};
  20.  
  21. int speaker = 7;
  22. int DS_pin = 8;
  23. int STCP_pin = 9;
  24. int SHCP_pin = 10;
  25. int switch_mode = A0; //button 1
  26. int switch_direction = A1; //button 2
  27. int switch_change = A2; //button 3
  28.  
  29. int alarm = 0;
  30. int alarm_hour = 0;
  31. int alarm_minute = 0;
  32.  
  33. int state = HIGH;
  34. int reading;
  35. int previous = LOW;
  36.  
  37. long time = 0;
  38. long debounce = 200;
  39.  
  40. // notes in the snow man melody:
  41. int snowman[] = {
  42. NOTE_DS4, NOTE_DS4, NOTE_DS4, NOTE_AS3, NOTE_DS4, NOTE_G4, NOTE_F4, NOTE_G4, 0, 0,
  43. 0, 0, NOTE_DS4, NOTE_DS4,NOTE_AS3, NOTE_DS4, NOTE_G4, NOTE_F4, 0, 0, 0, 0, 0,
  44. NOTE_DS4, NOTE_DS4, NOTE_AS3, NOTE_DS4, NOTE_G4, NOTE_GS4, NOTE_G4, NOTE_DS4, 0, NOTE_C4, NOTE_GS4, NOTE_G4,
  45. NOTE_DS4, 0, NOTE_DS4, NOTE_DS4, NOTE_AS3, NOTE_DS4, NOTE_G4, NOTE_B3, 0
  46. };
  47.  
  48. // note durations: 4 = quarter note, 8 = eighth note, etc.:
  49. int snowmanDurations[] = {
  50. 8, 8, 8, 8, 8, 8, 4, 2, 4, 8,
  51. 4, 8, 8, 8, 8, 8, 8, 2, 4, 4, 8, 4, 8,
  52. 8, 8, 8, 8, 8, 8, 8, 4, 8, 8, 8, 8,
  53. 4, 8, 8, 8, 8, 8, 8, 4, 4
  54. };
  55.  
  56. void play_snowmanMelody(){
  57. while(digitalRead(switch_direction) && digitalRead(switch_change)){
  58.  
  59. for (int thisNote = 0; thisNote < (sizeof(snowmanDurations)/2); thisNote++) {
  60. long random_led = random(0, 8);
  61. // to calculate the note duration, take one second
  62. // divided by the note type.
  63. //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
  64. int snowmanDuration = 1500/snowmanDurations[thisNote];
  65. tone(speaker, snowman[thisNote], snowmanDuration);
  66.  
  67. // to distinguish the notes, set a minimum time between them.
  68. // the note's duration + 30% seems to work well:
  69. int pauseBetweenNotes = snowmanDuration * 1.30;
  70. if(snowman[thisNote] != 0){
  71. setRegisterPin(random_led, HIGH);
  72. }
  73. delay(pauseBetweenNotes/2);
  74. if(!digitalRead(switch_direction) || !digitalRead(switch_change)){
  75. clearreg();
  76. writereg();
  77. break;
  78. }
  79. delay(pauseBetweenNotes/2);
  80. if(!digitalRead(switch_direction) || !digitalRead(switch_change)){
  81. clearreg();
  82. writereg();
  83. break;
  84. }
  85. setRegisterPin(random_led, LOW);
  86. // stop the tone playing:
  87. noTone(speaker);
  88. }
  89. }
  90. }
  91.  
  92. void setup() {
  93.  
  94. lcd.begin(16, 2);
  95. default_display();
  96. Wire.begin();
  97. RTC.begin();
  98. //RTC.adjust(DateTime(__DATE__,__TIME__));
  99. pinMode(speaker, OUTPUT);
  100. pinMode(DS_pin,OUTPUT);
  101. pinMode(STCP_pin,OUTPUT);
  102. pinMode(SHCP_pin,OUTPUT);
  103. pinMode(switch_mode, INPUT);
  104. pinMode(switch_direction, INPUT);
  105. pinMode(switch_change, INPUT);
  106. clearreg();
  107. writereg();
  108. randomSeed(analogRead(3));
  109. //play_snowmanMelody();
  110. }
  111.  
  112. boolean registers[8];
  113.  
  114. void writereg(){
  115. digitalWrite(STCP_pin, LOW);
  116. for (int i = 7; i>=0; i--){
  117. digitalWrite(SHCP_pin, LOW);
  118. digitalWrite(DS_pin, registers[i]);
  119. digitalWrite(SHCP_pin, HIGH);
  120. }
  121. digitalWrite(STCP_pin, HIGH);
  122. }
  123.  
  124. void clearreg(){
  125. for(int i = 7; i >= 0; i--){
  126. registers[i] = LOW;
  127. }
  128. }
  129.  
  130. void setRegisterPin(int index, int value){
  131. registers[index] = value;
  132. writereg();
  133. delay(50);
  134. }
  135.  
  136. void led_sequence(){
  137. for(int i = 0; i < 8; i++){
  138. if(!i){
  139. setRegisterPin(i, HIGH);
  140. }
  141. else{
  142. setRegisterPin(i, HIGH);
  143. setRegisterPin(i - 1, LOW);
  144. }
  145. }
  146. for(int i = 6; i >= 0; i--){
  147. setRegisterPin(i, HIGH);
  148. setRegisterPin(i + 1, LOW);
  149. }
  150. setRegisterPin(0, LOW);
  151. }
  152.  
  153. void led_blink(){
  154. for(int i = 0; i < 8; i++){
  155. setRegisterPin(i, HIGH);
  156. }
  157. delay(200);
  158. for(int i = 7; i >= 0; i--){
  159. setRegisterPin(i, LOW);
  160. }
  161. delay(200);
  162. for(int i = 7; i >= 0; i--){
  163. setRegisterPin(i, HIGH);
  164. }
  165. delay(200);
  166. for(int i = 0; i < 8; i++){
  167. setRegisterPin(i, LOW);
  168. }
  169. }
  170.  
  171. void check_switch_mode(){
  172. reading = digitalRead(switch_mode);
  173. if (reading == HIGH && previous == LOW && millis() - time > debounce) {
  174. if (state == HIGH)
  175. state = LOW;
  176. else
  177. state = HIGH;
  178.  
  179. time = millis();
  180. }
  181. previous = reading;
  182. }
  183.  
  184. void edit_time(){
  185. delay(500);
  186. int cursor_position = 1;
  187. lcd.setCursor(7,1);
  188. while(1){
  189. lcd.blink();
  190. if(!digitalRead(switch_direction)){
  191. cursor_position++;
  192. if(cursor_position > 2){
  193. lcd.noBlink();
  194. led_sequence();
  195. return;
  196. }
  197. switch(cursor_position){
  198. case 1:
  199. lcd.setCursor(7,1);
  200. break;
  201. case 2:
  202. lcd.setCursor(10,1);
  203. break;
  204. }
  205. delay(500);
  206. }
  207. if(!digitalRead(switch_change)){
  208. DateTime now = RTC.now();
  209. int new_hour = now.hour();
  210. int new_minute = now.minute();
  211. switch(cursor_position){
  212. case 1:
  213. if((now.hour() + 1) > 23){
  214. new_hour = 0;
  215. }
  216. else new_hour = (now.hour() + 1);
  217. RTC.adjust(DateTime(now.year(), now.month(), now.day(), new_hour, now.minute(), 0));
  218. lcd.setCursor(0,1);
  219. display_time();
  220. lcd.setCursor(7,1);
  221. break;
  222. case 2:
  223. if((now.minute() + 1) > 59){
  224. new_minute = 0;
  225. }
  226. else new_minute = (now.minute() + 1);
  227. RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), new_minute, 0));
  228. lcd.setCursor(0,1);
  229. display_time();
  230. lcd.setCursor(10,1);
  231. break;
  232. }
  233. delay(500);
  234. }
  235. }
  236. }
  237.  
  238. void edit_alarm(){
  239. int cursor_position = 1;
  240. lcd.clear();
  241. lcd.setCursor(0,0);
  242. lcd.print("Alarm: ");
  243. if(alarm) lcd.print("ON");
  244. else lcd.print("OFF");
  245. lcd.setCursor(0,1);
  246. display_alarm();
  247. lcd.setCursor(7,0);
  248. while(state == LOW){
  249. check_switch_mode();
  250. lcd.blink();
  251. if(!digitalRead(switch_direction)){ //2nd button
  252. cursor_position++;
  253. if(cursor_position > 3) cursor_position = 1;
  254. switch(cursor_position){
  255. case 1: //Alarm on or off
  256. lcd.setCursor(7,0);
  257. break;
  258. case 2: //hours
  259. lcd.setCursor(1,1);
  260. break;
  261. case 3: //minutes
  262. lcd.setCursor(4,1);
  263. break;
  264. }
  265. delay(500);
  266. }
  267. if(!digitalRead(switch_change)){ //3rd button
  268. switch(cursor_position){
  269. case 1:
  270. if(!alarm) alarm = 1;
  271. else alarm = 0;
  272. if(alarm) lcd.print("ON ");
  273. else lcd.print("OFF");
  274. lcd.setCursor(7,0);
  275. break;
  276. case 2:
  277. alarm_hour++;
  278. if(alarm_hour > 23) alarm_hour = 0;
  279. lcd.setCursor(0,1);
  280. display_alarm_hour();
  281. lcd.setCursor(6,1);
  282. if(alarm_hour < 12) lcd.print("AM");
  283. else lcd.print("PM");
  284. lcd.setCursor(1,1);
  285. break;
  286. case 3:
  287. alarm_minute++;
  288. if(alarm_minute > 59) alarm_minute = 0;
  289. lcd.setCursor(3,1);
  290. display_alarm_minute();
  291. lcd.setCursor(4,1);
  292. break;
  293. }
  294. delay(200);
  295. }
  296. }
  297. }
  298.  
  299. void default_display(){
  300. lcd.clear();
  301. lcd.setCursor(0,0);
  302. lcd.print("Alarm Clock");
  303. lcd.print(" ");
  304. if(alarm) lcd.print("ON");
  305. else lcd.print("OFF");
  306. lcd.noBlink();
  307. }
  308.  
  309. void display_time(){
  310. DateTime now = RTC.now();
  311. lcd.print(now.month(), DEC);
  312. lcd.print('/');
  313. lcd.print(now.day(), DEC);
  314. lcd.setCursor(6,1);
  315. if(now.hour() > 12 && now.hour() < 22){ //1 PM - 9 PM
  316. lcd.print(' ');
  317. lcd.print(AM_PM[now.hour() - 13]);
  318. }
  319. else if(now.hour() > 21){ // 10 PM - 12 AM
  320. lcd.print(AM_PM[now.hour() - 13]);
  321. }
  322. else if(now.hour() == 0){ // 12 AM
  323. lcd.print(AM_PM[now.hour() + 11]);
  324. }
  325. else if(now.hour() > 0 && now.hour() < 10){ //1 AM - 9 AM
  326. lcd.print(' ');
  327. lcd.print(now.hour(), DEC);
  328. }
  329. else{ //10 AM - 12 PM
  330. lcd.print(now.hour(), DEC);
  331. }
  332. lcd.print(':');
  333. if(now.minute() < 10){
  334. lcd.print('0');
  335. lcd.print(now.minute(), DEC);
  336. }
  337. else{
  338. lcd.print(now.minute(), DEC);
  339. }
  340. lcd.print(' ');
  341. if(now.hour() < 12) lcd.print("AM");
  342. else lcd.print("PM");
  343. }
  344.  
  345. void display_alarm_hour(){
  346. if(alarm_hour > 12 && alarm_hour < 22){ //1 PM - 9 PM
  347. lcd.print(' ');
  348. lcd.print(AM_PM[alarm_hour - 13]);
  349. }
  350. else if(alarm_hour > 21){ // 10 PM - 12 AM
  351. lcd.print(AM_PM[alarm_hour - 13]);
  352. }
  353. else if(alarm_hour == 0){ // 12 AM
  354. lcd.print(AM_PM[alarm_hour + 11]);
  355. }
  356. else if(alarm_hour > 0 && alarm_hour < 10){ //1 AM - 9 AM
  357. lcd.print(' ');
  358. lcd.print(alarm_hour);
  359. }
  360. else{ //10 AM - 12 PM
  361. lcd.print(alarm_hour);
  362. }
  363. }
  364.  
  365. void display_alarm_minute(){
  366. if(alarm_minute < 10){
  367. lcd.print('0');
  368. lcd.print(alarm_minute);
  369. }
  370. else{
  371. lcd.print(alarm_minute);
  372. }
  373. }
  374.  
  375.  
  376. void display_alarm(){
  377. display_alarm_hour();
  378. lcd.print(':');
  379. display_alarm_minute();
  380. lcd.print(' ');
  381. if(alarm_hour < 12) lcd.print("AM");
  382. else lcd.print("PM");
  383. }
  384.  
  385. void check_alarm(){
  386. DateTime now = RTC.now();
  387. int current_hour = now.hour();
  388. int current_minute = now.minute();
  389. if(alarm_hour == current_hour && alarm_minute == current_minute && alarm){
  390. play_snowmanMelody();
  391. alarm = 0;
  392. led_blink();
  393. default_display();
  394. }
  395. }
  396.  
  397. void loop(){
  398. noTone(speaker);
  399. lcd.setCursor(0, 1);
  400. display_time();
  401. check_alarm();
  402. check_switch_mode();
  403. if(state == LOW){
  404. edit_alarm();
  405. led_sequence();
  406. default_display();
  407. }
  408. if(!digitalRead(switch_direction)){
  409. edit_time();
  410. }
  411. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement