2013/05/09

LCD Keypad Adjustable Clock With Temperature Sensor

The sketch extends "LCD Displaying Date, Time From DS1307 And Temperature From LM35" on May 3, 2013 to adjust the date and time with keypad on LCD keypad shield. It works on Arduino ide 0022 without optimization.

There is a new version using time.h library and adds displaying weekday.

Usage

1. Use <RIGHT> keypad to enter set mode.
2. Use <RIGHT> to navigate on parameter to be modified.
3. Use <UP> to set value of the aimed parameter.
4. Use <SELECT> to save date and time to RTC.
5. Use <LEFT> to leave set mode.

Sketch

//
// Maurice Ribble
// 4-17-2008
//
http://www.glacialwanderer.com/hobbyrobotics
// This code tests the DS1307 Real Time clock on the Arduino board.
// The ds1307 works in binary coded decimal or BCD.  You can look up
// bcd in google if you aren't familior with it.  There can output
// a square wave, but I don't expose that in this code.  See the
// ds1307 for it's full capabilities.

// Revised by Befun Hung to set/sync date and time for DS1307 Real Time Clock on Freeduino/Arduino shield.
// June-01-2012
// Revised by Befun Hung to create terminalSync function to be more modular
// May-03-2013
// Revised by Befun Hung to use keypad for modifying date and time on May-09-2013
// It works on Arduino IDE 0022, just works without optimization
//
http://cheaphousetek.blogspot.com/
// Usage: 1. Press <RIGHT> to enter set mode
//        2. Press <RIGHT> to navigate on parameter to be modified
//        3. Press <UP> to select the value
//        4. Press <SELECT> to modify date and time
//        5. Press <LEFT> to leave set mode
// The sketch calculates the day of week before saving date and time to RTC

// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
// 2010-02-04 <
jcw@equi4.com> http://opensource.org/licenses/mit-license.php
// $Id: ds1307.pde 4773 2010-02-04 14:09:18Z jcw $
// Added LCD display and LM35 temperature function by Befun Hung 2011-10-13
// Take out displayDateTime procedure from loop() by Befun Hung 2013-05-03

#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

#define DS1307_I2C_ADDRESS 0x68
// define some values used by the panel and buttons
int lcd_key     = 0;
int adc_key_in  = 0;
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

String datetimeIn;
int TimeSet = 0;
int timeArray[19], checkStatus = 0;
int centuryCode = 6; // for year 2000-2099 (Wikipedia: determination of the day of the week)
int monTable[12] = {0,3,3,6,1,4,6,2,5,0,3,5};
int leapmonTable[12] = {6,2,3,6,1,4,6,2,5,0,3,5};
char *weekDay[] = {"", "MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"};

RTC_DS1307 RTC;
int potPin = 3;
float temperature = 0;

// read the buttons
int read_LCD_buttons()
{
 adc_key_in = analogRead(0);     
 // read the value from the sensor
 // my buttons when read are centered at these valies: 0, 144, 329, 504, 741
 // we add approx 50 to those values and check to see if we are close
 if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
 if (adc_key_in < 73)   return btnRIGHT; 
 if (adc_key_in < 237)  return btnUP;
 if (adc_key_in < 415)  return btnDOWN;
 if (adc_key_in < 623)  return btnLEFT;
 if (adc_key_in < 882)  return btnSELECT;  
 return btnNONE;  // when all others fail, return this...
}

// 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) );
}

// Stops the DS1307, but it has the side effect of setting seconds to 0
// Probably only want to use this for testing
/*void stopDs1307()
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0);
  Wire.send(0x80);
  Wire.endTransmission();
}*/

// 1) Sets the date and time on the ds1307
// 2) Starts the clock
// 3) Sets hour mode to 24 hour clock
// Assumes you're passing in valid numbers
void setDateDs1307(byte second,        // 0-59
                   byte minute,        // 0-59
                   byte hour,          // 1-23
                   byte dayOfWeek,     // 1-7
                   byte dayOfMonth,    // 1-28/29/30/31
                   byte month,         // 1-12
                   byte year)          // 0-99
{
   Wire.beginTransmission(DS1307_I2C_ADDRESS);
   Wire.send(0);
   Wire.send(decToBcd(second));    // 0 to bit 7 starts the clock
   Wire.send(decToBcd(minute));
   Wire.send(decToBcd(hour));      // If you want 12 hour am/pm you need to set
                                   // bit 6 (also need to change readDateDs1307)
   Wire.send(decToBcd(dayOfWeek));
   Wire.send(decToBcd(dayOfMonth));
   Wire.send(decToBcd(month));
   Wire.send(decToBcd(year));
   Wire.endTransmission();
}

// Gets the date and time from the ds1307
void getDateDs1307(byte *second,
          byte *minute,
          byte *hour,
          byte *dayOfWeek,
          byte *dayOfMonth,
          byte *month,
          byte *year)
{
  // Reset the register pointer
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
  // A few of these need masks because certain bits are control bits
  *second     = bcdToDec(Wire.receive() & 0x7f);
  *minute     = bcdToDec(Wire.receive());
  *hour       = bcdToDec(Wire.receive() & 0x3f);  // Need to change this if 12 hour am/pm
  *dayOfWeek  = bcdToDec(Wire.receive());
  *dayOfMonth = bcdToDec(Wire.receive());
  *month      = bcdToDec(Wire.receive());
  *year       = bcdToDec(Wire.receive());
}

void printFormatError() {
  Serial.println("Format Error\n");
}
/*
void printValueError() {
  Serial.println("Value Error\n");
}
*/

void setup() {
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  Wire.begin();
  Serial.begin(9600);
  RTC.begin();
  lcd.begin(16, 2);
  lcd.print("*cheaphousetek*");
  delay(5000);
  lcd.clear();
  // following line sets the RTC to the date & time this sketch was compiled
  // RTC.adjust(DateTime(__DATE__, __TIME__));
  // delay(100);

  // Change these values to what you want to set your clock to.
  // You probably only want to set your clock once and then remove
  // the setDateDs1307 call.
  // second = 45;
  // minute = 3;
  // hour = 7;
  // dayOfWeek = 5;
  // dayOfMonth = 17;
  // month = 4;
  // year = 8;
  // setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
}

void loop() {
  lcd_key = read_LCD_buttons();
  if (lcd_key == btnRIGHT)
  {
     keypadSetDateTime();
  } 
  displayDateTime();
}

void keypadSetDateTime()
{
  unsigned long tmp, longYear, longMonth, longDay, longHour, longMinute, longSecond;
  byte byteYear, byteMonth, byteDay, byteDayOfWeek, byteHour, byteMinute, byteSecond;
  int setVariable;
 
  DateTime now = RTC.now();
  lcd.clear();
  longYear = now.year();
  lcd.setCursor(0,0);
  lcd.print(longYear);
  lcd.setCursor(4,0);
  lcd.print("-");
 
  longMonth = now.month();
  if (longMonth < 10) {
    lcd.setCursor(5,0);
    lcd.print('0');
    lcd.setCursor(6,0);
    lcd.print(longMonth);
  }
  else {
    lcd.setCursor(5,0);
    lcd.print(longMonth);
  }
  lcd.setCursor(7,0);
  lcd.print('-');
 
  longDay = now.day();
  if (longDay < 10) {
    lcd.setCursor(8,0);
    lcd.print('0');
    lcd.setCursor(9,0);
    lcd.print(longDay);
  }
  else {
    lcd.setCursor(8,0);
    lcd.print(longDay);
  }
 
  longHour = now.hour();
  if (longHour < 10) {
    lcd.setCursor(0,1);
    lcd.print('0');
    lcd.setCursor(1,1);
    lcd.print(longHour);
  }
  else {
    lcd.setCursor(0,1);
    lcd.print(longHour);
  }
  lcd.setCursor(2,1);
  lcd.print(':'); 
 
  longMinute = now.minute();
  if (longMinute < 10) {
    lcd.setCursor(3,1);
    lcd.print('0');
    lcd.setCursor(4,1);
    lcd.print(longMinute);
  }
  else {
    lcd.setCursor(3,1);
    lcd.print(longMinute);
  }
  lcd.setCursor(5,1);
  lcd.print(':');
 
  longSecond = now.second();
  if (longSecond < 10) {
    lcd.setCursor(6,1);
    lcd.print('0');
    lcd.setCursor(7,1);
    lcd.print(longSecond);
  }
  else {
    lcd.setCursor(6,1);
    lcd.print(longSecond);
  }
 
  setVariable = 5;
  lcd.setCursor(0,3);
  while (true)
  {
    // lcd.setCursor(0,1);         // move to the begining of the second line
    lcd_key = read_LCD_buttons();  // read the buttons
    delay(200);                    // for debouncing

    switch (lcd_key)               // depending on which button was pushed, we perform an action
    {
      case btnRIGHT:
        {
        // lcd.print("RIGHT     ");
        setVariable = ((setVariable +1)) % 6;
        // lcd.setCursor(9,1);
        // lcd.print(setVariable);
        break;
        }
      case btnLEFT:
        {       
        // lcd.print("LEFT      "); 
        lcd.noBlink();
        lcd.clear();
        return;
        }
      case btnUP:
        {
        // lcd.print("UP        ");
        if (setVariable == 0) {
          longYear = ((longYear + 1) % 100) + 2000;
          lcd.setCursor(0,0);
          lcd.print(longYear);
        }
        if (setVariable == 1) {
          longMonth = (longMonth % 12) + 1;
          if (longMonth < 10) {
            lcd.setCursor(5,0);
            lcd.print('0');
            lcd.setCursor(6,0);
            lcd.print(longMonth);
          }
          else {
            lcd.setCursor(5,0);
            lcd.print(longMonth);
          }
        }
        if (setVariable == 2) {
          longDay = (longDay % 31) + 1;
          if (longDay< 10) {
            lcd.setCursor(8,0);
            lcd.print('0');
            lcd.setCursor(9,0);
            lcd.print(longDay);
          }
          else {
            lcd.setCursor(8,0);
            lcd.print(longDay);
          }
        }
        if (setVariable == 3) {
          longHour = (longHour + 1) % 24;
          if (longHour< 10) {
            lcd.setCursor(0,1);
            lcd.print('0');
            lcd.setCursor(1,1);
            lcd.print(longHour);
          }
          else {
            lcd.setCursor(0,1);
            lcd.print(longHour);
          }
        }
        if (setVariable == 4) {
          longMinute = (longMinute + 1) % 60;
          if (longMinute < 10) {
            lcd.setCursor(3,1);
            lcd.print('0');
            lcd.setCursor(4,1);
            lcd.print(longMinute);
          }
          else {
            lcd.setCursor(3,1);
            lcd.print(longMinute);
          }
        }
        if (setVariable == 5) {
          longSecond = (longSecond + 1) % 60;
          if (longSecond < 10) {
            lcd.setCursor(6,1);
            lcd.print('0');
            lcd.setCursor(7,1);
            lcd.print(longSecond);
          }
          else {
            lcd.setCursor(6,1);
            lcd.print(longSecond);
          }
        }
        break;
        }
      case btnDOWN:
        {
        // lcd.print("DOWN      ");
        break;
        }
      case btnSELECT:
        {
        // lcd.print("SELECT    ");    
        byteYear = byte(longYear-2000);
        byteMonth = byte(longMonth);
        byteDay = byte(longDay);
        byteHour = byte(longHour);
        byteMinute = byte(longMinute);
        byteSecond = byte(longSecond);
        if ((byteMonth == 1 || byteMonth == 3 || byteMonth == 5 ||byteMonth == 7 ||
             byteMonth == 8 || byteMonth == 10 || byteMonth ==12) && byteDay <= 31) {
          checkStatus = 1;  
        }
        if ((byteMonth == 4 || byteMonth == 6 || byteMonth == 9 || byteMonth == 11) && byteDay <= 30) {
          checkStatus = 1;
        }
        if ((byteMonth == 2 && (byteYear % 4) == 0) && byteDay <= 29) {
          checkStatus = 1;
        }
        if ((byteMonth == 2 && (byteYear % 4) != 0) && byteDay <= 28) {
          checkStatus = 1;
        }
        if (checkStatus) {
          if ((byteYear % 4) == 0) {
            byteDayOfWeek = (centuryCode + byteYear + ((byteYear - (byteYear % 4)) /4 ) + leapmonTable[byteMonth-1] + byteDay) % 7;
          }
          else {
            byteDayOfWeek = (centuryCode + byteYear + ((byteYear - (byteYear % 4)) / 4) + monTable[byteMonth-1] + byteDay) % 7;
          }
          if (byteDayOfWeek == 0) {
            byteDayOfWeek += 7;
          }
          setDateDs1307(byteSecond, byteMinute, byteHour, byteDayOfWeek, byteDay, byteMonth, byteYear);
        }
        lcd.setCursor(13,0);
        lcd.print(weekDay[byteDayOfWeek]);
        break;
        }
      case btnNONE:
        {
        // lcd.print("NONE      ");
        lcd.blink();
        if (setVariable == 0) {
          lcd.setCursor(3,0);
        }
        if (setVariable == 1) {
          lcd.setCursor(6,0);
        }
        if (setVariable == 2) {
          lcd.setCursor(9,0);
        }
        if (setVariable == 3) {
          lcd.setCursor(1,1);
        }
        if (setVariable == 4) {
          lcd.setCursor(4,1);
        }
        if (setVariable == 5) {
          lcd.setCursor(7,1);
        }
        break;
        }
    }
  }
}

void printTenths(long value) {
  // prints a value of 123 as 12.3
  // Serial.print(value / 10);
  // Serial.print('.');
  // Serial.print(value % 10);
  // Serial.println();
  lcd.setCursor(10, 1);
  lcd.print(value / 10);
  lcd.setCursor(12, 1);
  lcd.print('.');
  lcd.setCursor(13, 1);
  lcd.print(value % 10);
}

void displayDateTime() {
    DateTime now = RTC.now();
    int span = 10;
    long aRead = 0;
    unsigned long tmp;
     
    tmp = now.year();
    // Serial.print(now.year(), DEC);
    lcd.setCursor(0, 0);
    lcd.print(tmp);
    // Serial.print('/');
    lcd.setCursor(4, 0);
    lcd.print("-");
   
    tmp = now.month();
    if (now.month() < 10) {
      // Serial.print('0');
      // Serial.print(now.month(), DEC);
      lcd.setCursor(5, 0);
      lcd.print('0');
      lcd.setCursor(6, 0);
      lcd.print(tmp);
    }
    else {
      // Serial.print(now.month(), DEC);
      lcd.setCursor(5, 0);
      lcd.print(tmp);
    }
    // Serial.print('/');
    lcd.setCursor(7, 0);
    lcd.print('-');
   
    tmp = now.day();
    if (now.day() < 10) {
      // Serial.print('0');
      // Serial.print(now.day(), DEC);
      lcd.setCursor(8, 0);
      lcd.print('0');
      lcd.setCursor(9, 0);
      lcd.print(tmp);
    }
    else {
      // Serial.print(now.day(), DEC);
      lcd.setCursor(8, 0);
      lcd.print(tmp);
    }
    // Serial.print(' ');
   
    tmp = now.hour();
    if (now.hour() < 10) {
      // Serial.print('0');
      // Serial.print(now.hour(), DEC);
      lcd.setCursor(0, 1);
      lcd.print('0');
      lcd.setCursor(1, 1);
      lcd.print(tmp);
    }
    else {
      // Serial.print(now.hour(), DEC);
      lcd.setCursor(0, 1);
      lcd.print(tmp);
    }
    // Serial.print(':');
    lcd.setCursor(2, 1);
    lcd.print(':');
   
    tmp = now.minute();
    if (now.minute() < 10) {
      // Serial.print('0');
      // Serial.print(now.minute(), DEC);
      lcd.setCursor(3, 1);
      lcd.print('0');
      lcd.setCursor(4, 1);
      lcd.print(tmp);
    }
    else {
      // Serial.print(now.minute(), DEC);
      lcd.setCursor(3, 1);
      lcd.print(tmp);
    }
    // Serial.print(':');
    lcd.setCursor(5, 1);
    lcd.print(':');
   
    tmp = now.second();
    if (now.second() < 10) {
      // Serial.print('0');
      // Serial.print(now.second(), DEC);
      lcd.setCursor(6, 1);
      lcd.print('0');
      lcd.setCursor(7, 1);
      lcd.print(tmp);
    }
    else {
      // Serial.print(now.second(), DEC);
      lcd.setCursor(6, 1);
      lcd.print(tmp);
    }
    // Serial.print (' ');
    lcd.setCursor(8, 1);
    lcd.print(' ');
    // Serial.println();
   
    for (int i=0;i<span;i++) {
      aRead = aRead + analogRead(potPin);
      // Serial.print(aRead);
      // Serial.print(' ');
    }
    // aRead = aRead / span;
    temperature = (aRead / span * 500.0 / 1024.0);
    // Serial.print(aRead);
    // Serial.print(' ');
    // Serial.print(temperature);
    // Serial.print(' ');
    printTenths(long (temperature * 10));
    lcd.setCursor(14, 1);
    lcd.print(char(223));
    lcd.setCursor(15, 1);
    lcd.print('C');
       
    delay(200);
   
    // Serial.print(" since 2000 = ");
    // Serial.print(now.get());
    // Serial.print("s = ");
    // Serial.print(now.get() / 86400L);
    // Serial.println("d");
   
    // calculate a date which is 7 days and 30 seconds into the future
    // DateTime future (now.get() + 7 * 86400L + 30);
   
    // Serial.print(" now + 7d + 30s: ");
    // Serial.print(future.year(), DEC);
    // Serial.print('/');
    // Serial.print(future.month(), DEC);
    // Serial.print('/');
    // Serial.print(future.day(), DEC);
    // Serial.print(' ');
    // Serial.print(future.hour(), DEC);
    // Serial.print(':');
    // Serial.print(future.minute(), DEC);
    // Serial.print(':');
    // Serial.print(future.second(), DEC);
    // Serial.println();
   
    // Serial.println();
    // delay(3000);
}

2013/05/04

Terminal Emulator Adjustable LCD Real Time Clock

Combining two sketches - set/sync date and time on Jun 1, 2012 and LCD displaying date, time and temperature on May 3, 2013, a new sketch while displaying date, time and temperature on 16x2 LCD keypad shield, one can adjust the date and time using terminal emulator such as Arduino Serial Monitor without changing sketches. The usage is same as the sketch - set/sync date and time on Jun 1, 2012.

Sketch

//
// Maurice Ribble
// 4-17-2008
// http://www.glacialwanderer.com/hobbyrobotics

// This code tests the DS1307 Real Time clock on the Arduino board.
// The ds1307 works in binary coded decimal or BCD.  You can look up
// bcd in google if you aren't familior with it.  There can output
// a square wave, but I don't expose that in this code.  See the
// ds1307 for it's full capabilities.

// Revised by Befun Hung to set/sync date and time for DS1307 Real Time Clock on Freeduino/Arduino shield.
// June-01-2012
// Revised by Befun Hung to create terminalSync function to be more modular
// May-03-2013
// http://cheaphousetek.blogspot.com/
// Usage: After uploading to Freeduino/Arduino board, open the serial monitor.
// Input Format: YYYY-MM-DD hh:mm:ss <Enter>

// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
// 2010-02-04 <jcw@equi4.com> http://opensource.org/licenses/mit-license.php
// $Id: ds1307.pde 4773 2010-02-04 14:09:18Z jcw $
// Added LCD display and LM35 temperature function by Befun Hung 2011-10-13
// Take out displayDateTime procedure from loop() by Befun Hung 2013-05-03

#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

#define DS1307_I2C_ADDRESS 0x68

String datetimeIn;
int TimeSet = 0;
int timeArray[19], checkStatus = 1;
int centuryCode = 6; // for year 2000-2099 (Wikipedia: determination of the day of the week)
int monTable[12] = {0,3,3,6,1,4,6,2,5,0,3,5};
int leapmonTable[12] = {6,2,3,6,1,4,6,2,5,0,3,5};

RTC_DS1307 RTC;
int potPin = 3;
float temperature = 0;

// 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) );
}

// Stops the DS1307, but it has the side effect of setting seconds to 0
// Probably only want to use this for testing
/*void stopDs1307()
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0);
  Wire.send(0x80);
  Wire.endTransmission();
}*/

// 1) Sets the date and time on the ds1307
// 2) Starts the clock
// 3) Sets hour mode to 24 hour clock
// Assumes you're passing in valid numbers
void setDateDs1307(byte second,        // 0-59
                   byte minute,        // 0-59
                   byte hour,          // 1-23
                   byte dayOfWeek,     // 1-7
                   byte dayOfMonth,    // 1-28/29/30/31
                   byte month,         // 1-12
                   byte year)          // 0-99
{
   Wire.beginTransmission(DS1307_I2C_ADDRESS);
   Wire.send(0);
   Wire.send(decToBcd(second));    // 0 to bit 7 starts the clock
   Wire.send(decToBcd(minute));
   Wire.send(decToBcd(hour));      // If you want 12 hour am/pm you need to set
                                   // bit 6 (also need to change readDateDs1307)
   Wire.send(decToBcd(dayOfWeek));
   Wire.send(decToBcd(dayOfMonth));
   Wire.send(decToBcd(month));
   Wire.send(decToBcd(year));
   Wire.endTransmission();
}

// Gets the date and time from the ds1307
void getDateDs1307(byte *second,
          byte *minute,
          byte *hour,
          byte *dayOfWeek,
          byte *dayOfMonth,
          byte *month,
          byte *year)
{
  // Reset the register pointer
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  // A few of these need masks because certain bits are control bits
  *second     = bcdToDec(Wire.receive() & 0x7f);
  *minute     = bcdToDec(Wire.receive());
  *hour       = bcdToDec(Wire.receive() & 0x3f);  // Need to change this if 12 hour am/pm
  *dayOfWeek  = bcdToDec(Wire.receive());
  *dayOfMonth = bcdToDec(Wire.receive());
  *month      = bcdToDec(Wire.receive());
  *year       = bcdToDec(Wire.receive());
}

void printFormatError() {
  Serial.println("Format Error\n");
}
/*
void printValueError() {
  Serial.println("Value Error\n");
}
*/

void setup() {
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  Wire.begin();
  Serial.begin(9600);
  RTC.begin();
  lcd.begin(16, 2);
  lcd.print("*cheaphousetek*");
  delay(5000);
  lcd.clear();
  // following line sets the RTC to the date & time this sketch was compiled
  // RTC.adjust(DateTime(__DATE__, __TIME__));
  // delay(100);
  Serial.print("Waiting for setting the date and time now.\n");
  Serial.print("Input Format: YYYY-MM-DD HH:MM:SS\n");
  // Change these values to what you want to set your clock to.
  // You probably only want to set your clock once and then remove
  // the setDateDs1307 call.
  // second = 45;
  // minute = 3;
  // hour = 7;
  // dayOfWeek = 5;
  // dayOfMonth = 17;
  // month = 4;
  // year = 8;
  // setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
}

void loop() {
  terminalSync();
  displayDateTime();
}

void terminalSync() {
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  
  if (Serial.available() == 19 ) {
    for (int i=0;i<19;i++) {
      timeArray[i] = Serial.read();  // Serial.read() read int type ASCII code value 
    }
    // for digits subtract 48 ('0' ASCII code value)
    for (int j=0;j<19;j++) {
      if (timeArray[j] > 47 && timeArray[j] < 58) {
        timeArray[j] -= 48;
      }
      if (timeArray[j] <= 9) {
         Serial.print(timeArray[j]);
      } 
      else {
        Serial.print(char(timeArray[j]));
      }
    }
    Serial.println("");
    // check for digits range
    checkStatus = 1;
    if (timeArray[0] != 2) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[1] != 0) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[2] > 9) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[3] > 9) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[5] > 1) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[6] > 9) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[5]*10+timeArray[6] > 12) {
      // printValueError();
      checkStatus = 0;
    }
    if (timeArray[8] > 3) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[9] > 9) {
      printFormatError();
      checkStatus = 0;
    }
    if ((timeArray[5]*10+timeArray[6] == 1 || 
         timeArray[5]*10+timeArray[6] == 3 ||
         timeArray[5]*10+timeArray[6] == 5 ||
         timeArray[5]*10+timeArray[6] == 7 ||
         timeArray[5]*10+timeArray[6] == 8 ||
         timeArray[5]*10+timeArray[6] == 10 ||
         timeArray[5]*10+timeArray[6] == 12) && timeArray[8]*10+timeArray[9] > 31) {
      // printValueError();
      checkStatus = 0;
    }
    if ((timeArray[5]*10+timeArray[6] == 4 || 
         timeArray[5]*10+timeArray[6] == 6 ||
         timeArray[5]*10+timeArray[6] == 9 ||
         timeArray[5]*10+timeArray[6] == 11) && timeArray[8]*10+timeArray[9] > 30) {
      // printValueError();
      checkStatus = 0;
    }
    if ((timeArray[5]*10+timeArray[6] == 2 && year % 4 == 0) && timeArray[8]*10+timeArray[9] > 29) {
      // printValueError();
      checkStatus = 0;
    }
    if ((timeArray[5]*10+timeArray[6] == 2 && year % 4 != 0) && timeArray[8]*10+timeArray[9] > 28) {
      // printValueError();
      checkStatus = 0;
    }
    if (timeArray[11] > 2) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[12] > 9) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[11]*10+timeArray[12] > 23) {
      // printValueError();
      checkStatus = 0;
    }
    if (timeArray[14] > 5) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[15] > 9) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[14]*10+timeArray[15] > 59) {
      // printValueError();
      checkStatus = 0;
    }
    if (timeArray[17] > 5) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[18] > 9) {
      printFormatError();
      checkStatus = 0;
    }
    if (timeArray[17]*10+timeArray[18] > 59) {
      // printValueError();
      checkStatus = 0;
    }
    // Serial.println(checkStatus);
    if (checkStatus) {
      second = timeArray[17]*10+timeArray[18];
      minute = timeArray[14]*10+timeArray[15];
      hour = timeArray[11]*10+timeArray[12];
      // dayOfWeek = 5;
      dayOfMonth = timeArray[8]*10+timeArray[9];
      month = timeArray[5]*10+timeArray[6];
      year = timeArray[2]*10+timeArray[3];
      if ((year % 4) == 0) {
        dayOfWeek = (centuryCode + year + ((year - (year % 4)) / 4) + leapmonTable[month-1] + dayOfMonth) % 7;
      }
      else {
        dayOfWeek = (centuryCode + year + ((year - (year % 4)) / 4) + monTable[month-1] + dayOfMonth) % 7;
      }
      if (dayOfWeek == 0) {
        dayOfWeek += 7;
      }
      setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
    }
    getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
    Serial.print(hour, DEC);
    Serial.print(":");
    Serial.print(minute, DEC);
    Serial.print(":");
    Serial.print(second, DEC);
    Serial.print("  ");
    Serial.print(month, DEC);
    Serial.print("/");
    Serial.print(dayOfMonth, DEC);
    Serial.print("/");
    Serial.print(year, DEC);
    Serial.print("  Day_of_week:");
    Serial.println(dayOfWeek, DEC);
    // delay(1000);
  }
}

void printTenths(long value) {
  // prints a value of 123 as 12.3
  // Serial.print(value / 10);
  // Serial.print('.');
  // Serial.print(value % 10);
  // Serial.println();
  lcd.setCursor(10, 1);
  lcd.print(value / 10);
  lcd.setCursor(12, 1);
  lcd.print('.');
  lcd.setCursor(13, 1);
  lcd.print(value % 10);
}

void displayDateTime() {
    DateTime now = RTC.now();
    int span = 10;
    long aRead = 0;
    unsigned long tmp;
      
    tmp = now.year();
    // Serial.print(now.year(), DEC);
    lcd.setCursor(0, 0);
    lcd.print(tmp);
    // Serial.print('/');
    lcd.setCursor(4, 0);
    lcd.print("-");
    
    tmp = now.month();
    if (now.month() < 10) {
      // Serial.print('0');
      // Serial.print(now.month(), DEC);
      lcd.setCursor(5, 0);
      lcd.print('0');
      lcd.setCursor(6, 0);
      lcd.print(tmp);
    }
    else {
      // Serial.print(now.month(), DEC);
      lcd.setCursor(5, 0);
      lcd.print(tmp);
    }
    // Serial.print('/');
    lcd.setCursor(7, 0);
    lcd.print('-');
    
    tmp = now.day();
    if (now.day() < 10) {
      // Serial.print('0');
      // Serial.print(now.day(), DEC);
      lcd.setCursor(8, 0);
      lcd.print('0');
      lcd.setCursor(9, 0);
      lcd.print(tmp);
    }
    else {
      // Serial.print(now.day(), DEC);
      lcd.setCursor(8, 0);
      lcd.print(tmp);
    }
    // Serial.print(' ');
    
    tmp = now.hour();
    if (now.hour() < 10) {
      // Serial.print('0');
      // Serial.print(now.hour(), DEC);
      lcd.setCursor(0, 1);
      lcd.print('0');
      lcd.setCursor(1, 1);
      lcd.print(tmp);
    }
    else {
      // Serial.print(now.hour(), DEC);
      lcd.setCursor(0, 1);
      lcd.print(tmp);
    }
    // Serial.print(':');
    lcd.setCursor(2, 1);
    lcd.print(':');
    
    tmp = now.minute();
    if (now.minute() < 10) {
      // Serial.print('0');
      // Serial.print(now.minute(), DEC);
      lcd.setCursor(3, 1);
      lcd.print('0');
      lcd.setCursor(4, 1);
      lcd.print(tmp);
    }
    else {
      // Serial.print(now.minute(), DEC);
      lcd.setCursor(3, 1);
      lcd.print(tmp);
    }
    // Serial.print(':');
    lcd.setCursor(5, 1);
    lcd.print(':');
    
    tmp = now.second();
    if (now.second() < 10) {
      // Serial.print('0');
      // Serial.print(now.second(), DEC);
      lcd.setCursor(6, 1);
      lcd.print('0');
      lcd.setCursor(7, 1);
      lcd.print(tmp);
    }
    else {
      // Serial.print(now.second(), DEC);
      lcd.setCursor(6, 1);
      lcd.print(tmp);
    }
    // Serial.print (' ');
    lcd.setCursor(8, 1);
    lcd.print(' ');
    // Serial.println();
    
    for (int i=0;i<span;i++) {
      aRead = aRead + analogRead(potPin);
      // Serial.print(aRead);
      // Serial.print(' ');
    }
    // aRead = aRead / span;
    temperature = (aRead / span * 500.0 / 1024.0);
    // Serial.print(aRead);
    // Serial.print(' ');
    // Serial.print(temperature);
    // Serial.print(' ');
    printTenths(long (temperature * 10));
    lcd.setCursor(14, 1);
    lcd.print(char(223));
    lcd.setCursor(15, 1);
    lcd.print('C');
        
    delay(200);
    
    // Serial.print(" since 2000 = ");
    // Serial.print(now.get());
    // Serial.print("s = ");
    // Serial.print(now.get() / 86400L);
    // Serial.println("d");
    
    // calculate a date which is 7 days and 30 seconds into the future
    // DateTime future (now.get() + 7 * 86400L + 30);
    
    // Serial.print(" now + 7d + 30s: ");
    // Serial.print(future.year(), DEC);
    // Serial.print('/');
    // Serial.print(future.month(), DEC);
    // Serial.print('/');
    // Serial.print(future.day(), DEC);
    // Serial.print(' ');
    // Serial.print(future.hour(), DEC);
    // Serial.print(':');
    // Serial.print(future.minute(), DEC);
    // Serial.print(':');
    // Serial.print(future.second(), DEC);
    // Serial.println();
    
    // Serial.println();
    // delay(3000);
}

2013/05/03

LCD Displaying Date, Time From DS1307 And Temperature From LM35

Date and time is useful for many applications. Most visitors to my blog search for rtc stuff. The following sketch show a simple application using a LCD shield, a RTC Sensor shield and a LM35 temperature sensor to display date, time and enviromnental temperature. To use the sketch, you need to download the RTClib library.

There is a new version using Time.h library and showing weekday.

Output:


Sketch:

// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
// 2010-02-04 <jcw@equi4.com> http://opensource.org/licenses/mit-license.php
// $Id: ds1307.pde 4773 2010-02-04 14:09:18Z jcw $
// Added LCD display and LM35 temperature function by Befun Hung 2011-10-13
// Take out displayDateTime procedure from loop() by Befun Hung 2013-05-03
// The sketch works on Arduino IDE 0022

#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

RTC_DS1307 RTC;
// change potPin value to 0, 1, 2 for A0, A1, A2 respectly
int potPin = 3;
float temperature = 0;

void setup () {
    Serial.begin(9600);
    Wire.begin();
    RTC.begin();
    lcd.begin(16, 2);
    lcd.print("*cheaphousetek*");
    delay(5000);
    lcd.clear();
    
    // following line sets the RTC to the date & time this sketch was compiled
    // RTC.adjust(DateTime(__DATE__, __TIME__));
}

void loop() {
  displayDateTime();
}

void printTenths(long value) {
  // prints a value of 123 as 12.3
  Serial.print(value / 10);
  Serial.print('.');
  Serial.print(value % 10);
  Serial.println();
  lcd.setCursor(10, 1);
  lcd.print(value / 10);
  lcd.setCursor(12, 1);
  lcd.print('.');
  lcd.setCursor(13, 1);
  lcd.print(value % 10);
}

void displayDateTime() {
    DateTime now = RTC.now();
    int span = 10;
    long aRead = 0;
    unsigned long tmp;
      
    tmp = now.year();
    Serial.print(now.year(), DEC);
    lcd.setCursor(0, 0);
    lcd.print(tmp);
    Serial.print('/');
    lcd.setCursor(4, 0);
    lcd.print("-");
    
    tmp = now.month();
    if (now.month() < 10) {
      Serial.print('0');
      Serial.print(now.month(), DEC);
      lcd.setCursor(5, 0);
      lcd.print('0');
      lcd.setCursor(6, 0);
      lcd.print(tmp);
    }
    else {
      Serial.print(now.month(), DEC);
      lcd.setCursor(5, 0);
      lcd.print(tmp);
    }
    Serial.print('/');
    lcd.setCursor(7, 0);
    lcd.print('-');
    
    tmp = now.day();
    if (now.day() < 10) {
      Serial.print('0');
      Serial.print(now.day());
      lcd.setCursor(8, 0);
      lcd.print('0');
      lcd.setCursor(9, 0);
      lcd.print(tmp);
    }
    else {
      Serial.print(now.day(), DEC);
      lcd.setCursor(8, 0);
      lcd.print(tmp);
    }
    Serial.print(' ');
    
    tmp = now.hour();
    if (now.hour() < 10) {
      Serial.print('0');
      Serial.print(now.hour(), DEC);
      lcd.setCursor(0, 1);
      lcd.print('0');
      lcd.setCursor(1, 1);
      lcd.print(tmp);
    }
    else {
      Serial.print(now.hour(), DEC);
      lcd.setCursor(0, 1);
      lcd.print(tmp);
    }
    Serial.print(':');
    lcd.setCursor(2, 1);
    lcd.print(':');
    
    tmp = now.minute();
    if (now.minute() < 10) {
      Serial.print('0');
      Serial.print(now.minute(), DEC);
      lcd.setCursor(3, 1);
      lcd.print('0');
      lcd.setCursor(4, 1);
      lcd.print(tmp);
    }
    else {
      Serial.print(now.minute(), DEC);
      lcd.setCursor(3, 1);
      lcd.print(tmp);
    }
    Serial.print(':');
    lcd.setCursor(5, 1);
    lcd.print(':');
    
    tmp = now.second();
    if (now.second() < 10) {
      Serial.print('0');
      Serial.print(now.second(), DEC);
      lcd.setCursor(6, 1);
      lcd.print('0');
      lcd.setCursor(7, 1);
      lcd.print(tmp);
    }
    else {
      Serial.print(now.second(), DEC);
      lcd.setCursor(6, 1);
      lcd.print(tmp);
    }
    Serial.print (' ');
    lcd.setCursor(8, 1);
    lcd.print(' ');
    // Serial.println();
    
    for (int i=0;i<span;i++) {
      aRead = aRead + analogRead(potPin);
      // Serial.print(aRead);
      // Serial.print(' ');
    }
    // aRead = aRead / span;
    temperature = (aRead / span * 500.0 / 1024.0);
    // Serial.print(aRead);
    // Serial.print(' ');
    // Serial.print(temperature);
    // Serial.print(' ');
    printTenths(long (temperature * 10));
    lcd.setCursor(14, 1);
    lcd.print(char(223));
    lcd.setCursor(15, 1);
    lcd.print('C');
        
    delay(200);
    
    // Serial.print(" since 2000 = ");
    // Serial.print(now.get());
    // Serial.print("s = ");
    // Serial.print(now.get() / 86400L);
    // Serial.println("d");
    
    // calculate a date which is 7 days and 30 seconds into the future
    // DateTime future (now.get() + 7 * 86400L + 30);
    
    // Serial.print(" now + 7d + 30s: ");
    // Serial.print(future.year(), DEC);
    // Serial.print('/');
    // Serial.print(future.month(), DEC);
    // Serial.print('/');
    // Serial.print(future.day(), DEC);
    // Serial.print(' ');
    // Serial.print(future.hour(), DEC);
    // Serial.print(':');
    // Serial.print(future.minute(), DEC);
    // Serial.print(':');
    // Serial.print(future.second(), DEC);
    // Serial.println();
    
    // Serial.println();
    // delay(3000);
}