/*
### simplest ever Arduino UNO digital clock ###
This clock needs only a 1602 LCD 2X16 and 2 push buttons
No Potentiometer for contrast, no resistors for pull-up or backlight !!!!
The simplest clock ever made with a Arduino UNO
Button Functions:
- short stroke on one of the buttons put Backlight on for 30 s
Time settings
- Press on H increments the Hours
- Press on M increments the Minutes and resets the seconds
*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define DS1307_I2C_ADDRESS 0x68
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val) {
return ( (val / 10 * 16) + (val % 10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val) {
return ( (val / 16 * 10) + (val % 16) );
}
/*void setDS1307time(byte second, byte minute, byte hour, byte dayOfWeek, byte dayOfMonth, byte month, byte year) {
// sets time and date data to DS1307
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.write(0); // set next input to start at the seconds register
Wire.write(decToBcd(second)); // set seconds
Wire.write(decToBcd(minute)); // set minutes
Wire.write(decToBcd(hour)); // set hours
Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
Wire.write(decToBcd(month)); // set month
Wire.write(decToBcd(year)); // set year (0 to 99)
Wire.endTransmission();
}
*/
void readDS1307time(byte *second, byte *minute, byte *hour, byte *dayOfWeek, byte *dayOfMonth, byte *month, byte *year) {
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.write(0); // set DS1307 register pointer to 00h
Wire.endTransmission();
Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
// request seven bytes of data from DS1307 starting from register 00h
*second = bcdToDec(Wire.read() & 0x7f);
*minute = bcdToDec(Wire.read());
*hour = bcdToDec(Wire.read() & 0x3f);
*dayOfWeek = bcdToDec(Wire.read());
*dayOfMonth = bcdToDec(Wire.read());
*month = bcdToDec(Wire.read());
*year = bcdToDec(Wire.read());
*second = sec;
}
void displayTime() {
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
// retrieve data from DS1307
readDS1307time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
// send it to the serial monitor
Serial.print(hour, DEC);
// convert the byte variable to a decimal number when displayed
Serial.print(":");
if (minute < 10) {
Serial.print("0");
}
Serial.print(minute, DEC);
Serial.print(":");
if (second < 10) {
Serial.print("0");
}
Serial.print(second, DEC);
Serial.print(" ");
Serial.print(dayOfMonth, DEC);
Serial.print(".");
Serial.print(month, DEC);
Serial.print(".20");
Serial.print(year, DEC);
Serial.print(" ");
switch (dayOfWeek) {
case 1:
Serial.println("Neděle");
break;
case 2:
Serial.println("Pondělí");
break;
case 3:
Serial.println("Úterý");
break;
case 4:
Serial.println("Středa");
break;
case 5:
Serial.println("Čtvrtek");
break;
case 6:
Serial.println("Pátek");
break;
case 7:
Serial.println("Sobota");
break;
}
}
// clear the terminal screen and send the cursor home
void clearAndHome() {
Serial.write(27);
Serial.print("[2J"); // clear screen
Serial.write(27); // ESC
Serial.print("[H"); // cursor to home
}
// This defines the LCD wiring to the DIGITALpins
LiquidCrystal_I2C lcd(0x27, 20, 2);
// Digital LCD Constrast setting
int cs = 9; // pin 9 for contrast PWM
const int contrast = 20;// default contrast
// initial Time display is 12:59:45 PM
int h = 23;
int m = 59;
int s = 45;
int flag = 1; //PM
// Time Set Buttons
int button1;
int button2;
// Pins definition for Time Set Buttons
int hs = 0; // pin 0 for Hours Setting
int ms = 1; // pin 1 for Minutes Setting
// Backlight Time Out
const int Time_light = 150;
int bl_TO = Time_light; // Backlight Time-Out
int bl = 10; // Backlight pin
const int backlight = 40; // no more then 7mA !!!
// For accurate Time reading, use Arduino Real Time Clock and not just delay()
static uint32_t last_time, now = 0; // RTC
byte aa [8] = {
B00001,
B00010,
B00000,
B01110,
B00001,
B01111,
B10001,
B01111,
};
byte cz [8] = {
B01010,
B00100,
B00000,
B01110,
B10000,
B10000,
B10001,
B01110,
};
void setup() {
Serial.begin(115200);
Wire.begin();
// set the initial time here:
// DS1307 seconds, minutes, hours, day, date, month, year
// setDS1307time(30,42,21,4,26,11,14);
lcd.begin(16, 2);
lcd.createChar(0, aa);
lcd.createChar(1, cz);
pinMode(hs, INPUT_PULLUP); // avoid external Pullup resistors for Button 1
pinMode(ms, INPUT_PULLUP); // and Button 2
analogWrite(cs, contrast); // Adjust Contrast VO
analogWrite(bl, backlight); // Turn on Backlight
now = millis(); // read RTC initial value
}
void loop() {
if (second != s) {
clearAndHome();
displayTime();
}
}
/* void loop() {
lcd.begin(16, 2); // every second
// Update LCD Display
// Print TIME in Hour, Min, Sec + AM/PM
lcd.setCursor(4, 0);
//lcd.print("Time ");
if (h < 10)lcd.print("0"); // always 2 digits
lcd.print(h);
lcd.print(":");
if (m < 10)lcd.print("0");
lcd.print(m);
lcd.print(":");
if (s < 10)lcd.print("0");
lcd.print(s);
//if(flag==0) lcd.print(" AM");
//if(flag==1) lcd.print(" PM");
clearAndHome();
displayTime(); // display the real-time clock data on the Serial Monitor,
if ((h >= 4) && (h < 9))
{
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(6, 1);
lcd.print("R");
lcd.write(byte(0));
lcd.print ("no");
}
if ((h >= 9) && (h < 12))
{
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(3, 1);
lcd.print("Dopoledne");
}
if ((h >= 12) && (h < 18))
{
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(3, 1);
lcd.print("Odpoledne");
}
if ((h >= 18) && (h < 22))
{
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(5, 1);
lcd.print("Ve");
lcd.write(byte(1));
lcd.print ("er");
}
if ((h < 4) | (h >= 22))
{
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(6, 1);
lcd.print("Noc");
}
// improved replacement of delay(1000)
// Much better accuracy, no more dependant of loop execution time
for ( int i = 0 ; i < 5 ; i++) // make 5 time 200ms loop, for faster Button response
{
while ((now - last_time) < 200) //delay200ms
{
now = millis();
}
// inner 200ms loop
last_time = now; // prepare for next loop
// read Setting Buttons
button1 = digitalRead(hs); // Read Buttons
button2 = digitalRead(ms);
//Backlight time out
bl_TO--;
if (bl_TO == 0)
{
analogWrite(bl, 0); // Backlight OFF
bl_TO++;
}
// Hit any to activate Backlight
if ( ((button1 == 0) | (button2 == 0)) & (bl_TO == 1) )
{
bl_TO = Time_light;
analogWrite(bl, backlight);
// wait until Button released
while ((button1 == 0) | (button2 == 0))
{
button1 = digitalRead(hs); // Read Buttons
button2 = digitalRead(ms);
}
}
else
// Process Button 1 or Button 2 when hit while Backlight on
{
if (button1 == 0) {
h = h + 1;
bl_TO = Time_light;
analogWrite(bl, backlight);
}
if (button2 == 0) {
s = 0;
m = m + 1;
bl_TO = Time_light;
analogWrite(bl, backlight);
}
// ---- manage seconds, minutes, hours am/pm overflow ----//
if (s == 60) {
s = 0;
m = m + 1;
}
if (m == 60)
{
m = 0;
h = h + 1;
}
if (h == 24)
{
h = 0;
flag = flag + 1;
if (flag == 2)flag = 0;
}
if ((button1 == 0) | (button2 == 0)) // Update display if time set button pressed
{
// Update LCD Display
// Print TIME in Hour, Min, Sec + AM/PM
lcd.setCursor(4, 0);
//lcd.print("Time ");
if (h < 10)lcd.print("0"); // always 2 digits
lcd.print(h);
lcd.print(":");
if (m < 10)lcd.print("0");
lcd.print(m);
lcd.print(":");
if (s < 10)lcd.print("0");
lcd.print(s);
// if(flag==0) lcd.print(" AM");
// if(flag==1) lcd.print(" PM");
lcd.setCursor(0, 1); // for Line 2
lcd.print("Alzheimer hodiny");
}
} // end if else
}// end for
// outer 1000ms loop
s = s + 1; //increment sec. counting
// ---- manage seconds, minutes, hours am/pm overflow ----
if (s == 60) {
s = 0;
m = m + 1;
}
if (m == 60)
{
m = 0;
h = h + 1;
}
if (h == 24)
{
h = 0;
flag = flag + 1;
if (flag == 2)flag = 0;
}
// Loop end
*/