Components and supplies
High Accuracy Pi RTC (DS3231)
Arduino Nano R3
LED switch button (green)
Graphic OLED, 128 x 32 Pixels
LED switch button (blue)
LED Light Bulb, Frosted GLS
Rotary potentiometer (generic)
DC-DC Buck (Step Down) Regulator, Adjustable
Power MOSFET N-Channel
Tools and machines
Solder Wire, Lead Free
Soldering iron (generic)
Solder Flux, Soldering
Project description
Code
wakeup.c
c_cpp
Main routine for the wakeup clock
1#include <Adafruit_GFX.h> 2#include <Adafruit_SSD1306.h> 3#include <Wire.h> //I2C library 4#include <RtcDS3231.h> //RTC library 5#include <EEPROM.h> 6// CONSTANTS 7//--------------------------------- 8#define BUTTON_L 3 9#define BUTTON_R 2 10#define SDA A4 11#define SLC A5 12#define FET_OUT 9 13#define POT_IN A2 14#define BUTTON_LED_OUT 6 15#define BUTTON_TIME 3000 // Time after which a click is considered as a long click 16#define BLINK_DURATION 1000 // Blink duration of digits when setting time/date 17#define SCREEN_WIDTH 128 // OLED display width, in pixels 18#define SCREEN_HEIGHT 32 // OLED display height, in pixels 19#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) 20// calendar image 21const static unsigned char PROGMEM calendar[] = {48, 12, 48, 12, 127, 254, 255, 255, 255, 255, 192, 3, 219, 109, 219, 109, 192, 1, 203, 109, 219, 109, 192, 1, 219, 109, 219, 109, 96, 2, 63, 252}; 22// bell image 23const static unsigned char PROGMEM bell[] = {1, 128, 1, 128, 3, 192, 6, 96, 12, 16, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 48, 12, 112, 14, 96, 6, 96, 14, 60, 60, 3, 192}; 24// clockhour image 25const static unsigned char PROGMEM clockhour[] = {3, 192, 12, 48, 16, 8, 33, 132, 65, 130, 65, 130, 129, 129, 129, 129, 129, 1, 130, 1, 68, 3, 72, 2, 32, 4, 16, 8, 12, 48, 3, 192}; 26// smiley image 27const static unsigned char PROGMEM smiley[] = {0, 15, 240, 0, 0, 127, 254, 0, 1, 255, 255, 128, 3, 240, 31, 192, 7, 0, 1, 224, 14, 0, 0, 240, 28, 240, 15, 120, 57, 8, 16, 188, 48, 96, 6, 28, 112, 240, 15, 14, 112, 240, 15, 14, 96, 240, 15, 6, 224, 240, 15, 7, 224, 96, 6, 7, 224, 0, 0, 7, 224, 0, 0, 7, 226, 0, 0, 71, 227, 128, 3, 199, 227, 248, 31, 199, 225, 255, 255, 135, 97, 255, 255, 134, 112, 255, 255, 6, 112, 127, 254, 14, 56, 63, 252, 12, 56, 31, 248, 28, 28, 15, 240, 56, 14, 0, 0, 112, 7, 0, 0, 224, 3, 192, 3, 192, 1, 240, 15, 128, 0, 127, 254, 0, 0, 31, 248, 0}; 28// hourglass image 29const static unsigned char hourglass[] PROGMEM = {63, 254, 31, 252, 16, 4, 11, 232, 11, 232, 11, 200, 4, 144, 2, 32, 2, 32, 4, 16, 8, 8, 8, 8, 8, 8, 16, 4, 31, 252, 63, 254}; 30// days per month 31const unsigned char daysPerMonth[12] = {31, 30, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 32// Functions 33boolean adjustDST(RtcDateTime& time_); 34unsigned char readButtons(); 35unsigned char readButtons_setTime(); 36void setDuration(unsigned char& curDuration); 37void setTime(unsigned char& curHour, unsigned char& curMin, boolean setAlarm = false); 38void setDate(unsigned short& curYear, unsigned char& curMonth, unsigned char& curDay); 39void u8gInfo(char info[]); 40void displayInfo(char info[], const unsigned char *picture); 41void displayInfo(char info[], short blink_index[]); 42void displayInfo(char info[], const unsigned char *picture, short blink_index[]); 43void displayInfo(char info[], char info2[]); 44void displayInfo(char info[], char info2[], const unsigned char *picture); 45// VARIABLES 46//--------------------------------- 47// Initialize flags 48boolean buttonActive = false; // if a button is clicked 49boolean longPressActive = false; // if long click 50boolean button1Active = false; // if button 1 clicked 51boolean button2Active = false; // if button 2 clicked 52boolean mainLightOn = false; // if main led on 53boolean updateTime = false; // if new time has been set 54boolean updateAlarm = false; // if new alarm has been set 55boolean alarmEnabled = false; 56boolean alarmRunning = false; 57boolean isDST = false; // if daylight saving time is on 58boolean displayOn = true; // whether or not display on screen 59// Initialize counters 60unsigned short potLevel; //pot level 61unsigned long buttonTimer = 0; // current click duration 62unsigned char currentMenu = 0; // current choosen menu 63char choice = '0'; // current user choice in menu (day, month, year, hour,...) 64long remainingTime; // remaining time before alarm (in seconds) 65unsigned short currentYearClock; 66char currentMonthClock; 67char currentDayClock; 68char currentMinClock; 69char currentHourClock; 70char currentMinAlarm; 71char currentHourAlarm; 72unsigned char currentDurationAlarm; 73boolean adjustDST(RtcDateTime& time_) { 74 // ********************* Calculate offset for Sunday ********************* 75 boolean DST; 76 int y = time_.Year(); // DS3231 uses two digit year (required here) 77 int x = (y + y / 4 + 2) % 7; // remainder will identify which day of month 78 // is Sunday by subtracting x from the one 79 // or two week window. First two weeks for March 80 // and first week for November 81 // *********** Test DST: BEGINS on 2nd Sunday of March @ 2:00 AM ********* 82 if (time_.Month() == 3 && time_.Day() == (14 - x) && time_.Hour() >= 2) 83 { 84 DST = true; // Daylight Savings Time is TRUE (add one hour) 85 } 86 if ((time_.Month() == 3 && time_.Day() > (14 - x)) || time_.Month() > 3) 87 { 88 DST = true; 89 } 90 // ************* Test DST: ENDS on 1st Sunday of Nov @ 2:00 AM ************ 91 if (time_.Month() == 11 && time_.Day() == (7 - x) && time_.Hour() >= 2) 92 { 93 DST = false; // daylight savings time is FALSE (Standard time) 94 } 95 if ((time_.Month() == 11 && time_.Day() > (7 - x)) || time_.Month() > 11 || time_.Month() < 3) 96 { 97 DST = false; 98 } 99 if (DST == true) // Test DST and add one hour if = 1 (TRUE) 100 { 101 time_ = time_ + 3600; 102 } 103 return DST; 104} 105void displayInfo(char info[]) { 106 // ********************* Displays a text string ********************* 107 display.clearDisplay(); 108 display.setTextSize(2); // 2:1 pixel scale 109 display.setTextColor(WHITE); // Draw white text 110 display.setCursor(4 * (10 - strlen(info)), 15); // Centers the text horizontally 111 display.println(info); 112 return; 113} 114void displayInfo(char info[], char info2[]) { 115 // ********************* Displays two strings ********************* 116 display.clearDisplay(); 117 display.setTextSize(2); // 2:1 pixel scale 118 display.setTextColor(WHITE); // Draw white text 119 display.setCursor(4 * (10 - strlen(info)), 15); // Centers the text horizontally 120 display.println(info); 121 display.setTextSize(1); // Normal 1:1 pixel scale 122 display.setCursor(4 * (10 - strlen(info)), 0); // Centers the text horizontally 123 display.println(info2); 124 return; 125} 126void displayInfo(char info[], char info2[], const unsigned char *picture) { 127 // ********************* Displays two strings and a picture ********************* 128 displayInfo(info,info2); 129 display.drawBitmap( 130 (display.width() - 16 - 10 ), 131 (display.height() - 16 - 8), 132 picture, 16, 16, 1); 133 return; 134} 135void displayInfo(char info[], const unsigned char *picture) { 136 // ********************* Displays one string and a picture ********************* 137 displayInfo(info); 138 display.drawBitmap( 139 (display.width() - 16 - 10 ), 140 (display.height() - 16 - 8), 141 picture, 16, 16, 1); 142 return; 143} 144void displayInfo(char info[], short blink_index[]) { 145 // ********************* Displays a string and blinks specified digits ********************* 146 char info_cp[20]; 147 strcpy(info_cp, info); 148 if ((millis() % BLINK_DURATION) > BLINK_DURATION / 2) { 149 for (int i = blink_index[0]; i <= blink_index[1]; i++) 150 info_cp[i] = ' '; // to blink we replace temporarily the digits with spaces 151 } 152 displayInfo(info_cp); 153} 154void displayInfo(char info[], const unsigned char *picture, short blink_index[]) { 155 // ********************* Displays a string, a picture and blinks specified digits ********************* 156 displayInfo(info, blink_index); 157 display.drawBitmap( 158 (display.width() - 16 - 10 ), 159 (display.height() - 16 - 8), 160 picture, 16, 16, 1); 161} 162void welcome(){ 163 display.clearDisplay(); 164 for (int posx = 0; posx <= 128 - 32; posx += 8) { 165 display.drawBitmap( 166 (posx), 167 (0), 168 smiley, 32, 32, 1); 169 display.display(); 170 delay(100); 171 display.clearDisplay(); 172 } 173 for (int posx = 128 - 32; posx >= 0; posx -= 8) { 174 display.drawBitmap( 175 (posx), 176 (0), 177 smiley, 32, 32, 1); 178 display.display(); 179 delay(100); 180 display.clearDisplay(); 181 } 182 delay(2000); 183} 184unsigned char readButtons_setTime() { 185 // ********************* Reads the two buttons in the set time context ********************* 186 unsigned char button_press = 0; 187 // Possibilities are 00 : None - None, 10 : Press - None, 01 : None - Press, 11 : Press - Press 188 ////////////////////////////////////////////////////////// 189 // Read buttons 190 if (digitalRead(BUTTON_L) == LOW && digitalRead(BUTTON_R) == LOW) { 191 button_press = 11; 192 } 193 else if (digitalRead(BUTTON_L) == LOW) { 194 button_press = 10; 195 } 196 else if (digitalRead(BUTTON_R) == LOW) { 197 button_press = 1; 198 } 199 else { 200 button_press = 0; 201 } 202 ////////////////////////////////////////////////////////// 203 return button_press; 204} 205unsigned char readButtons() { 206 // ********************* Reads the two buttons in the standard menu context ********************* 207 unsigned char button_press = 0; 208 // Possibilities are 00 : None - None, 01 : None - ShortPress, 10 : ShortPress - None, 209 // 11 : ShortPress - ShortPress, 02 : None - LongPress, 20 : LongPress - None, 22 : LongPress - LongPress 210 ////////////////////////////////////////////////////////// 211 // Read buttons 212 if (digitalRead(BUTTON_L) == LOW) { 213 if (buttonActive == false) { 214 buttonActive = true; 215 buttonTimer = millis(); 216 } 217 button1Active = true; 218 } 219 if (digitalRead(BUTTON_R) == LOW) { 220 if (buttonActive == false) { 221 buttonActive = true; 222 buttonTimer = millis(); 223 } 224 button2Active = true; 225 } 226 if ((buttonActive == true) && ((unsigned long)(millis() - buttonTimer) > BUTTON_TIME) && (longPressActive == false)) { 227 longPressActive = true; 228 if ((button1Active == true) && (button2Active == true)) { 229 button_press = 22; 230 } else if ((button1Active == true) && (button2Active == false)) { 231 button_press = 20; 232 } else { 233 button_press = 2; 234 } 235 } 236 if ((buttonActive == true) && (digitalRead(BUTTON_L) == HIGH) && (digitalRead(BUTTON_R) == HIGH)) { 237 if (longPressActive == true) { 238 longPressActive = false; 239 } else { 240 if ((button1Active == true) && (button2Active == true)) { 241 button_press = 11; 242 } else if ((button1Active == true) && (button2Active == false)) { 243 button_press = 10; 244 } else { 245 button_press = 1; 246 } 247 } 248 buttonActive = false; 249 button1Active = false; 250 button2Active = false; 251 } 252 return button_press; 253} 254void setup() { 255 // Setup code that is run only once 256 //Serial.begin(9600); //Starts serial connection 257 //Serial.setTimeout(2000); 258 pinMode(BUTTON_LED_OUT, OUTPUT); // Controls button led brightness 259 pinMode(FET_OUT, OUTPUT); // Controls main led brightness 260 analogWrite(FET_OUT, 0); // turn off main led 261 pinMode(BUTTON_R, INPUT_PULLUP); // Input right button 262 pinMode(BUTTON_L, INPUT_PULLUP); // Input left button 263 // Initialize RTC module 264 rtcObject.Begin(); //Starts I2C 265 // Retrieve user specifications from EEPROM 266 if (EEPROM.read(0) == 126) { // Indicates that it has been written already 267 currentHourAlarm = EEPROM.read(1); 268 currentMinAlarm = EEPROM.read(2); 269 currentDurationAlarm = EEPROM.read(3); 270 } 271 else { // Set defaults, since nothing in memory 272 currentHourAlarm = 7; 273 currentMinAlarm = 30; 274 currentDurationAlarm = 30; 275 } 276 currentMenu = 0; // start with menu zero 277 // Start small welcoming animation (smiley) 278 welcome(); 279} 280void setDuration(unsigned char& curDuration) { 281 // ********************* Sets the duration of the alarm ********************* 282 unsigned char button_press = readButtons_setTime(); // Read buttons 283 // Left button => decrease value, right button => increase value 284 // Both buttons => Accept value and pursue 285 if (button_press == 1) { 286 curDuration += 1; 287 } 288 else if (button_press == 10) { 289 curDuration -= 1; 290 } 291 else if (button_press == 11) { 292 currentMenu = 0; // Return to main menu 293 updateAlarm = true; //Flag to inform that alarm has been updated 294 } 295 // Display current duration value and hourglass image 296 char str[3]; //declare a string as an array of chars 297 sprintf(str, "%d", //%d allows to print an integer to the string 298 curDuration); 299 if (displayOn) { 300 displayInfo(str, hourglass); 301 display.display(); 302 } 303 return; 304} 305void setDate(unsigned short& curYear, char& curMonth, char& curDay) { 306 // ********************* Sets the current date ********************* 307 short blink_index[2]; // will be updated 308 unsigned char button_press = readButtons_setTime(); // Read buttons 309 if (choice == 'y') { // year setup step 310 blink_index[0] = 0; //blink from digit 0 311 blink_index[1] = 3; // to digit 3 312 if (button_press == 1) { 313 curYear += 1; 314 } 315 else if (button_press == 10) { 316 curYear -= 1; 317 } 318 else if (button_press == 11) { 319 choice = 'm'; // jump to month setup step 320 delay(1000); // wait a bit to avoid fast clicks 321 } 322 } 323 else if (choice == 'm') { // month setup step 324 blink_index[0] = 5; //blink from digit 5 325 blink_index[1] = 6; // to digit 6 326 if (button_press == 1) { 327 curMonth += 1; 328 if (curMonth > 12) { 329 curMonth = 1; // avoid month > 12 330 } 331 } 332 else if (button_press == 10) { 333 curMonth -= 1; 334 if (curMonth < 1) { 335 curMonth = 12; // avoid month < 1 336 } 337 } 338 else if (button_press == 11) { 339 choice = 'd'; // jump to day setup step 340 delay(1000); // wait a bit to avoid fast clicks 341 } 342 } 343 else if (choice == 'd') { 344 blink_index[0] = 8; //blink from digit 8 345 blink_index[1] = 9; // to digit 9 346 if (button_press == 1) { 347 curDay += 1; 348 if (curDay > daysPerMonth[curMonth]) { 349 curDay = 1; // avoid impossible day 350 } 351 } 352 else if (button_press == 10) { 353 curDay -= 1; 354 if (curDay < 1) { 355 curDay = 1; // avoid day < 1 356 } 357 } 358 else if (button_press == 11) { 359 choice = 'h'; // jump to hour setup step 360 delay(1000); // wait a bit to avoid fast clicks 361 currentMenu = 2; // go to menu 2 (time setup) 362 } 363 } 364 // Create date string in the format YYYY-MM-DD, ex. 2019-06-30 365 char str[11]; //declare a string as an array of chars 366 sprintf(str, "%04d-%02d-%02d", //%d allows to print an integer to the string 367 curYear, 368 curMonth, 369 curDay 370 ); 371 if (displayOn) { 372 displayInfo(str, blink_index); 373 display.display(); 374 } 375 return; 376} 377void setTime(char& curHour, char& curMin, boolean setAlarm = false) { 378 short blink_index[2]; 379 unsigned char button_press = readButtons_setTime(); 380 if (choice == 'h') { 381 blink_index[0] = 0; 382 blink_index[1] = 1; 383 if (button_press == 1) { 384 curHour += 1; 385 if (curHour > 23) { 386 curHour = 0; 387 } 388 } 389 else if (button_press == 10) { 390 curHour -= 1; 391 if (curHour < 0) { 392 curHour = 23; 393 } 394 } 395 else if (button_press == 11) { 396 choice = 'm'; 397 delay(1000); 398 } 399 } 400 else if (choice == 'm') { 401 blink_index[0] = 3; 402 blink_index[1] = 4; 403 if (button_press == 1) { 404 curMin += 1; 405 if (curMin > 59) { 406 curMin = 0; 407 } 408 } 409 else if (button_press == 10) { 410 curMin -= 1; 411 if (curMin < 0) { 412 curMin = 59; 413 } 414 } 415 else if (button_press == 11) { 416 if (setAlarm) { 417 currentMenu = 4; 418 } 419 else { 420 updateTime = true; 421 currentMenu = 0; 422 } 423 } 424 } 425 char str[11]; //declare a string as an array of chars 426 sprintf(str, "%02d:%02d", //%d allows to print an integer to the string 427 curHour, //get hour method 428 curMin //get minute method 429 ); 430 if (displayOn) { 431 displayInfo(str, clockhour, blink_index); 432 display.display(); 433 } 434 return; 435} 436void loop() { 437 // Main code that is run repeatedly 438 // ADJUSTING TIME AND ALARM 439 //-------------------------------- 440 // Start by updating RTC module if new time has been chosen 441 if (updateTime) { 442 RtcDateTime currentTime = RtcDateTime(currentYearClock, currentMonthClock, currentDayClock, 443 currentHourClock, currentMinClock, 0); //define date and time object 444 if (isDST) { // correct for DST if needed 445 currentTime -= 3600; 446 } 447 rtcObject.SetDateTime(currentTime); 448 updateTime = false; 449 } 450 // Also update alarm in EEPROM if new alarm setup has been chosen 451 if (updateAlarm) { 452 EEPROM.write(1, currentHourAlarm); 453 EEPROM.write(2, currentMinAlarm); 454 EEPROM.write(3, currentDurationAlarm); 455 updateAlarm = false; 456 } 457 // ADJUSTING BUTTON LED AND OLED BRIGHTNESS 458 //-------------------------------- 459 // Now we read the value of the button led pot 460 // We get average of 5 measurements 461 int niter = 5; 462 float potLevel = 0; 463 for (int i = 0; i < niter; i++) { 464 potLevel += float(analogRead(POT_IN)); 465 delay(5); 466 } 467 potLevel /= niter; 468 // Normalize pot level between 0 and 1 469 float level = (float)potLevel / 1023.; 470 level = pow(level, 2); // Use power of two to get more smooth transition 471 // if pot level below a certain value, we disable oled screen 472 if (level < 0.02) { 473 displayOn = false; 474 } 475 else { 476 displayOn = true; 477 } 478 // Finally set button led brightness value 479 analogWrite(BUTTON_LED_OUT, int(level * 255)); 480 // Also control OLED brightness (doesn't work very well) 481 display.ssd1306_command(0x81); 482 display.ssd1306_command(int(level * 160)); //max 160 483 display.ssd1306_command(0xD9); 484 display.ssd1306_command(int(level * 34)); //max 34 485 // MANAGE ALARM 486 //-------------------------------- 487 RtcDateTime currentTime = rtcObject.GetDateTime(); //get the time from the RTC 488 // COrrect for daylight saving time 489 isDST = adjustDST(currentTime); // Get DST 490 if (currentMenu != 1 && currentMenu != 2) { // menu 1 and 2 set the date and time manually, so don't update from RTC 491 currentYearClock = currentTime.Year(); 492 currentMonthClock = currentTime.Month(); 493 currentDayClock = currentTime.Day(); 494 currentHourClock = currentTime.Hour(); 495 currentMinClock = currentTime.Minute(); 496 } 497 // Compute remaining time until alarm starts in seconds 498 remainingTime = 3600L * (int(currentHourAlarm) - int(currentHourClock)) + 60L * (int(currentMinAlarm) - int(currentMinClock)) - int(currentTime.Second()); 499 if (remainingTime < 0) { 500 remainingTime += (24 * 3600L); 501 } 502 // Alarm starts only if time until specified alarm time is less than specified duration 503 // and in main menu (user is not changing settings) and alarm is enabled 504 if ((remainingTime < currentDurationAlarm * 60 && currentMenu == 0 && alarmEnabled)) { 505 //Start to light the led 506 float level = 1. - float(remainingTime) / (60 * currentDurationAlarm); // fraction of time remaining until alarm 507 level = 255 * pow(level, 2); // power of 2 for smoother transition 508 if (level < 1) { 509 level = 1; // ensure minimal brightness 510 } 511 analogWrite(FET_OUT, level); 512 alarmRunning = true; 513 } 514 else { // if alarm is running continue to light LED at max brightness even after alarm time has passed 515 // (it makes no sense to stop it immediately as person might not yet have woken up) 516 if (alarmRunning) { 517 analogWrite(FET_OUT, 255); 518 } 519 } 520 // MANAGE MENUS 521 //-------------------------------- 522 if (currentMenu == 0) { 523 // Main menu 524 unsigned char buttonPress = readButtons(); 525 // 4 possibilities 526 if (buttonPress == 10) { // short press left 527 // Toggle on/off light 528 if (mainLightOn) { 529 analogWrite(FET_OUT, 0); 530 mainLightOn = false; 531 } 532 else { 533 analogWrite(FET_OUT, 255); 534 mainLightOn = true; 535 } 536 } 537 else if (buttonPress == 1 ) { // short press right 538 // Toggle on/off alarm 539 if (alarmEnabled) { 540 alarmEnabled = false; 541 // turn off lamp 542 analogWrite(FET_OUT, 0); 543 } 544 else { 545 alarmEnabled = true; 546 } 547 } 548 else if (buttonPress == 20) { // long press left 549 // Jump into date selection menu 550 choice = 'y'; // Start with year selection 551 delay(1000); 552 currentMenu = 1; 553 } 554 else if (buttonPress == 2) { // short press right 555 // Jump into alarm selection menu 556 choice = 'h'; // Start with hour 557 currentMenu = 3; 558 delay(1000); 559 } 560 // DISPLAY INFO 561 //-------------------------------- 562 char str[5]; //declare a string as an array of chars 563 sprintf(str, "%02d:%02d", //%d allows to print an integer to the string 564 currentTime.Hour(), //get hour method 565 currentTime.Minute()); 566 if (displayOn) { 567 if (alarmEnabled) {// time + bell image 568 char str2[5]; //declare a string as an array of chars 569 sprintf(str2, "%02d:%02d", //%d allows to print an integer to the string 570 currentHourAlarm, //get hour method 571 currentMinAlarm //get minute method 572 ); 573 displayInfo(str, str2, bell); 574 } 575 else {// only time 576 displayInfo(str); 577 } 578 } 579 else { // Display empty string to show nothing on screen 580 displayInfo(""); 581 } 582 display.display(); 583 // UPDATE USER CHANGES 584 //-------------------------------- 585 if (updateTime) { // set new time on RTC 586 RtcDateTime currentTime = RtcDateTime(currentYearClock, currentMonthClock, currentDayClock, 587 currentHourClock, currentMinClock, 0); //define date and time object 588 if (isDST) { 589 currentTime -= 3600; 590 } 591 rtcObject.SetDateTime(currentTime); 592 updateTime = false; 593 } 594 if (updateAlarm) { // write alarm setup in EEPROM 595 EEPROM.write(1, currentHourAlarm); 596 EEPROM.write(2, currentMinAlarm); 597 EEPROM.write(3, currentDurationAlarm); 598 updateAlarm = false; 599 } 600 if (!alarmEnabled) { 601 // turn off alarm if it is started 602 if (alarmRunning) { 603 alarmRunning = false; 604 } 605 } 606 } 607 // THINGS TO DO IN OTHER MENUS 608 //-------------------------------- 609 else if (currentMenu == 1) { 610 // set clock 611 setDate(currentYearClock, currentMonthClock, currentDayClock); 612 } 613 else if (currentMenu == 2) { 614 setTime(currentHourClock, currentMinClock, false); 615 } 616 else if (currentMenu == 3) { 617 setTime(currentHourAlarm, currentMinAlarm, true); 618 } 619 else if (currentMenu == 4) { 620 setDuration(currentDurationAlarm); 621 } 622 delay(200); 623}
Downloadable files
Electrical diagram
Electrical diagram
Electrical diagram
Electrical diagram
Comments
Only logged in users can leave comments
Anonymous user
3 years ago
Overall a nice project, but there are some errors. In order to get this thing working here are some additions. 1) global variables are missing, add the following lines to //Initialize Flags: Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); RtcDS3231<TwoWire> rtcObject(Wire); 2) Initialization of display is missing, add the following lines to setup(), screen_address is the I2C slave address of the display: if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { Serial.println(F("SSD1306 allocation failed")); for(;;); // Don't proceed, loop forever } 3) In the schematic: swap source and drain of the N-channel MOSFET 4) 78XX is not a buck-down regulator. You can also directly connect the 12V power supply to VIN of arduino. 5) Connect the gate of the N-Channel MOSFET to D9 of arduino, A6 is not a PWM output. 6) The schematic is missing the display, connect SDA and SCL of Display to A5 and A6.