#include <RTClib.h>
#include <tm1637.h>
#include <Wire.h>
RTC_DS3231 rtc;
DateTime NOW;
bool timedOut;
bool modeClock;
bool modeTimer;
bool modeDateClock;
bool timerRunning;// use for pausing timer
uint8_t button1 = 11;// Pin Definitions
uint8_t button2 = 10;
uint8_t button3 = 9;
uint8_t led0 = 2;
uint8_t led1 = 3;
uint8_t led2 = 4;
uint8_t led3 = 5;
uint8_t ldr = A7;
uint8_t ledPWMPin = 6;
const int AM = 1;// Constants to set indicator LEDs to AM or PM or OFF (led0 = AM, led3=PM)
const int PM = 5;
const int NONE = 0;
uint8_t MONTHx = 0;// Field editing flags for setting clock
uint8_t DAYx = 1;
uint8_t YEARx = 2;
uint8_t DAYofWEEKx = 3;
uint8_t HOURx = 4;
uint8_t MINUTEx = 5;
long lapStartMillis;// Timer Lap Start Value
long totalMillis;// Timer Lapsed Time Count
uint8_t brightness;
bool clockMode_12 = true;
bool leadingZero = false;
char dspVal[8];// Char array to store values to be sent to display
void setup() {
Serial.begin(9600);
timedOut = false;
if (! rtc.begin()) {// start RTC module communication
Serial.println("Couldn't find RTC");
//while (1);
}
if (rtc.lostPower()) {// This will initialize clock setting after battery change etc. when clock HAS NOT been set
Serial.println("RTC needs set!");
// following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
// rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}
pinMode(button1, INPUT_PULLUP);
pinMode(button2, INPUT_PULLUP);
pinMode(button3, INPUT_PULLUP);
pinMode(led0, OUTPUT);
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(ledPWMPin, OUTPUT);
digitalWrite(led0, LOW);
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
pinMode(ldr, INPUT);
brightness = 3;
modeClock = true;
NOW = rtc.now();
ledSetBrightness(3);
ledSequence(1);
ledSequence(0);
tm1637Init(7, 8); // clock, data pins of LED Display
tm1637SetBrightness(brightness);
}// ******************************************* End of setup
void ledSequence(int cmd) {
// display short sequences on the LED column.
//Turn all LEDs OFF to start
digitalWrite(led0, LOW);
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
if (cmd) {
digitalWrite(led0, HIGH);
delay(100);
digitalWrite(led1, HIGH);
delay(100);
digitalWrite(led2, HIGH);
delay(100);
digitalWrite(led3, HIGH);
delay(100);
digitalWrite(led0, LOW);
delay(100);
digitalWrite(led1, LOW);
delay(100);
digitalWrite(led2, LOW);
delay(100);
digitalWrite(led3, LOW);
delay(100);
}
else {
digitalWrite(led3, HIGH);
delay(100);
digitalWrite(led2, HIGH);
delay(100);
digitalWrite(led1, HIGH);
delay(100);
digitalWrite(led0, HIGH);
delay(100);
digitalWrite(led3, LOW);
delay(100);
digitalWrite(led2, LOW);
delay(100);
digitalWrite(led1, LOW);
delay(100);
digitalWrite(led0, LOW);
delay(100);
}
}// ******************************************* End of ledSequence
long numberGet(uint8_t myField, int startVal, int maxVal) {
// Get user input for setting clock/timer/etc.
bool gotNumber = false;
//bool timeOut = millis()+10000;
timedOut = false;
int debounce = 30;
char dspTemp[8];
while (!gotNumber) {
NOW = rtc.now();// This is only done here to provide flashing digits when setting.
switch (myField) {
case 0:
if (NOW.second() & 1) {
Serial.println("Setting Month");
sprintf(dspTemp, "%02d ", startVal);
}
else {
sprintf(dspTemp, " : " );
}
break;
case 1://day
Serial.println("Setting Day");
if (NOW.second() & 1) {
sprintf(dspTemp, " %02d", startVal);
}
else {
sprintf(dspTemp, " : " );
}
break;
case 2://year
Serial.println("Setting Year");
if (NOW.second() & 1) {
sprintf(dspTemp, "%02d %02d", startVal / 100, startVal % 100);
}
else {
sprintf(dspTemp, " " );
}
break;
case 4://hour
if (NOW.second() & 1) {
sprintf(dspTemp, "%02d ", startVal);
}
else {
sprintf(dspTemp, " : " );
}
break;
case 5://minute
if (NOW.second() & 1) {
sprintf(dspTemp, " %02d", startVal);
}
else {
sprintf(dspTemp, " : " );
}
break;
}
tm1637ShowDigits(dspTemp);
// Check for button presses here
if (digitalRead(button1) == LOW) {
delay(debounce);
if (digitalRead(button1) == LOW) {
while (digitalRead(button1) == LOW) { // Lets pause until button released
}
}
startVal--;
//timeOut = millis() + 10000;
delay(300);
}
if (digitalRead(button2) == LOW) {
delay(debounce);
if (digitalRead(button2) == LOW) {
while (digitalRead(button2) == LOW) { // Lets pause until button released
}
}
startVal++;
//timeOut = millis() + 10000;
delay(300);
}
if (digitalRead(button3) == LOW) {
delay(debounce);
if (digitalRead(button3) == LOW) {
while (digitalRead(button3) == LOW) { // Lets pause until button released
}
}
gotNumber = true;
if (myField < 5) { // DON'T delay if minutes field is being set.
delay(300);
}
}
}
if (startVal > maxVal) {
startVal = 0;
}
if (startVal < 0) {
startVal = maxVal;
}
return (startVal);
}// ******************************************* End of numberGet
void clockSet() {
bool doneSetting = false;
bool settingMonth = true;
bool settingDay = false;
bool settingWeekDay = false;
bool settingYear = false;
bool settingHours = false;
bool settingMinutes = false;
int myMonth, myDay, myYear, myHour, myMinute;
NOW = rtc.now();
myMonth = NOW.month();
myDay = NOW.day();
myYear = NOW.year();
myHour = NOW.hour();
myMinute = NOW.minute();
Serial.println(myMonth);
Serial.println(myDay);
Serial.println(myYear);
Serial.println(myHour);
Serial.println(myMinute);
while (!doneSetting) {
while (settingMonth & !timedOut) { // Month Set routine here
myMonth = numberGet(MONTHx, myMonth, 12);
settingMonth = false;
settingDay = true;
}
while (settingDay & !timedOut) {
//Day Set Routine here
myDay = numberGet(DAYx, myDay, 31);
settingDay = false;
settingYear = true;
}
while (settingYear & !timedOut) {
// Year Set Routine here
myYear = numberGet(YEARx, myYear, 3000);
settingYear = false;
settingHours = true;
}
while (settingHours & !timedOut) {
// hour Set Routine here
myHour = numberGet(HOURx, myHour, 23);
settingHours = false;
settingMinutes = true;
}
while (settingMinutes & !timedOut) {
// Minute Set Routine here
myMinute = numberGet(MINUTEx, myMinute, 59);
settingMinutes = false;
doneSetting = true;
}
}
if (!timedOut) {
rtc.adjust(DateTime(myYear, myMonth, myDay, myHour, myMinute, 0));
}
timedOut = false;
}// ******************************************* End of clockSet
void ledSet(int setting) {// Set the 4 LEDs that display timer hours count/AM/PM
static int oldSetting;
if (oldSetting != setting) { // only update if setting changes
//Turn all LEDs OFF to start
digitalWrite(led0, LOW);
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
if (setting > 4) { // Display PM indication
digitalWrite(led3, HIGH);
}
else {
if (setting > 3) {
digitalWrite(led3, HIGH);
}
if (setting > 2) {
digitalWrite(led2, HIGH);
}
if (setting > 1) {
digitalWrite(led1, HIGH);
}
if (setting > 0) {
digitalWrite(led0, HIGH);
}
}
oldSetting = setting;
}
}// ******************************************* End of ledSet
void ledSetBrightness(int setting) {
// Setting multipliers were chosen by trial and error, to best match the display brightness settings.
// Other LED/resistor/display combinations may require different values.
Serial.println( setting);
if (setting == 1) {
analogWrite(ledPWMPin, setting * 25);
}
if (setting == 2) {
analogWrite(ledPWMPin, setting * 25);
}
if (setting == 3) {
analogWrite(ledPWMPin, setting * 40);
}
if (setting == 4) {
analogWrite(ledPWMPin, setting * 50);
}
if (setting == 5) {
analogWrite(ledPWMPin, setting * 51);
}
}// ******************************************* End of ledSetBrightness
void showClock() {
NOW = rtc.now();
int myHour = NOW.hour();
bool morning = (myHour < 12); //
int myMin = NOW.minute();
if (myHour > 12) {
myHour -= (12 * clockMode_12); //Displays 12 or 24 hour modes
}
if (NOW.second() & 1) {
ledSet(NONE);
if ((myHour < 10) && clockMode_12 && !leadingZero) {
sprintf(dspVal, " %01d:%02d", myHour, myMin);
}
else {
sprintf(dspVal, "%02d:%02d", myHour, myMin);
}
}
else {
if (morning) {
ledSet(AM);
}
else {
ledSet(PM);
}
if ((myHour < 10) && clockMode_12 && !leadingZero) {
sprintf(dspVal, " %01d %02d", myHour, myMin);
}
else {
sprintf(dspVal, "%02d %02d", myHour, myMin);
}
}
}// ******************************************* End of showClock
void showTimer() {
long currentMillis = totalMillis;
if (timerRunning) {
currentMillis = totalMillis + (millis() - lapStartMillis);
}
currentMillis /= 1000; // convert to seconds
int tmrHours = (currentMillis / 60) / 60;
if (tmrHours > 4) {
tmrHours -= 4;
}
int curMins = (currentMillis / 60) % 60;
int curSecs = currentMillis % 60;
sprintf(dspVal, "%02d:%02d", curMins, curSecs);
ledSet(tmrHours);
}// ******************************************* End of showTImer
void readButtons() {
long holdTimer;
int debounce = 30;
if (digitalRead(button3) == LOW) {
delay(debounce);
if (digitalRead(button3) == LOW) {
holdTimer = millis();
while (digitalRead(button3) == LOW) { // Lets pause until button released
}
if (millis() > holdTimer + 5000) {
Serial.println ("clock Mode Changed");
clockMode_12 = !clockMode_12;
ledSequence(1);
ledSequence(0);
ledSequence(1);
ledSequence(0);
}
else if (millis() > holdTimer + 2300) {
ledSequence(1);
Serial.println("Setting Clock");
clockSet();
}
else {
if (modeClock) {
modeTimer = true;
modeClock = false;
}
else if (modeTimer) {
modeClock = true;
modeTimer = false;
}
else if (modeDateClock) {
modeClock = true;
modeDateClock = false;
}
}
delay(500);
}
}
if (digitalRead(button1) == LOW) {
delay(debounce);
if (digitalRead(button1) == LOW) {
holdTimer = millis();
while (digitalRead(button1) == LOW) { // Lets pause until button released
}
if (millis() > holdTimer + 2300) {
Serial.println ("Leading Zero Changed");
leadingZero = !leadingZero;
ledSequence(0);
ledSequence(1);
}
else {
modeTimer = true;
modeClock = false;
timerRunning = !timerRunning;
if (timerRunning) { // Lap has just been started
lapStartMillis = millis();
}
else { // Lap ending,
totalMillis += millis() - lapStartMillis;
}
}
}
}
if (digitalRead(button2) == LOW) {
delay(debounce);
if (digitalRead(button2) == LOW) {
holdTimer = millis();
while (digitalRead(button2) == LOW) { // Lets pause until button released
}
if (millis() > holdTimer + 6000) {
Serial.println("Set Clock");
delay(1000);
}
else if (millis() > holdTimer + 3000) {
clockMode_12 = !clockMode_12;
}
else {
if (!timerRunning) {
totalMillis = 0;// Reset timer to 0
sprintf(dspVal, "%02d %02d", 0, 0);
tm1637ShowDigits(dspVal);
}
}
delay(500);
}
}
}// ******************************************* End of readButtons
void lightMeter() { // Used to read light level and set brightness of LEDs/Display
static int oldBrt;
int myBrt = 6 - (analogRead(ldr) / 150 - 1);// Read value from Light Dependent Resistor,
// convert to value from 1 to 5
if (oldBrt != myBrt) {// Only adjsut if light reading changes
ledSetBrightness(myBrt);
tm1637SetBrightness(myBrt);
oldBrt = myBrt;
}
}// ******************************************* End of lightMeter
void loop() {
readButtons();// Check to see if any buttons are pressed
lightMeter();// check/adjust display brightness if needed
if (modeClock) {
showClock();
}
else if (modeTimer) {
showTimer();
}
tm1637ShowDigits(dspVal);
}
Comments