You are on page 1of 13

// Build 1

//   r1 150214 - initial build with glyphs and big font character table in program memory
//   r2 150227 - added RTC support
//************************************************************
#define build 1
#define revision 2
//************************************************************
 
#include "avr/pgmspace.h" // for memory storage in program space
 
#include "Wire.h"
#include "LiquidCrystal_I2C.h" // library for I@C interface
 
LiquidCrystal_I2C lcd(0x27, 20, 4);
 
#define DS3231_I2C_ADDRESS 0x68
byte decToBcd(byte val){ return( (val/10*16) + (val%10) ); }
byte bcdToDec(byte val){ return( (val/16*10) + (val%16) ); }
 
void readDS3231time(byte *second,byte *minute,byte *hour,byte *dayOfWeek,byte
*dayOfMonth,byte *month,byte *year){
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0); // set DS3231 register pointer to 00h
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
  // request seven bytes of data from DS3231 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());
}
 
void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte dayOfMonth,
byte month, byte year)
{
  // sets time and date data to DS3231
  Wire.beginTransmission(DS3231_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();
}
 
 
const char custom[][8] PROGMEM = {
  {0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x0f, 0x1f}, // char 1: top left triangle
  {0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x1f, 0x1f}, // char 2: upper block
  {0x00, 0x00, 0x00, 0x00, 0x10, 0x1c, 0x1e, 0x1f}, // char 3: top right triangle
  {0x1f, 0x0f, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00}, // char 4: bottom left triangle
  {0x1f, 0x1e, 0x1c, 0x10, 0x00, 0x00, 0x00, 0x00}, // char 5: bottom right triangle
  {0x1f, 0x1f, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00}, // char 6: bottom block
  {0x1f, 0x1f, 0x1e, 0x1c, 0x18, 0x18, 0x10, 0x10}  // char 7: full top right triangle
                                                    // room for another one!
};
 
const char bn[][30] PROGMEM = { // organized by row
//         0               1               2               3               4              5               6                7              
8               9
    {0x01,0x02,0x03, 0x01,0x02,0xFE, 0x01,0x02,0x03, 0x01,0x02,0x03, 0x02,0xFE,0x02,
0x02,0x02,0x02, 0x01,0x02,0x03, 0x02,0x02,0x02, 0x01,0x02,0x03, 0x01,0x02,0x03},
    {0xff,0xfe,0xff, 0xFE,0xFF,0xFE, 0x01,0x02,0xFF, 0xFE,0x02,0xFF, 0xFF,0x02,0xFF,
0xFF,0x02,0x02, 0xFF,0x02,0x03, 0xFE,0x01,0x07, 0xFF,0x02,0xFF, 0xFF,0xFE,0xFF},
    {0xff,0xfe,0xff, 0xFE,0xFF,0xFE, 0xFF,0xFE,0xFE, 0xFE,0xFE,0xFF, 0xFE,0xFE,0xFF,
0xFE,0xFE,0xFF, 0xFF,0xFE,0xFF, 0xFE,0xFF,0xFE, 0xFF,0xFE,0xFF, 0x04,0x06,0xFF},
    {0x04,0x06,0x05, 0xFE,0x06,0xFE, 0x06,0x06,0x06, 0x04,0x06,0x05, 0xFE,0xFE,0x06,
0x04,0x06,0x05, 0x04,0x06,0x05, 0xFE,0x06,0xFE, 0x04,0x06,0x05, 0xFE,0xFE,0x06}
};
 
byte col, row, nb=0, bc=0; // general
byte bb[8]; // byte buffer for reading from PROGMEM
int Mode = 0;
#include "RTClib.h"
RTC_Millis RTC;
byte hr, mn, se, osec;
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
volatile boolean buttonA = false;
volatile boolean buttonB = false;
volatile boolean buttonC = false;
int StateOfbuttonA = 0;
int StateOfbuttonB = 0;  
int StateOfbuttonC = 0;        
int NewStateOfbuttonA = 0;        
int NewStateOfbuttonB = 0;        
int NewStateOfbuttonC = 0;
 
uint8_t degC[] = { 6, 3, 3, 56, 68, 68, 68 }; // Deg C
 
char *mon2str(uint8_t mon, char *psz, uint8_t len)
 
// Get a label from PROGMEM into a char array
{
  const __FlashStringHelper* const Jan = F("Jan");
   const __FlashStringHelper* const Feb = F("Feb");
   const __FlashStringHelper* const Mar = F("Mar");
   const __FlashStringHelper* const Apr = F("Apr");
   const __FlashStringHelper* const May = F("May");
   const __FlashStringHelper* const Jun = F("Jun");
   const __FlashStringHelper* const Jul = F("Jul");
   const __FlashStringHelper* const Aug = F("Aug");
   const __FlashStringHelper* const Sep = F("Sep");
   const __FlashStringHelper* const Oct = F("Oct");
   const __FlashStringHelper* const Nov = F("Nov");
   const __FlashStringHelper* const Dec = F("Dec");
  
   const __FlashStringHelper* str[] =
  {
    Jan, Feb, Mar, Apr,
    May, Jun, Jul, Aug,
    Sep, Oct, Nov, Dec
  };
}
 
char *dow2str(uint8_t code, char *psz, uint8_t len)
{
   const __FlashStringHelper* const Sunday = F("Sunday");
   const __FlashStringHelper* const Monday = F("Monday");
   const __FlashStringHelper* const Tuesday = F("Tuesday");
   const __FlashStringHelper* const Wednesday = F("Wednesday");
   const __FlashStringHelper* const Thursday = F("Thursday");
   const __FlashStringHelper* const Friday = F("Friday");
   const __FlashStringHelper* const Saturday = F("Saturday");
  
   const __FlashStringHelper*  str[] =
  {
  Sunday, Monday, Tuesday,
  Wednesday, Thursday,Friday,
  Saturday ,Sunday
  };
}
 
  
//*********************** INITIAL SETUP ***********************
void setup() {
  randomSeed(analogRead(0));
  RTC.begin(DateTime(__DATE__, __TIME__));
  Serial.begin(9600);
  
  lcd.init(); // initialize the LCD
  lcd.backlight();
  lcd.begin(20, 4);
  
  for (nb=0; nb<7; nb++ ) { // create 8 custom characters
    for (bc=0; bc<8; bc++) bb[bc]= pgm_read_byte( &custom[nb][bc] );
    lcd.createChar( nb+1, bb );
  }
  
  lcd.clear();
  lcd.setCursor(4, 0);
  lcd.print(F("4-Line LARGE"));
  lcd.setCursor(4, 1);
  lcd.print(F("TIME DISPLAY"));
  lcd.setCursor(5, 3);
  lcd.print(F("V"));
  lcd.print(build);
  lcd.print(F("."));
  lcd.print(revision);
  lcd.print(F(" "));
  //lcd.print(freeRam());
  lcd.print(F("B"));
// printNum(random(0,10),0);
// printNum(random(0,10),17);
  delay(500);
  lcd.clear();
readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month,
  &year);
//hour=hour+1;
  //setDS3231time(second,minute, hour, dayOfWeek, dayOfMonth, month,year);
  //setDS3231time(30,42,21,4,26,11,14);
}
 
//************************* MAIN LOOP ************************
void loop() {
 
datetinme_print();
timesetup();
  
}
/*
// ******************* OPERATION ROUTINES ********************
// FREERAM: Returns the number of bytes currently free in RAM  
int freeRam(void) {
  extern int  __bss_end, *__brkval;
  int free_memory;
  
  if((int)__brkval == 0) {
    free_memory = ((int)&free_memory) - ((int)&__bss_end);
  } else {
    free_memory = ((int)&free_memory) - ((int)__brkval);
  }
  return free_memory;
}*/
void datetinme_print(){
readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month,
  &year);
 
// DateTime now = RTC.now();
  hr =hour;
  mn = minute;
  se = second;
  
  if(se != osec) {
    printNum(hr/10,0);
    printNum(hr%10,3);
    printColon(6);
    printNum(mn/10,7);
    printNum(mn%10,10);
    printColon(13);
    printNum(se/10,14);
    printNum(se%10,17);
    osec = se;
  }
  delay(50); // not strictly necessary
 
}
 
// ********************** SUBROUTINES ************************
void printNum(byte digit, byte leftAdjust) {
  for(row=0; row<4; row++) {
    lcd.setCursor(leftAdjust,row);
    for(col=digit*3; col <digit*3+3; col++) {
      lcd.write(pgm_read_byte( &bn[row][col]) );
    }
  }
}
 
void printColon(byte leftAdjust) {
  for(row=0; row<4; row++) {
    lcd.setCursor(leftAdjust,row);
    if(row == 1 || row == 2) lcd.print(F(".")); else lcd.print(F(" "));
  }
 
}
 
void timesetup(){
   Serial.println(Mode);
    NewStateOfbuttonA = digitalRead(3);
  NewStateOfbuttonB = digitalRead(4);
  NewStateOfbuttonC =   digitalRead(5);
  buttonAisPressed();
  buttonBisPressed();
  buttonCisPressed();
  
if (buttonB) {
    buttonB = false;
      Mode++;
    
      if (Mode > 4 ) {
      Mode = 0;
  }
}
 
  if (buttonA) {
   if (Mode == 0 ) {
    buttonA = false;
  /*  contrast++;
    if (contrast >= 51 ) {
    contrast = 50;*/
  }
      
  else if (Mode == 1 ) {
    buttonA = false;
     // Mode = 0;
  }
  else if (Mode == 2 ) {
    buttonA = false;
    hour++;
    if (hour >= 24 ) {
    hour = 0;
  }
   Serial.println("up");
    setDS3231time(second,minute, hour, dayOfWeek, dayOfMonth, month,year);
  }
  else if (Mode == 3 ) {
    buttonA = false;
    minute++;
    if (minute >= 60 ) {
    minute = 0;
  }
    setDS3231time(second,minute, hour, dayOfWeek, dayOfMonth, month,year);
  }
  else if (Mode == 4 ) {
    buttonA = false;
     second = 0;
    setDS3231time(second,minute, hour, dayOfWeek, dayOfMonth, month,year);
  }
  else if (Mode == 5 ) {
    buttonA = false;
    dayOfWeek++;
    if (dayOfWeek >= 8 ) {
    dayOfWeek = 1;
  }
    setDS3231time(second,minute, hour, dayOfWeek, dayOfMonth, month,year);
   //P.displayReset(2);
  }
  else if (Mode == 6 ) {
    buttonA = false;
    dayOfMonth++;
    if (dayOfMonth >= 32 ) {
    dayOfMonth = 1;
  }
    setDS3231time(second,minute, hour, dayOfWeek, dayOfMonth, month,year);
  }    
  else if (Mode == 7 ) {
    buttonA = false;
    month++;
    if (month >= 13 ) {
    month = 1;
  }
    setDS3231time(second,minute, hour, dayOfWeek, dayOfMonth, month,year);
  }      
  else if (Mode == 8 ) {
    buttonA = false;
    year++;
    if (year >= 2035 ) {
    year = 2015;
  }  
    setDS3231time(second,minute, hour, dayOfWeek, dayOfMonth, month,year);
      
  }
  }
 
    
    
   if (buttonC) {
   if (Mode == 0 ) {
    buttonC = false;
  //  contrast--;
   // if (contrast <= 0 ) {
   // contrast = 0;
  //}
    }  
  else if (Mode == 1 ) {
    buttonC = false;
     // Mode = 0;
  }
  else if (Mode == 2 ) {
    buttonC = false;
    hour--;
    if (hour <= 0 ) {
    hour = 23;
  } Serial.println("Down");
    setDS3231time(second,minute, hour, dayOfWeek, dayOfMonth, month,year);
  }
  else if (Mode == 3 ) {
    buttonC = false;
    minute--;
    if (minute <= 0 ) {
    minute = 59;
  }
    setDS3231time(second,minute, hour, dayOfWeek, dayOfMonth, month,year);
  }
  else if (Mode == 4 ) {
    buttonC = false;
     second = 0;
    setDS3231time(second,minute, hour, dayOfWeek, dayOfMonth, month,year);
  }
  else if (Mode == 5 ) {
    buttonC = false;
    dayOfWeek--;
    if (dayOfWeek <= 0 ) {
    dayOfWeek = 7;
  }
    setDS3231time(second,minute, hour, dayOfWeek, dayOfMonth, month,year);
    //P.displayReset(2);
  }
  else if (Mode == 6 ) {
    buttonC = false;
    dayOfMonth--;
    if (dayOfMonth <= 0 ) {
    dayOfMonth = 31;
  }
    setDS3231time(second,minute, hour, dayOfWeek, dayOfMonth, month,year);
  }    
  else if (Mode == 7 ) {
    buttonC = false;
    month--;
    if (month <= 0 ) {
    month = 12;
  }
    setDS3231time(second,minute, hour, dayOfWeek, dayOfMonth, month,year);
  }      
  else if (Mode == 8 ) {
    buttonC = false;
    year--;
    if (year <= 2010 ) {
    year = 2025;
  }
    setDS3231time(second,minute, hour, dayOfWeek, dayOfMonth, month,year);;
  }  
       }
 
  if (Mode == 0)
  {
  static uint32_t lastTime = 0; // millis() memory
  static bool flasher = false;  // seconds passing flasher
 
    if (millis() - lastTime >= 1000)
  {
    lastTime = millis();
    
    flasher = !flasher;
  
  }
  }
 
  if (Mode == 1)
  {
  static uint8_t  display = 0;  // current display mode
 
  {
    switch (display)
    {
      case 0: // Time
       datetinme_print();
        break;
 
      case 1: // Day
      
        break;
 
      case 2:  // Calendar
    
        break;
    }
 
    
  }
  }
  
    if (Mode == 2)
  {
  static uint32_t lastTime = 0; // millis() memory
  static bool flasher = false;  // seconds passing flasher
    if (millis() - lastTime >= 200)
  
  {
    lastTime = millis();
   // lcd.setCursor(4,1);
    //lcd.setCursor(6,4);
    lcd.cursor();
   printNum(hr/10,0);
    printNum(hr%10,3);
    flasher = !flasher;
    
  }
  }
  
    if (Mode == 3)
  {
  static uint32_t lastTime = 0; // millis() memory
  static bool flasher = false;  // seconds passing flasher
 
    if (millis() - lastTime >= 200)
  {
    lastTime = millis();
    printColon(6);
   printNum(mn/10,7);
    printNum(mn%10,10);
    flasher = !flasher;
    
  }
  }
  
    if (Mode == 4)
  {
  static uint32_t lastTime = 0; // millis() memory
  static bool flasher = false;  // seconds passing flasher
 
    if (millis() - lastTime >= 200)
  {
    lastTime = millis();
    printColon(13);
    printNum(se/10,14);
    printNum(se%10,17);
  }
  }
  
    if (Mode == 5)
  {
  static uint8_t  display = 0;  // current display mode
 
 
  }
  
    if (Mode == 6)
  {
/* P.displayAnimate();
  P.getZoneStatus(2);
    P.setTextEffect(2, PA_PRINT, PA_NO_EFFECT);
        getdyy(szMesg);
    P.displayReset(2);*/
  }
 
    if (Mode == 7)
  {
   /*P.displayAnimate();
  P.getZoneStatus(2);
    P.setTextEffect(2, PA_PRINT, PA_NO_EFFECT);
        getmon(szMesg);
    P.displayReset(2);*/
  }
 
    if (Mode == 8)
  {
  /* P.displayAnimate();
  P.getZoneStatus(2);
    P.setTextEffect(2, PA_PRINT, PA_NO_EFFECT);
        getyyyy(szMesg);
    P.displayReset(2);*/
  }
  
}
 
  void buttonAisPressed()
  {
    if (NewStateOfbuttonA != StateOfbuttonA)
  {
    if (NewStateOfbuttonA == 0)
    {
      buttonA=true;
    }
    delay(50);
  }
   StateOfbuttonA = NewStateOfbuttonA;
  }
 
void buttonBisPressed()
{
  if (NewStateOfbuttonB != StateOfbuttonB)
  {
    if (NewStateOfbuttonB == 0) {
      buttonB=true;
    }
    delay(50);
  }
   StateOfbuttonB = NewStateOfbuttonB;
}
 
void buttonCisPressed()
{
   if (NewStateOfbuttonC != StateOfbuttonC)
  {
    if (NewStateOfbuttonC == 0) {
      buttonC=true;
    }
    delay(50);
  }
   StateOfbuttonC = NewStateOfbuttonC;
}

You might also like