//V1 - original release

#include <Wire.h>
#include <RTClib.h>

RTC_DS1307 RTC;

int hours; //24 hour time on the RTC
int hh; //time displayed - adjusted to 12 hour mode
int mm;
int ss;
int timecc;

//pinouts for when the display is flipped upside down (so decimals are on the top - to be used as AM/PM indicators)
int segmentD = 2;
int segmentE = 3;
int segmentF = 4;
int segmentA = 5;
int segmentB = 6;
int segmentC = 7;
int segmentG = 8;
int ampm = 9;
int digitOne = 13;
int digitTwo = 12;
int digitThree = 11;
int digitFour = 10;
int hoursButton = A0;
int minsButton = A1;
int decimal = A2;
void setup() {

  pinMode(segmentA, OUTPUT);
  pinMode(segmentB, OUTPUT);
  pinMode(segmentC, OUTPUT);
  pinMode(segmentD, OUTPUT);
  pinMode(segmentE, OUTPUT);
  pinMode(segmentF, OUTPUT);
  pinMode(segmentG, OUTPUT);
  pinMode(digitOne, OUTPUT);
  pinMode(decimal, OUTPUT);
  pinMode(digitTwo, OUTPUT);
  pinMode(digitThree, OUTPUT);
  pinMode(digitFour, OUTPUT);

  pinMode(hoursButton, INPUT);
  pinMode(minsButton, INPUT);

  Serial.begin(9600);
  Wire.begin();
  RTC.begin();  

  //Set time on RTC
  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(__DATE__, __TIME__));
  }

  //set SQW on RTC to 1 hz for flashing colon
  Wire.beginTransmission(104);
  Wire.write(0x0E); // point to SQW address
  Wire.write(0b00000000); // send 1Hz
  Wire.endTransmission();
}

void loop() {

  DateTime now = RTC.now(); //time from the RTC in 24 hour mode
  hours = now.hour(); //used to check AM/PM status
  mm = now.minute();
  ss = now.second(); 

  //pass RTC values into a new variable -
  //this way one variable stores time in 24 hour mode and another that can be converted to 12 hour mode
  //time is monitored 'in the background' in 24 hour mode using the RTC, but is displayed in an adjusted 12-hr format
  hh = hours;

  //convert to 12 hr mode for display
  if (hours < 1) {
    hh = 12;
  }

  if ((hours > 12) && (hours < 24)) {
    hh = hours - 12;
  }

  //format time to be displayed
  timecc = hh*100+mm;
  showNum(timecc);

  //hours button pressed
  if (digitalRead(hoursButton) == LOW) {
    //debounce
    delay(200);
    hours++;

    if (hours > 23) {
      hours = 0;
    }

    updateRTC();
  } 

  //minutes button pressed
  if (digitalRead(minsButton) == LOW) {
    //debounce
    delay(200);

    mm++;
    ss = 0;

    if (mm >59) {
      mm = 0;
    }

    updateRTC();
  }

} //end of loop


void showNum(int n) {

  //display digit X
  //digit 1 - only display if time is greater thatn 9:59
  int n1 = (n%10000)/1000;
  if (n > 999) {
    printNumber(n1,1);
  }
  delay(4);

  //digit 2
  int n2 = (n%1000)/100;
  printNumber(n2,2); 
  delay(4);

  //digit 3
  int n3 = (n%100)/10;
  printNumber(n3,3);
  delay(4);

  //digit 4
  int n4 = n%10;
  printNumber(n4,4); 
  delay(4);

}

void printNumber(int n, int d) {

  //d is the display to illuminate
  if(d==1)  {
    digitalWrite(digitOne,HIGH);
    digitalWrite(digitTwo,LOW);
    digitalWrite(digitThree,LOW);
    digitalWrite(digitFour,LOW);

    //toggle AM/PM indicator
    if ((hours == 12) || (hours == 22) || (hours == 23)) {
      //PM
      digitalWrite(decimal,LOW); //decimal on
    } 
    else {
      //AM
      digitalWrite(decimal,HIGH); //decimal off
    }
  } 

  if(d==2) {
    digitalWrite(digitOne,LOW);
    digitalWrite(digitTwo,HIGH);
    digitalWrite(digitThree, LOW);
    digitalWrite(digitFour,LOW);

    //toggle AM/PM indicator
    if ((hours > 12) && (hours < 22)) {
      //PM
      digitalWrite(decimal,LOW); //decimal on
    } 
    else {
      //AM
      digitalWrite(decimal,HIGH); //decimal off
    }
  }

  if(d==3) {
    digitalWrite(digitOne,LOW);
    digitalWrite(digitTwo,LOW);
    digitalWrite(digitThree,HIGH);
    digitalWrite(digitFour,LOW);
    digitalWrite(decimal,HIGH); //decimal off
  }

  if(d==4) {
    digitalWrite(digitOne,LOW);
    digitalWrite(digitTwo,LOW);
    digitalWrite(digitThree,LOW);
    digitalWrite(digitFour,HIGH);
    digitalWrite(decimal,HIGH); //decimal off
  }

  //n is for the number to be displayed
  switch(n) {
  case 0:
    digitalWrite(segmentA,LOW);
    digitalWrite(segmentB,LOW);
    digitalWrite(segmentC,LOW);
    digitalWrite(segmentD,LOW);
    digitalWrite(segmentE,LOW);
    digitalWrite(segmentF,LOW);
    digitalWrite(segmentG,HIGH);
    break;

  case 1:
    digitalWrite(segmentA,HIGH);
    digitalWrite(segmentB,LOW);
    digitalWrite(segmentC,LOW);
    digitalWrite(segmentD,HIGH);
    digitalWrite(segmentE,HIGH);
    digitalWrite(segmentF,HIGH);
    digitalWrite(segmentG,HIGH);
    break;

  case 2:
    digitalWrite(segmentA,LOW);
    digitalWrite(segmentB,LOW);
    digitalWrite(segmentC,HIGH);
    digitalWrite(segmentD,LOW);
    digitalWrite(segmentE,LOW);
    digitalWrite(segmentF,HIGH);
    digitalWrite(segmentG,LOW);
    break;

  case 3:
    digitalWrite(segmentA,LOW);
    digitalWrite(segmentB,LOW);
    digitalWrite(segmentC,LOW);
    digitalWrite(segmentD,LOW);
    digitalWrite(segmentE,HIGH);
    digitalWrite(segmentF,HIGH);
    digitalWrite(segmentG,LOW);
    break;

  case 4:
    digitalWrite(segmentA,HIGH);
    digitalWrite(segmentB,LOW);
    digitalWrite(segmentC,LOW);
    digitalWrite(segmentD,HIGH);
    digitalWrite(segmentE,HIGH);
    digitalWrite(segmentF,LOW);
    digitalWrite(segmentG,LOW);
    break;

  case 5:
    digitalWrite(segmentA,LOW);
    digitalWrite(segmentB,HIGH);
    digitalWrite(segmentC,LOW);
    digitalWrite(segmentD,LOW);
    digitalWrite(segmentE,HIGH);
    digitalWrite(segmentF,LOW);
    digitalWrite(segmentG,LOW);
    break;

  case 6:
    digitalWrite(segmentA,LOW);
    digitalWrite(segmentB,HIGH);
    digitalWrite(segmentC,LOW);
    digitalWrite(segmentD,LOW);
    digitalWrite(segmentE,LOW);
    digitalWrite(segmentF,LOW);
    digitalWrite(segmentG,LOW);
    break;

  case 7:
    digitalWrite(segmentA,LOW);
    digitalWrite(segmentB,LOW);
    digitalWrite(segmentC,LOW);
    digitalWrite(segmentD,HIGH);
    digitalWrite(segmentE,HIGH);
    digitalWrite(segmentF,HIGH);
    digitalWrite(segmentG,HIGH);
    break;

  case 8:
    digitalWrite(segmentA,LOW);
    digitalWrite(segmentB,LOW);
    digitalWrite(segmentC,LOW);
    digitalWrite(segmentD,LOW);
    digitalWrite(segmentE,LOW);
    digitalWrite(segmentF,LOW);
    digitalWrite(segmentG,LOW);
    break;

  case 9:
    digitalWrite(segmentA,LOW);
    digitalWrite(segmentB,LOW);
    digitalWrite(segmentC,LOW);
    digitalWrite(segmentD,LOW);
    digitalWrite(segmentE,HIGH);
    digitalWrite(segmentF,LOW);
    digitalWrite(segmentG,LOW);
    break;
  }
}

byte decToBcd(byte val) {
  return ( (val/10*16) + (val%10) );
}

byte bcdToDec(byte val) {
  return ( (val/16*10) + (val%16) );
}

void updateRTC() {
  Wire.beginTransmission(104);
  Wire.write(0);
  Wire.write(decToBcd(ss));
  Wire.write(decToBcd(mm));
  Wire.write(decToBcd(hours));
  Wire.endTransmission();
}












