Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
/**************************************************************************//*** \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 <Deuligne.h>#include <RTClib.h>#include <Arduino.h>#include <Wire.h>#include <stdio.h>/******************************************************************************* 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.******************************************************************************/staticvoidclock__handleKey(Keyboard::Key_t key);/**************************************************************************//*** \fn static void clock__setCursor()** \brief Set cursor position.******************************************************************************/staticvoidclock__setCursor();/**************************************************************************//*** \fn static clock__incrementMember()** \brief Increment current member: day, month, year, hour, minute or second.******************************************************************************/staticvoidclock__incrementMember();/**************************************************************************//*** \fn static void clock__decrementMember()** \brief Decrement current member: day, month, year, hour, minute or second.******************************************************************************/staticvoidclock__decrementMember();/**************************************************************************//*** \fn static void clock__printDatetime()** \brief Print current datetime.******************************************************************************/staticvoidclock__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.******************************************************************************/staticvoidclock__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.******************************************************************************/staticvoidclock__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.******************************************************************************/staticvoidclock__incrementMember(){switch (clock__currentMember){case clock__MemberDay:{byte day = clock__currentTime.day();day = (day + 1 <= CLOCK__DAY_MAX) ? (day + 1) : CLOCK__DAY_MIN;DateTime tempTime(clock__currentTime.year(),clock__currentTime.month(),day,clock__currentTime.hour(),clock__currentTime.minute(),clock__currentTime.second());clock__currentTime = tempTime;}break;case clock__MemberMonth:{byte month = clock__currentTime.month();month = (month + 1 <= CLOCK__MONTH_MAX) ? (month + 1) : CLOCK__MONTH_MIN;DateTime tempTime(clock__currentTime.year(),month,clock__currentTime.day(),clock__currentTime.hour(),clock__currentTime.minute(),clock__currentTime.second());clock__currentTime = tempTime;}break;case clock__MemberYear:{word year = clock__currentTime.year();year = (year + 1 <= CLOCK__YEAR_MAX) ? (year + 1) : CLOCK__YEAR_MIN;DateTime tempTime(year,clock__currentTime.month(),clock__currentTime.day(),clock__currentTime.hour(),clock__currentTime.minute(),clock__currentTime.second());clock__currentTime = tempTime;}break;case clock__MemberHour:{byte hour = clock__currentTime.hour();hour = (hour + 1 <= CLOCK__HOUR_MAX) ? (hour + 1) : CLOCK__HOUR_MIN;DateTime tempTime(clock__currentTime.year(),clock__currentTime.month(),clock__currentTime.day(),hour,clock__currentTime.minute(),clock__currentTime.second());clock__currentTime = tempTime;}break;case clock__MemberMinute:{byte minute = clock__currentTime.minute();minute = (minute + 1 <= CLOCK__MINUTE_MAX) ? (minute + 1) : CLOCK__MINUTE_MIN;DateTime tempTime(clock__currentTime.year(),clock__currentTime.month(),clock__currentTime.day(),clock__currentTime.hour(),minute,clock__currentTime.second());clock__currentTime = tempTime;}break;case clock__MemberSecond:{byte second = clock__currentTime.second();second = (second + 1 <= CLOCK__SECOND_MAX) ? (second + 1) : CLOCK__SECOND_MIN;DateTime tempTime(clock__currentTime.year(),clock__currentTime.month(),clock__currentTime.day(),clock__currentTime.hour(),clock__currentTime.minute(),second);clock__currentTime = tempTime;}break;default:break;}clock__printDatetime();}/**************************************************************************//*** \fn static void clock__decrementMember()** \brief Decrement current member: day, month, year, hour, minute or second.******************************************************************************/staticvoidclock__decrementMember(){switch (clock__currentMember){case clock__MemberDay:{byte day = clock__currentTime.day();day = (day - 1 >= CLOCK__DAY_MIN) ? (day - 1) : CLOCK__DAY_MAX;DateTime tempTime(clock__currentTime.year(),clock__currentTime.month(),day,clock__currentTime.hour(),clock__currentTime.minute(),clock__currentTime.second());clock__currentTime = tempTime;}break;case clock__MemberMonth:{byte month = clock__currentTime.month();month = (month - 1 >= CLOCK__MONTH_MIN) ? (month - 1) : CLOCK__MONTH_MAX;DateTime tempTime(clock__currentTime.year(),month,clock__currentTime.day(),clock__currentTime.hour(),clock__currentTime.minute(),clock__currentTime.second());clock__currentTime = tempTime;}break;case clock__MemberYear:{word year = clock__currentTime.year();year = (year - 1 >= CLOCK__YEAR_MIN) ? (year - 1) : CLOCK__YEAR_MAX;DateTime tempTime(year,clock__currentTime.month(),clock__currentTime.day(),clock__currentTime.hour(),clock__currentTime.minute(),clock__currentTime.second());clock__currentTime = tempTime;}break;case clock__MemberHour:{byte hour = clock__currentTime.hour();hour = (hour - 1 >= CLOCK__HOUR_MIN) ? (hour - 1) : CLOCK__HOUR_MIN;DateTime tempTime(clock__currentTime.year(),clock__currentTime.month(),clock__currentTime.day(),hour,clock__currentTime.minute(),clock__currentTime.second());clock__currentTime = tempTime;}break;case clock__MemberMinute:{byte minute = clock__currentTime.minute();minute = (minute - 1 >= CLOCK__MINUTE_MIN) ? (minute - 1) : CLOCK__MINUTE_MAX;DateTime tempTime(clock__currentTime.year(),clock__currentTime.month(),clock__currentTime.day(),clock__currentTime.hour(),minute,clock__currentTime.second());clock__currentTime = tempTime;}break;case clock__MemberSecond:{byte second = clock__currentTime.second();second = (second - 1 >= CLOCK__SECOND_MIN) ? (second - 1) : CLOCK__SECOND_MAX;DateTime tempTime(clock__currentTime.year(),clock__currentTime.month(),clock__currentTime.day(),clock__currentTime.hour(),clock__currentTime.minute(),second);clock__currentTime = tempTime;}break;default:break;}clock__printDatetime();}/**************************************************************************//*** \fn static void clock__printDatetime()** \brief Print current datetime.******************************************************************************/staticvoidclock__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);}