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

No comments:

Post a Comment