#include <Pushbutton.h>
#include <RTClib.h>
/*
* Choose your display
*/
//#define USE_PARALLEL_2004_LCD // Is default
//#define USE_PARALLEL_1602_LCD
//#define USE_SERIAL_2004_LCD
#define USE_SERIAL_1602_LCD
#include "LCDBigNumbers.hpp" // Include sources for LCD big number generation
#if defined(USE_PARALLEL_LCD)
LiquidCrystal myLCD(2, 3, 4, 5, 6, 7); // Depends on your actual connections
//LiquidCrystal myLCD(4, 5, 6, 7, 8, 9); // Sample connections starting at pin 4
#else
#define LCD_I2C_ADDRESS 0x27 // Default LCD address is 0x27 for a 20 chars and 4 line / 2004 display
LiquidCrystal_I2C myLCD(LCD_I2C_ADDRESS, LCD_COLUMNS, LCD_ROWS); // LCD_COLUMNS and LCD_ROWS are set by LCDBigNumbers.hpp depending on the defined display
#endif
/*
* Available big number fonts are: BIG_NUMBERS_FONT_1_COLUMN_2_ROWS_VARIANT_1, BIG_NUMBERS_FONT_2_COLUMN_2_ROWS_VARIANT_1,
* BIG_NUMBERS_FONT_3_COLUMN_2_ROWS_VARIANT_1, BIG_NUMBERS_FONT_3_COLUMN_2_ROWS_VARIANT_2, BIG_NUMBERS_FONT_3_COLUMN_2_ROWS_VARIANT_3,
* BIG_NUMBERS_FONT_2_COLUMN_3_ROWS_VARIANT_1, BIG_NUMBERS_FONT_2_COLUMN_3_ROWS_VARIANT_2, BIG_NUMBERS_FONT_3_COLUMN_3_ROWS_VARIANT_1,
* BIG_NUMBERS_FONT_3_COLUMN_4_ROWS_VARIANT_1, BIG_NUMBERS_FONT_3_COLUMN_4_ROWS_VARIANT_2
*/
LCDBigNumbers bigLCD(&myLCD, BIG_NUMBERS_FONT_3_COLUMN_2_ROWS_VARIANT_2);
RTC_DS1307 rtc;
#define LDR_PIN 15
#define BUTTON_PIN 25
#define SW_PIN 33
#define DT_PIN 32
#define CLK_PIN 35
Pushbutton buttonAlarm(BUTTON_PIN);
Pushbutton buttonSelect(SW_PIN);
const uint16_t LDR_DARK = 3700;
const uint16_t LDR_LIGHT = 60;
unsigned int menu = 0; // Relative position of rotary encoder
byte mode = 0;
struct clockConfig {
bool twelvehr;
bool backLight;
};
struct alarmSetting {
};
struct clockConfig config;
const char menu_clock[4][16] = { "12/24hr", "Alarm on/off", "Alarm set", "Time set" };
const char menu_wifi[3][16] = { "Wifi On/Off", "Set SSID", "Set password" };
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
pinMode(LDR_PIN, INPUT);
pinMode(SW_PIN, INPUT_PULLUP);
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(DT_PIN, INPUT);
pinMode(CLK_PIN, INPUT);
rtc.begin();
if (! rtc.isrunning()) {
Serial.println("RTC is NOT running!");
// following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
// Initialise LCD
#if defined(USE_PARALLEL_LCD)
myLCD.begin(LCD_COLUMNS, LCD_ROWS); // LCD_COLUMNS and LCD_ROWS are set by LCDBigNumbers.hpp depending on the defined display
#else
myLCD.init();
myLCD.clear();
myLCD.backlight();
#endif
bigLCD.begin(); // Creates custom character used for generating big numbers
// read clockConfig from RTC nvram
rtc.readnvram((uint8_t *) &config, sizeof(struct clockConfig), 0);
attachInterrupt(digitalPinToInterrupt(CLK_PIN), readEncoder, FALLING);
Serial.print("Config: ");
Serial.print(config.twelvehr);
Serial.print(", ");
Serial.println(config.backLight);
}
void loop() {
static uint8_t prevMinute = 0;
static uint8_t prevSecond = 0;
uint8_t thehour = 0;
static bool prevBLState = true;
bool newBLState = ambient();
DateTime now = rtc.now();
if (now.minute() > prevMinute) {
displayTime(now);
}
if (now.second() > prevSecond) {
blinkTime(now.second());
}
if ( buttonSelect.getSingleDebouncedPress() ) {
}
switch( mode 0) {
case 0: // Show the time
// Turn on backlight when needed
if (prevBLState != newBLState) {
myLCD.setBacklight(newBLState);
prevBLState = newBLState;
}
// Show the time each minute
if (now.minute() > prevMinute) {
displayTime(now);
// play Alarm sound if needed
}
// Toggle the colon every second
if (now.second() > prevSecond) {
blinkTime(now.second());
}
break;
case 1: // Show the clock menu
break;
case 2:
break;
}
if (now.second() > prevSecond) {
blinkTime(now.second());
}
}
prevMinute = now.minute();
prevSecond = now.second();
}
// showMenu ()
void showMenu(char * menuarray[][]) {
int numItems = sizeof(menuarray)/sizeof(menuarray[0]);
int lenItems = sizeof(menuarray[0])/sizeof(menuarray[0][0]);
myLCD.clear();
myLCD.setCursor(2,1);
myLCD.print()
}
// void readEncoder()
//
// Read the rotary encoder
// Sets relative offset of encoder position is stored in global unsigned int counter
//
void readEncoder() {
int dtValue = digitalRead(ENCODER_DT);
if (dtValue == HIGH) {
counter++; // Clockwise
}
if (dtValue == LOW) {
counter--; // Counterclockwise
}
}
// bool ambient()
//
// Returns true when backlight should be on:
// false: Too dark, it must be sleepy time
// true: It's light enough to be doing something
// false: Too bright, backlight pointless
//
bool ambient() {
uint16_t raw = analogRead(LDR_PIN);
if (raw > LDR_DARK) {
return false;
} else if (raw < LDR_LIGHT) {
return false;
}
return true;
}
// void blinkTime()
//
// Blinks the colon in time display every second
//
void blinkTime(const uint8_t sec) {
bigLCD.setBigNumberCursor(8);
if ((sec % 2) == 0) {
bigLCD.print(':');
}
else {
bigLCD.print(ONE_COLUMN_SPACE_CHARACTER);
}
}
// void displayTime()
//
// Display the time in a big font
void displayTime(const DateTime &now) {
bigLCD.setBigNumberCursor(2);
bigLCD.print(now.hour(), DEC);
bigLCD.print(":");
bigLCD.print(now.minute(), DEC);
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.println();
}