/**************************************************************************//** * \brief Arduino clock. * \author Copyright (C) 2012 Julien Le Sech - www.idreammicro.com * \version 1.0 * \date 20120428 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses. ******************************************************************************/ /**************************************************************************//** * \file clock.ino ******************************************************************************/ /****************************************************************************** * Header file inclusions. ******************************************************************************/ #include "Keyboard.h" #include #include #include #include #include /****************************************************************************** * Private macro definitions. ******************************************************************************/ #define CLOCK__DAY_MIN 1 #define CLOCK__DAY_MAX 31 #define CLOCK__MONTH_MIN 1 #define CLOCK__MONTH_MAX 12 #define CLOCK__YEAR_MIN 2000 #define CLOCK__YEAR_MAX 2099 #define CLOCK__HOUR_MIN 0 #define CLOCK__HOUR_MAX 23 #define CLOCK__MINUTE_MIN 0 #define CLOCK__MINUTE_MAX 59 #define CLOCK__SECOND_MIN 0 #define CLOCK__SECOND_MAX 59 /****************************************************************************** * Private type definitions. ******************************************************************************/ /**************************************************************************//** * \enum clock__members * \brief * * \type clock__member_t * \brief ******************************************************************************/ typedef enum clock__members { clock__MemberDay, clock__MemberMonth, clock__MemberYear, clock__MemberHour, clock__MemberMinute, clock__MemberSecond } clock__member_t; /****************************************************************************** * Private function prototypes. ******************************************************************************/ /**************************************************************************//** * \fn static void clock__handleKey(Keyboard::Key_t key) * * \brief Handle pressed key. * * \param key Pressed key. ******************************************************************************/ static void clock__handleKey ( Keyboard::Key_t key ); /**************************************************************************//** * \fn static void clock__setCursor() * * \brief Set cursor position. ******************************************************************************/ static void clock__setCursor(); /**************************************************************************//** * \fn static clock__incrementMember() * * \brief Increment current member: day, month, year, hour, minute or second. ******************************************************************************/ static void clock__incrementMember(); /**************************************************************************//** * \fn static void clock__decrementMember() * * \brief Decrement current member: day, month, year, hour, minute or second. ******************************************************************************/ static void clock__decrementMember(); /**************************************************************************//** * \fn static void clock__printDatetime() * * \brief Print current datetime. ******************************************************************************/ static void clock__printDatetime(); /****************************************************************************** * Private variable declarations. ******************************************************************************/ static Deuligne clock__lcd; static RTC_DS1307 clock__rtc; static DateTime clock__currentTime; static bool clock__adjustMode = false; static clock__member_t clock__currentMember = clock__MemberDay; /****************************************************************************** * Public function definitions. ******************************************************************************/ /**************************************************************************//** * \fn void setup() * * \brief System initialization. ******************************************************************************/ void setup() { // Initialize TWI bus. Wire.begin(); // Initialize RTC. clock__rtc.begin(); // Initialize LCD. clock__lcd.init(); clock__lcd.clear(); clock__lcd.backLight(true); // Get current time and print it. clock__currentTime = clock__rtc.now(); clock__printDatetime(); } /**************************************************************************//** * \fn void loop() * * \brief Infinite loop. ******************************************************************************/ void loop() { // Get pressed key and process it. Keyboard::Key_t key = (Keyboard::Key_t)(clock__lcd.get_key()); if (key > Keyboard::KeyNone) { clock__handleKey(key); } // If we aren't in adjust mode, get current time and print it. if (!clock__adjustMode) { clock__currentTime = clock__rtc.now(); clock__printDatetime(); } delay(200); } /****************************************************************************** * Private function definitions. ******************************************************************************/ /**************************************************************************//** * \fn static void clock__handleKey(Keyboard::Key_t key) * * \brief Handle pressed key. * * \param key Pressed key. ******************************************************************************/ static void clock__handleKey ( Keyboard::Key_t key ){ switch (key) { case Keyboard::KeyRight: { if (clock__adjustMode) { if (clock__currentMember < clock__MemberSecond) { byte tmpMember = (byte)clock__currentMember; tmpMember++; clock__currentMember = (clock__member_t)tmpMember; } else { clock__currentMember = clock__MemberDay; } clock__setCursor(); } } break; case Keyboard::KeyUp: { if (clock__adjustMode) { clock__incrementMember(); clock__setCursor(); } } break; case Keyboard::KeyDown: { if (clock__adjustMode) { clock__decrementMember(); clock__setCursor(); } } break; case Keyboard::KeyLeft: { if (clock__adjustMode) { if (clock__currentMember > clock__MemberDay) { byte tmpMember = (byte)clock__currentMember; tmpMember--; clock__currentMember = (clock__member_t)tmpMember; } else { clock__currentMember = clock__MemberSecond; } clock__setCursor(); } } break; case Keyboard::KeySelect: { if (clock__adjustMode) { // If we are in adjust mode, update RTC time. clock__rtc.adjust(clock__currentTime); clock__lcd.noBlink(); clock__lcd.noCursor(); clock__currentMember = clock__MemberDay; clock__adjustMode = false; } else { // Enter adjust mode. clock__adjustMode = true; clock__lcd.setCursor(1, 0); clock__lcd.blink(); clock__lcd.cursor(); } } break; case Keyboard::KeyNone: case Keyboard::KeyInvalid: default: break; } } /**************************************************************************//** * \fn static void clock__setCursor() * * \brief Set cursor position. ******************************************************************************/ static void clock__setCursor() { switch (clock__currentMember) { case clock__MemberDay: clock__lcd.setCursor(1, 0); break; case clock__MemberMonth: clock__lcd.setCursor(4, 0); break; case clock__MemberYear: clock__lcd.setCursor(9, 0); break; case clock__MemberHour: clock__lcd.setCursor(1, 1); break; case clock__MemberMinute: clock__lcd.setCursor(4, 1); break; case clock__MemberSecond: clock__lcd.setCursor(7, 1); break; default: break; } } /**************************************************************************//** * \fn static void clock__incrementMember() * * \brief Increment current member: day, month, year, hour, minute or second. ******************************************************************************/ static void clock__incrementMember() { switch (clock__currentMember) { case clock__MemberDay: { byte day = clock__currentTime.day(); day = (day + 1 <= CLOCK__DAY_MAX) ? (day + 1) : CLOCK__DAY_MIN; clock__currentTime.setDay(day); } break; case clock__MemberMonth: { byte month = clock__currentTime.month(); month = (month + 1 <= CLOCK__MONTH_MAX) ? (month + 1) : CLOCK__MONTH_MIN; clock__currentTime.setMonth(month); } break; case clock__MemberYear: { word year = clock__currentTime.year(); year = (year + 1 <= CLOCK__YEAR_MAX) ? (year + 1) : CLOCK__YEAR_MIN; clock__currentTime.setYear(year); } break; case clock__MemberHour: { byte hour = clock__currentTime.hour(); hour = (hour + 1 <= CLOCK__HOUR_MAX) ? (hour + 1) : CLOCK__HOUR_MIN; clock__currentTime.setHour(hour); } break; case clock__MemberMinute: { byte minute = clock__currentTime.minute(); minute = (minute + 1 <= CLOCK__MINUTE_MAX) ? (minute + 1) : CLOCK__MINUTE_MIN; clock__currentTime.setMinute(minute); } break; case clock__MemberSecond: { byte second = clock__currentTime.second(); second = (second + 1 <= CLOCK__SECOND_MAX) ? (second + 1) : CLOCK__SECOND_MIN; clock__currentTime.setSecond(second); } break; default: break; } clock__printDatetime(); } /**************************************************************************//** * \fn static void clock__decrementMember() * * \brief Decrement current member: day, month, year, hour, minute or second. ******************************************************************************/ static void clock__decrementMember() { switch (clock__currentMember) { case clock__MemberDay: { byte day = clock__currentTime.day(); day = (day - 1 >= CLOCK__DAY_MIN) ? (day - 1) : CLOCK__DAY_MAX; clock__currentTime.setDay(day); } break; case clock__MemberMonth: { byte month = clock__currentTime.month(); month = (month - 1 >= CLOCK__MONTH_MIN) ? (month - 1) : CLOCK__MONTH_MAX; clock__currentTime.setMonth(month); } break; case clock__MemberYear: { word year = clock__currentTime.year(); year = (year - 1 >= CLOCK__YEAR_MIN) ? (year - 1) : CLOCK__YEAR_MAX; clock__currentTime.setYear(year); } break; case clock__MemberHour: { byte hour = clock__currentTime.hour(); hour = (hour - 1 >= CLOCK__HOUR_MIN) ? (hour - 1) : CLOCK__HOUR_MIN; clock__currentTime.setHour(hour); } break; case clock__MemberMinute: { byte minute = clock__currentTime.minute(); minute = (minute - 1 >= CLOCK__MINUTE_MIN) ? (minute - 1) : CLOCK__MINUTE_MAX; clock__currentTime.setMinute(minute); } break; case clock__MemberSecond: { byte second = clock__currentTime.second(); second = (second - 1 >= CLOCK__SECOND_MIN) ? (second - 1) : CLOCK__SECOND_MAX; clock__currentTime.setSecond(second); } break; default: break; } clock__printDatetime(); } /**************************************************************************//** * \fn static void clock__printDatetime() * * \brief Print current datetime. ******************************************************************************/ static void clock__printDatetime() { // Build date string. char date[] = "01/01/2000"; snprintf ( date, strlen(date) + 1, "%02d/%02d/%04d", clock__currentTime.day(), clock__currentTime.month(), clock__currentTime.year() ); // Build time string. char time[] = "00:00:00"; snprintf ( time, strlen(time) + 1, "%02d:%02d:%02d", clock__currentTime.hour(), clock__currentTime.minute(), clock__currentTime.second() ); // Print date. clock__lcd.setCursor(0, 0); clock__lcd.print(date); // Print time. clock__lcd.setCursor(0, 1); clock__lcd.print(time); }