RTC Clock

#include 
#include "RTClib.h"

RTC_DS1307 RTC;

/*

Uses 3.5 digit display GL-3P402 without additional hardware - rely on POV for user to see time :)

Pinout:

   D3   Se    Sb    Sd     Sc    D0  Sa
   |    |      |     |      |    |    |

     Dig3     Dig2       Dig1  Dot  Dig0 

   |    |      |     |      |    |
   Sf   D2    Sg    D1     Dot+  Dot-

S = segment
D = digit

Segments:

         aaa
        b   c
        b   c
         ddd
        e   f
        e   f
         ggg 

TinyRTC I2C module connected as follows: 

TinyRTC VCC - Arduino 5V
TinyRTC GND - Arduino GND
TinyRTC SDA - Arduino A4
TinyRTC SCL - Arduino A5

*/

// pins for selecting segments
int   pinA = 4;
int   pinB = 5;
int   pinC = 6;
int   pinD = 7;
int   pinE = 8;
int   pinF = 9;
int   pinG = 10;
int   pinDot = 13;

// pins for selecting digits
int   dig0 = 12;
int   dig1 = 11;
int   dig2 = 3;
int   dig3 = 2;
int   dot = 1;

// init
void setup()
{
  // init Wire library for I2C comms
  Wire.begin();
  // init Clock library
  RTC.begin();

  // if its not already running start it
  if (! RTC.isrunning()) {
    // reset the halt bit to make sure it runs
    RTC.adjust(DateTime(0,0));
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }

  // configure all as outputs - this is COMMON CATHODE display so inverse of what you expect
  pinMode(pinA,OUTPUT);
  pinMode(pinB,OUTPUT);
  pinMode(pinC,OUTPUT);
  pinMode(pinD,OUTPUT);
  pinMode(pinE,OUTPUT);
  pinMode(pinF,OUTPUT);
  pinMode(pinG,OUTPUT);
  pinMode(pinDot,OUTPUT);

  // we use INPUT_PULLUP to isolate unselected digits by sinking the signals
  pinMode(dig0,INPUT_PULLUP);
  pinMode(dig1,INPUT_PULLUP);
  pinMode(dig2,INPUT_PULLUP);
  pinMode(dig3,INPUT_PULLUP);

  // dot is independent - not multiplexed
  pinMode(dot,OUTPUT);
}

void loop()
{
  // get the latest time
  DateTime now = RTC.now();

  int iM1 = now.minute() % 10;
  int iM2 = now.minute() / 10;
  int iH2 = now.hour() % 10;
  int iH1 = now.hour() / 10;
  int iS = now.second();

  // enable one digit at a time and send the number to it
  pinMode(dig0,OUTPUT);
  DoNum(iM1);
  pinMode(dig0,INPUT_PULLUP);

  pinMode(dig1,OUTPUT);
  DoNum(iM2);
  pinMode(dig1,INPUT_PULLUP);

  pinMode(dig2,OUTPUT);
  DoNum(iH2);
  pinMode(dig2,INPUT_PULLUP);

  pinMode(dig3,OUTPUT);
  if (iH1 == 0)
  {
    blank();
  }
  else
  {
    DoNum(iH1);
  }
  pinMode(dig3,INPUT_PULLUP);

  digitalWrite(pinDot, (iS & 1) ? LOW : HIGH);
}

// blank is no signals
void blank()
{
  outNum(B00000000);
}

// output a number - send binary pattern in sequence to pins
// each bit relates to one segment - top bit not used
void DoNum(int i)
{
  switch(i)
  {
    case 0:
      outNum(B01110111);
      break;

    case 1:
      outNum(B00010010);
      break;

    case 2:
      outNum(B01011101);
      break;

    case 3:
      outNum(B01011011);
      break;

    case 4:
      outNum(B00111010);
      break;

    case 5:
      outNum(B01101011);
      break;

    case 6:
      outNum(B01101111);
      break;

    case 7:
      outNum(B01010010);
      break;

    case 8:
      outNum(B01111111);
      break;

    case 9:
      outNum(B01111011);;
      break;
  }
}

void outNum(byte bNum)
{
  // cycle through all pins and set to correct thing for pin
  // delay if we turn it on so users eye can see it
  int iSeg[7] = { pinA, pinB, pinC, pinD, pinE, pinF, pinG };
  for (int i=0; i<8; i++)
  {
    bNum = bNum << 1;
    if (bNum & 128)
    {
      digitalWrite(iSeg[i], LOW);
      delayMicroseconds(1600);
    }
    digitalWrite(iSeg[i], HIGH);
  }
}

2 thoughts on “RTC Clock

Leave a Reply

Your email address will not be published. Required fields are marked *