Home    Master Clock   LCD Master Clock    Kenley Weather

Section   Top  Specs   Intro   Background  Schematic Construction    Vero Layout  Reading The Displays  Code

 

 

 

Arduino 7 Segment Display Binary Clock

7 Segment Display of Binary Time, Binary Coded Decimal Time & Binary Date

 

7 Segment Binary Display Animated Loop

 

 

Specs

3 rows of 8 seven segment displays show time and date in binary

Main clock display can be remotely switched between full binary time display, binary coded decimal time and full binary display of date

Time and date is synchronized to the DCF77 time code transmitter is Germany.

Main display brightness is auto adjusted to room level.

PIR sensor automatically shuts down the main 7 segment display and LCD display when no movement is detected.

USB connection for serial programming and reading via a CP2102 USB to UART / TTL Adapter

There is also a DCF77 Signal Match output to the WIFI board on my Arduino Radiation Monitor.

This allows me to monitor the signal reception for all my clocks.

 

 

 

  

Display Modes

The Clock has three different displays that are switched by the remote control

The LCD display shows the display mode Binary Date, BCD Time & Binary Time

In all modes the LCD display can be used to help decode the Binary display

 

 

 

 

 

BCD Display

Individual Decimal numbers are split into binary code

Top row Hours

Middle row Minutes

Bottom row Seconds

 

 

 

 

 

     

Full Binary Display

The complete Decimal number is shown as Binary

Top row Hours

Middle row Minutes

Bottom row Seconds

 

 

 

 

 

 

 

Binary Date Display

The date is shown in full Binary- note LCD date is in UK format dd/mm/yy

Top row Day

Middle row Month

Bottom row Year (0 to 99)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Demo Video showing Binary display modes. The Binary clock is silent, the ticking and chiming on the video is from my LCD Master Clock just visible in the far right of the video

 

 

 

 

 

Introduction

An Arduino 328 Microprocessor is used to decode and display Time & date from the DCF77 "Atomic" Clock in Mainflingen near Frankfurt Germany

The DCF77 signal is decoded using the fantastic new DCF77 library written by Udo Klein meaning the clock stays in sync and keeps perfect time even with a massive amount of noise on the received DCF77 signal

Udo Klein's DCF77 library continually "Auto Tunes" the quartz crystal so in the rare event the signal can't be decoded the clock remains accurate within 1 sec over many days

I don't want any switches on the clock so time display modes switching are carried out by 433MHZ remote control

 

 

 

 

Background

Old clocks/previous designs

My first Binary clock was built in 1985 and was built into an old pendulum clock.

The pendulum operated a contact every 0.5 second and drove the Binary Coded Decimal LED display via 5v TTL logic.

 

 

The animation above and picture below shows the binary clock I built in 1996.

It uses CMOS logic and LEDs to display full binary time.

 

While they were nice to look at it was very difficult to read in dim lights as any LEDs that were off made it hard to see the value of the LEDs that were on.

 

Above - the same clock viewed in the dark.

The displayed time is illegible as the binary 0s are invisible so you are not able to see what value the binary 1s are indicating.

 

 

What I needed was to show the Binary 1s and 0s on 7 segment displays. At the time it was too difficult and too expensive to consider so in the late 1990's  while learning Visual Basic

I built a software version " Windows Binary Clock" as a proof of concept.

 

below looped animation of my Windows Binary Clock

The Windows Binary Clock displays time in Binary Coded Decimal.

The top row is hours the middle minutes and the bottom seconds.

The 2 columns are split into tens and units.

 

This really basic program still seems to work in all versions of Windows and can be downloaded below.

On loading press Setup to show help digits or to select AMD or Intel if the display does not show all digits.

Download Binary_Clock.exe

 

 

With the advent of cheep modular displays and Microprocessors I am now able to build a hardware version of the clock.

7 Segment Display Binary Clock hardware test setup

 

 

I have decided to have 3 wireless remote control switched displays on the clock.

1. Full Binary display of the Time

2. Full Binary display of the Date

3. Binary Coded Decimal display of the Time

see animation below for available display modes

 

 

 

 

 

Construction

Main Binary 7 segment display modules.

Each module has 8 digits so I can display in BCD or full binary as required.

7 segment display modules available from Tindie

Red and Green displays also available

see this page for full details Yellow 7 segment module from Tindie

 

 

 

 

Clock main board. 7 segment LED displays are mounted on the headers.

The main board is vero painted matt black and will only take a few hours to wire up

 

 

 

 

 

 

Main Vero Board Layout

Main Vero board layout with board shown in it's natural white colour for clarity.

The board is painted matt black before components are mounted.

Resistor R4, LEDs D2 & D3 along with Rly conn not required.

 

 

Rear of Vero Board flipped down. Note some cable connectors mounted on the rear of the Vero Board.

 

.

 

 

 

 

 

How to read the clock displays

 

Clock showing Time in full Binary.

Top Row Hours 08

Middle Row Minutes 10

Bottom Row Seconds 21

 

 

 

 

Clock showing Time in Binary Coded Decimal.

Top Row Hours- Tens 1  Hours Units 7 = 17

Middle Row Minutes- Tens 2  Minutes Units 3 = 23

Bottom Row Seconds- Tens 1 Seconds Units = 6 = 16

 

 

 

 

 

Clock showing the full Binary Date in UK date format day/mth/year

Top Row Day 30th

Middle Row Month Nov

Bottom Row Year Tens and Units 14 or 2014 (there are not enough digits on the display for 100s and 1000s)

 

 

 

 

A Secondary 4x20 I2C LCD display is used to display time & date, display brightness, sync information,

signal quality, auto tune'd frequency and auto tuned quartz accuracy. The display also shows decimal time and date

which is handy when you are learning to decode the binary displays in your head.

 

 

 

 

 

 

Remote control is over 433MHz wireless link. I found it hard to source a key fob and receiver board in the UK

so I purchased a transmitter and receiver board from Hobby Components LTD. The transmitter was used to program a 433MHz key fob

using the DIY board above.

 

 

 

The receiver is then plugged into the main clock board.

 

 

 

    

Remote control transmitter Front and Back

 

If you don't want do purchase the remote key fob then just connect the transmitter as above.

 

 

 

 

 

 

I do not want the clock on 24/7 and so a PIR is used to switch on the display when motion is detected in the room.

 

 

 

 

Schematic

Pin 15 outputs 1 when the incoming signal has no errors. If there are any errors then the output is 0.

This is fed into my Arduino Radiation Monitor WIFI board so I cam monitor my signal quality on my Android Mobile device.

 

 

 

 

 

 

The Binary Clock uses the following Arduino Libraries.

LedControl.h
dcf77.h Note this clock uses Udo Kleins Release 3 library download here DCF77 Release 3
LiquidCrystal_I2C.h
Wire.h

Code v41
Download

//  Binary Clock using 7 Segment displays
//  http://www.brettoliver.org.uk
//
//  Copyright 2014 Brett Oliver
//
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program. If not, see http://www.gnu.org/licenses/
//
// 
// Based on the DCF77 library by Udo Klein
// http://blog.blinkenlight.net/experiments/dcf77/dcf77-library/
// http://blog.blinkenlight.net/experiments/dcf77/simple-clock/
//

// v29 BCD added
// v32 remote receive LED added
// v34 Sw 4 added to display binary help
// v36 Light levels adjusted
// v37 old unused code deleted
// v38 removed serial.prints to save compile space for Arduino v 1.5.8
// v39 coded to use Udo Klein's v3 library https://github.com/udoklein/dcf77/releases/tag/v3.0.0
// v40 mod to output signal quality on pin 15 "DCFSync" is 1 if Signal match is 100%  this changes once per min
// this outputs to the radiation monitor instead of the rain sensor
// v41 Move DCFSync from void signalmatch() to top of program so it is called every second
#include <LedControl.h>
#include <dcf77.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
using namespace Internal; //v3


/*
 
 ***** MAX7219 PINs *****
 pin 12 is connected to the DataIn 
 pin 11 is connected to the CLK 
 pin 10 is connected to LOAD 
 We have 3x MAX72XX.
 */
LedControl lc=LedControl(12,11,10,3); // 12,11,10 are Arduino pins 3 is number of MAX2719s

/* we always wait a bit between updates of the display */
unsigned long delaytime=250;
//**********************
// set the LCD address to 0x27 for a 20 chars 4 line display
// Set the pins on the I2C chip used for LCD connections:
//                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address


//**********************

const uint8_t dcf77_analog_sample_pin = 5;
const uint8_t dcf77_sample_pin = A1;  // A5 == d19 (DFC77 signal)changed from A5
const uint8_t dcf77_inverted_samples = 0;
const uint8_t dcf77_analog_samples = 0;

const uint8_t dcf77_monitor_led       = A0; // v3
//const uint8_t dcf77_monitor_pin = A0;  // A4 == d18 changed from A4 removed v3
uint8_t ledpin(const uint8_t led){ //v3
  return led; //v3
} //v3
const int8_t timezone_offset = -1;  // GB is one hour behind CET/CEST

int DCFSync = 9; // DCF77 Signal Sync
int infraredSwval = 0; // infrared value
int infraredSw = 17; // set A3 to input ( pin 13)
int summertest = 0; // equals 1 for summertime and 0 for wintertime
int summerwinter = 0; // summer winter toggle
int yearsm = 00; // year showing units and 10s only eg 2014 is 14
int intensity; // 7 segment intensity
int ldr = A2; // LDR connected to analogue A2 pin
unsigned int ldrValue; // LDR value
int signalQual = 0; // computed once per minute and indicates how well
// the received signal matches the locally synthesized reference signal max 50
int signalDCF = 0; // as above used to get DCFSync output to Geiger counter WIFI module

int monthval = 0;
int dayval = 0;
int years = 0;
int months = 0;
int days = 0;
int hours2 = 0; //2nd 7 segment hour digit
int hours1 = 0; //1st 7 segment hour digit
int hours = 0;
int minutes2 = 0; //2nd 7 segment minute digit
int minutes1 = 0; //1st 7 segment minute digit
int minutes = 0;
int seconds2 = 0;  //2nd 7 segment seconds digit
int seconds1 = 0; //1st 7 segment seconds digit
int seconds = 0;
int secsval = 0;
int minsval = 0;
int hourval = 0;
int remote1out =2;  // remote control output 1 is pin 2 (pin 4 on IC)
int remote2out =3;  // remote control output 2 is pin 3 (pin 5 on IC)
//int remote3out =4;  // remote control output 3 is pin 4 (pin 6 on IC)
//int remote4out =13;  // remote control output 4 is pin 13 (pin 19 on IC)

int remote1val; // current value of remote sw no1
int remote1prev = 0; // previous value of remote sw no1
int datesw = 0; // previous value
int remote2val; // current value of remote sw no2
int remote2prev = 0; // previous value of remote sw no2
int EZlinkPwr = 0; // state of power conrol for EZ-Link
int remote3val; // current value of remote sw no3
int remote3prev = 0; // previous value of remote sw no3
int BCDdisplay = 0; // state of BCD display
int remote4val = 0; // current value of remote sw no4
//int remote4prev = 0; // previous value of remote sw no4

int remote1in =8;  // remote control input 1 is pin 8 (pin 14 on IC)
int remote2in =7;  // remote control input 2 is pin 7 (pin 13 on IC)
int remote3in =6;  // remote control input 3 is pin 6 (pin 12 on IC)
int remote4in =5;  // remote control input 4 is pin 5 (pin 11 on IC)
//********************

namespace Timezone {
  uint8_t days_per_month(const Clock::time_t &now) { //v3 mod
    switch (now.month.val) {
    case 0x02:
      // valid till 31.12.2399
      // notice year mod 4 == year & 0x03
    return 28 + ((now.year.val != 0) && ((bcd_to_int(now.year) & 0x03) == 0)? 1: 0);
            case 0x01: case 0x03: case 0x05: case 0x07: case 0x08: case 0x10: case 0x12: return 31;
            case 0x04: case 0x06: case 0x09: case 0x11:                                  return 30;
            default: return 0;
    }
  }   

  void adjust(Clock::time_t &time, const int8_t offset) { //v3 mod
    // attention: maximum supported offset is +/- 23h

    int8_t hour = BCD::bcd_to_int(time.hour) + offset;

    if (hour > 23) {
      hour -= 24;
      uint8_t day = BCD::bcd_to_int(time.day) + 1;
      uint8_t weekday = BCD::bcd_to_int(time.weekday) + 1; //v3
      if (day > days_per_month(time)) {
        day = 1;
        uint8_t month = BCD::bcd_to_int(time.month);
        ++month;
        if (month > 12) {
          month = 1;
          uint8_t year = BCD::bcd_to_int(time.year);                  
          ++year;
          if (year > 99) {
            year = 0;
          }
          time.year = BCD::int_to_bcd(year);
        }                
        time.month = BCD::int_to_bcd(month);
      }
      time.day = BCD::int_to_bcd(day);
      time.weekday = BCD::int_to_bcd(weekday); //v3
    }

    if (hour < 0) {
      hour += 24;
      uint8_t day = BCD::bcd_to_int(time.day) - 1;
      uint8_t weekday = BCD::bcd_to_int(time.weekday) - 1; //v3
      if (day < 1) {
        uint8_t month = BCD::bcd_to_int(time.month);
        --month;
        if (month < 1) {
          month = 12;
          int8_t year = BCD::bcd_to_int(time.year);                  
          --year;
          if (year < 0) {
            year = 99;
          }
          time.year = BCD::int_to_bcd(year);
        }                
        time.month = BCD::int_to_bcd(month);
        day = days_per_month(time);
      }
      time.day = BCD::int_to_bcd(day);
      time.weekday = BCD::int_to_bcd(weekday); //v3
    }

    time.hour = BCD::int_to_bcd(hour);
  }
}

uint8_t sample_input_pin() {
  const uint8_t sampled_data =
    dcf77_inverted_samples ^ (dcf77_analog_samples? (analogRead(dcf77_analog_sample_pin) > 200)
    : digitalRead(dcf77_sample_pin));

  //digitalWrite(dcf77_monitor_pin, sampled_data); // removed v3
  digitalWrite(ledpin(dcf77_monitor_led), sampled_data); // v3
  return sampled_data;
}

void setup() {
  //****** 7 seg
  /*
   The MAX72XX is in power-saving mode on startup,
   we have to do a wakeup call for all 3 modules
   */
  lc.shutdown(0,false);
  lc.shutdown(1,false);
  lc.shutdown(2,false);
  /* Set the brightness to a medium values */
  lc.setIntensity(0,0);
  lc.setIntensity(1,0);
  lc.setIntensity(2,0);
  /* and clear the display */
  lc.clearDisplay(0);
  lc.clearDisplay(1);
  lc.clearDisplay(2);
  lc.setScanLimit(0, 7); // set to 7 for 8 digits
  lc.setScanLimit(1, 7);
  lc.setScanLimit(2, 7);
  lcd.begin(20,4);   // initialize the lcd for 20 chars 4 lines, turn on backlight 
 // using namespace DCF77_Encoder; // v3 Removed
  //*************
  lcd.backlight(); // backlight on not needed as controlled by 7 MAX2719
  lcd.setCursor(0,0); //Start at character 0 on line 0
  lcd.print(" DCF77 Binary Clock");  
  lcd.setCursor(0,1); //Start at character 0 on line 0
  lcd.print("    Version 41");  


  //***************
  /*
  Serial.begin(9600);
  Serial.println();
  Serial.println(F(" DCF77 Binary Clock "));
  Serial.println(F("(c) Brett Oliver 2014"));
  Serial.println(F("http://www.brettoliver.org.uk"));
  Serial.println(F("Based on the DCF77 library by Udo Klein"));
  Serial.println(F("www.blinkenlight.net"));
  Serial.println();
  Serial.print(F("Sample Pin:     ")); 
  Serial.println(dcf77_sample_pin);
  Serial.print(F("Inverted Mode:  ")); 
  Serial.println(dcf77_inverted_samples);
  Serial.print(F("Analog Mode:    ")); 
  Serial.println(dcf77_analog_samples);
  Serial.print(F("Monitor Pin:    ")); 
  Serial.println(dcf77_monitor_pin);
  Serial.print(F("Timezone Offset:")); 
  Serial.println(timezone_offset);
  Serial.println();
  Serial.println();
  Serial.println(F("Initializing..."));
*/
 // pinMode(dcf77_monitor_pin, OUTPUT); // v3 removed
  pinMode(ledpin(dcf77_monitor_led), OUTPUT); // v3
  pinMode(dcf77_sample_pin, INPUT);
  digitalWrite(dcf77_sample_pin, HIGH);


  pinMode(remote1out, OUTPUT); 
  pinMode(remote2out, OUTPUT);
  pinMode(DCFSync, OUTPUT); 
  

  pinMode(remote1in, INPUT);   
  pinMode(remote2in, INPUT);
  pinMode(remote3in, INPUT);
  pinMode(remote4in, INPUT);  
  pinMode(infraredSw,INPUT);
  pinMode(infraredSw,INPUT);
  


  //*******************

  DCF77_Clock::setup();
  DCF77_Clock::set_input_provider(sample_input_pin);


  // Wait till clock is synced, depending on the signal quality this may take
  // rather long. About 5 minutes with a good signal, 30 minutes or longer
  // with a bad signal
  for (uint8_t state = Clock::useless; // v3 Mod
         state == Clock::useless || state == Clock::dirty; //v3 Mod
         state = DCF77_Clock::get_clock_state()) {

    // wait for next sec
    Clock::time_t now; //v3 Mod
    DCF77_Clock::get_current_time(now);

    // render one dot per second while initializing
    static uint8_t count = 0;
    Serial.print('.');
    ++count;
    if (count == 60) {
      count = 0;
      Serial.println();
    }
  }
}

void paddedPrint(BCD::bcd_t n) {
  Serial.print(n.digit.hi);
  Serial.print(n.digit.lo);
}
void LCDpaddedPrint(BCD::bcd_t n) { 
  lcd.print(n.digit.hi); 
  lcd.print(n.digit.lo); 
}

void loop() {

  Clock::time_t now; //v3 Mod

  DCF77_Clock::get_current_time(now);
  Timezone::adjust(now, timezone_offset);

  if (now.month.val > 0) {


    //***********
    // get month & day values
    dayval = now.day.val, DEC;
    monthval = now.month.val, DEC;

    // display 7 segment intensity value on LCD
    lcd.setCursor(0,2);
    lcd.print("Brightness ");
    segIntensity(intensity); // adds leading zero to 7 segment intensity

      // end display 7 segment intensity value on LCD   


    DCFSyncMon(); // Check if signal match is = 50 (100% match) then output a 1 on Arduino IC pin 15
                  // This is output to the Geiger counter WIFI board to show DCF77 is 100% match online



    // #################################
    //LDR start

    ldrValue = analogRead(ldr);
    intensityValue();
 /*   
    Serial.print ("LDR Value ");
    Serial.print (ldrValue, DEC);
    Serial.print (" ");
    
    Serial.print ("Intensity ");
    Serial.print (intensity);
    Serial.println (" ");
*/

    //LDR finish
    //#################################
    lcd.setCursor(13,2);
    switch (DCF77_Clock::get_clock_state()) {
      case Clock::useless: //v3 Mod
      lcd.print(F(" Fail  ")); 
      break;

      case Clock::dirty:   //v3 Mod
      lcd.print(F(" Dirty ")); 
      break;
      case Clock::synced:  //v3 Mod
      lcd.print(F(" Sync'd")); 
      break;
      case Clock::locked:  //v3 Mod
      lcd.print(F(" Locked")); 
      break;
    }

    //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    // Get hours minutes and seconds variables


    // Binary
    hours = BCD::bcd_to_int(now.hour);
    byte h = hours;

    byte h0 = bitRead(h, 5);
    byte h1 = bitRead(h, 4);
    byte h2 = bitRead(h, 3);
    byte h3 = bitRead(h, 2);
    byte h4 = bitRead(h, 1);
    byte h5 = bitRead(h, 0);

    minutes = BCD::bcd_to_int(now.minute);
    byte m = minutes;

    byte m0 = bitRead(m, 5);
    byte m1 = bitRead(m, 4);
    byte m2 = bitRead(m, 3);
    byte m3 = bitRead(m, 2);
    byte m4 = bitRead(m, 1);
    byte m5 = bitRead(m, 0);

    seconds = BCD::bcd_to_int(now.second);

    byte s = seconds;

    byte s0 = bitRead(s, 5);
    byte s1 = bitRead(s, 4);
    byte s2 = bitRead(s, 3);
    byte s3 = bitRead(s, 2);
    byte s4 = bitRead(s, 1);
    byte s5 = bitRead(s, 0);


    days = BCD::bcd_to_int(now.day);

    byte d = days;
    byte d0 = bitRead(d, 7);
    byte d1 = bitRead(d, 6);
    byte d2 = bitRead(d, 5);
    byte d3 = bitRead(d, 4);
    byte d4 = bitRead(d, 3);
    byte d5 = bitRead(d, 2);
    byte d6 = bitRead(d, 1);
    byte d7 = bitRead(d, 0);


    months = BCD::bcd_to_int(now.month);

    byte mth = months;

    byte mth0 = bitRead(mth, 7);
    byte mth1 = bitRead(mth, 6);
    byte mth2 = bitRead(mth, 5);
    byte mth3 = bitRead(mth, 4);
    byte mth4 = bitRead(mth, 3);
    byte mth5 = bitRead(mth, 2);
    byte mth6 = bitRead(mth, 1);
    byte mth7 = bitRead(mth, 0);


    years = BCD::bcd_to_int(now.year);

    yearsm = years % 100; // modulo eg modulo of year 2014 is 14 we don't want the thousands displayed in binary as
    // are only using 7 digits



    byte y = yearsm;

    byte y0 = bitRead(y, 7);
    byte y1 = bitRead(y, 6);
    byte y2 = bitRead(y, 5);
    byte y3 = bitRead(y, 4);
    byte y4 = bitRead(y, 3);
    byte y5 = bitRead(y, 2);
    byte y6 = bitRead(y, 1);
    byte y7 = bitRead(y, 0);


    seconds2 = floor(seconds/10); //gets 2nd seconds char from seconds for 7 segment display
    seconds1 = seconds - (seconds2 * 10); //gets 1st seconds char from seconds for 7 segment display

    // BCD seconds
    // 1st second digit to BCD
    byte sbcd = seconds1;


    byte sbcd2 = bitRead(sbcd, 3);
    byte sbcd3 = bitRead(sbcd, 2);
    byte sbcd4 = bitRead(sbcd, 1);
    byte sbcd5 = bitRead(sbcd, 0);


    // 2st second digit to BCD
    byte s2bcd = seconds2;


    byte s2bcd3 = bitRead(s2bcd, 2);
    byte s2bcd4 = bitRead(s2bcd, 1);
    byte s2bcd5 = bitRead(s2bcd, 0);

    // end BCD seconds




    minutes2 = floor(minutes/10); //gets 2nd seconds char from seconds for 7 segment display
    minutes1 = minutes - (minutes2 * 10); //gets 1st seconds char from seconds for 7 segment display

    // BCD minutes
    // 1st min digit to BCD
    byte mbcd = minutes1;


    byte mbcd2 = bitRead(mbcd, 3);
    byte mbcd3 = bitRead(mbcd, 2);
    byte mbcd4 = bitRead(mbcd, 1);
    byte mbcd5 = bitRead(mbcd, 0);


    // 2st second digit to BCD
    byte m2bcd = minutes2;

    byte m2bcd3 = bitRead(m2bcd, 2);
    byte m2bcd4 = bitRead(m2bcd, 1);
    byte m2bcd5 = bitRead(m2bcd, 0);


    // end BCD mins


    hours2 = floor(hours/10); //gets 2nd seconds char from hours for 7 segment display
    hours1 = hours - (hours2 * 10); //gets 1st seconds char from hours for 7 segment display

    // BCD hours
    // 1st hour digit to BCD
    byte hbcd = hours1;

    byte hbcd2 = bitRead(hbcd, 3);
    byte hbcd3 = bitRead(hbcd, 2);
    byte hbcd4 = bitRead(hbcd, 1);
    byte hbcd5 = bitRead(hbcd, 0);


    // 2st hours digit to BCD
    byte h2bcd = hours2;

    byte h2bcd3 = bitRead(h2bcd, 2);
    byte h2bcd4 = bitRead(h2bcd, 1);
    byte h2bcd5 = bitRead(h2bcd, 0);


    // end BCD hours







    // start infrared detect #######################################
    int infraredSw = digitalRead(17); // reads infrared detector output
   // Serial.print ("Infrared ");
   // Serial.println (infraredSw);
   // Serial.println ("");



    // Start of remote control switch reading
    // Switch 1
    {
      remote1val = digitalRead(remote1in); // reads OP from remote sw output

      // if the input just went from LOW and HIGH toggle the output pin

        if ( remote1val == 1 && remote1prev == 0 ) {
        if (datesw == 1)
          datesw = 0;
        else
          datesw = 1;


      }
     // Serial.print("remote1val ");
    //  Serial.println(remote1val);

    //  Serial.print("remote1prev ");
   //   Serial.println(remote1prev);

   //   Serial.print("datesw ");
    //  Serial.println(datesw);

      digitalWrite(remote1out, datesw);

      remote1prev = remote1val;
    }

    // Switch 2
    {
      remote2val = digitalRead(remote2in); // reads OP from remote sw output

      // if the input just went from LOW and HIGH toggle the output pin

        if ( remote2val == 1 && remote2prev == 0 ) {
        if (EZlinkPwr == 1)
          EZlinkPwr = 0;
        else
          EZlinkPwr = 1;


      }
     // Serial.print("remote2val ");
     // Serial.println(remote2val);

    //  Serial.print("remote2prev ");
     // Serial.println(remote2prev);

    //  Serial.print(" ");
   //   Serial.println(EZlinkPwr);

      digitalWrite(remote2out, EZlinkPwr);

      remote2prev = remote2val;
    }



    // Switch 3
    {
      remote3val = digitalRead(remote3in); // reads OP from remote sw output

      // if the input just went from LOW and HIGH toggle the output pin

        if ( remote3val == 1 && remote3prev == 0 ) {
        if (BCDdisplay == 1)
          BCDdisplay = 0;
        else
          BCDdisplay = 1;


      }


      remote3prev = remote3val;
    }

    // Switch 4
    remote4val = digitalRead(remote4in); // reads OP from remote sw output

    // End of remote control

    if (infraredSw == 1) // turns displays on during the day if infrared detects movement

    {
      lc.shutdown(0, false); // turns on the 7 segment display
      lc.shutdown(1, false);
      lc.shutdown(2, false);
      lcd.backlight(); // backlight on not needed as controlled by MAX2719
      lcd.display(); //display on   

    }
    else
    {
      lc.shutdown(0, true); // turns off the 7 segment display and puts it into standby mode
      lc.shutdown(1, true);
      lc.shutdown(2, true);

      lcd.noBacklight(); // LCD backlight off not needed as controlled by MAX2719
      lcd.noDisplay(); //LCD display off 

    }
    // end infrared detect #######################################

    // shows 7 segment display if infrared detected or time is after 22:00 and before 08:00
    /* Set the brightness to a medium values */
    //lc.setIntensity(0,8);
    lc.setIntensity(0,intensity); // set 7 segment intensity to value of "intensity"
    lc.setIntensity(1,intensity);
    lc.setIntensity(2,intensity);

    // If button C or 3 pressed on remote display goes to BCD time mode

    if (BCDdisplay == 1) // if date switch is off binary time is displayed
    {

      lcd.setCursor(0,3);
      lcd.print("BCD Time      ");
      // BCD Time
      // BCD Seconds
      lc.setChar(0,0,sbcd5,false); // print 1st seconds binary digit on 7 segment display 
      lc.setChar(0,1,sbcd4,false); // print 2nd seconds binary digit on 7 segment display 
      lc.setChar(0,2,sbcd3,false); // print 3rd seconds binary digit on 7 segment display 
      lc.setChar(0,3,sbcd2,false); // print 4th seconds binary digit on 7 segment display 
      lc.setChar(0,4,' ',false); // print blank seperator on BCD seconds 
      lc.setChar(0,5,s2bcd5,false); // print 1st seconds tens binary digit on 7 segment display 
      lc.setChar(0,6,s2bcd4,false); // print 2nd seconds tens binary digit on 7 segment display
      lc.setChar(0,7,s2bcd3,false); // print 3rd seconds tens binary digit on 7 segment display

      // BCD Minutes
      lc.setChar(1,0,mbcd5,false); // print 1st minute binary digit on 7 segment display 
      lc.setChar(1,1,mbcd4,false); // print 2nd minute binary digit on 7 segment display 
      lc.setChar(1,2,mbcd3,false); // print 3rd minute binary digit on 7 segment display 
      lc.setChar(1,3,mbcd2,false); // print 4th minute binary digit on 7 segment display 
      lc.setChar(1,4,' ',false); // print blank seperator on BCD minutes 
      lc.setChar(1,5,m2bcd5,false); // print 1st minutes tens binary digit on 7 segment display 
      lc.setChar(1,6,m2bcd4,false); // print 2nd minutes tens binary digit on 7 segment display
      lc.setChar(1,7,m2bcd3,false); // print 3rd minutes tens binary digit on 7 segment display

      // BCD Hours
      lc.setChar(2,0,hbcd5,false); // print 1st hour binary digit on 7 segment display 
      lc.setChar(2,1,hbcd4,false); // print 2nd hour binary digit on 7 segment display 
      lc.setChar(2,2,hbcd3,false); // print 3rd hour binary digit on 7 segment display 
      lc.setChar(2,3,hbcd2,false); // print 4th hour binary digit on 7 segment display 
      lc.setChar(2,4,' ',false); // print blank seperator on BCD hours
      lc.setChar(2,5,h2bcd5,false); // print 1st hours tens binary digit on 7 segment display 
      lc.setChar(2,6,h2bcd4,false); // print 2nd hours tens binary digit on 7 segment display
      lc.setChar(2,7,h2bcd3,false); // print 3rd hours tens binary digit on 7 segment display
    }







    else if (datesw == 0) // if date switch is off binary time is displayed
    {

      // Serial.println ("Showing Time");
      lcd.setCursor(0,3);
      lcd.print("Binary Time   ");  
      // Time
      // Seconds
      lc.setChar(0,1,s5,false); // print 1st seconds binary digit on 7 segment display 
      lc.setChar(0,2,s4,false); // print 2nd seconds binary digit on 7 segment display 
      lc.setChar(0,3,s3,false); // print 3rd seconds binary digit on 7 segment display 
      lc.setChar(0,4,s2,false); // print 4th seconds binary digit on 7 segment display 
      lc.setChar(0,5,s1,false); // print 5th seconds binary digit on 7 segment display 
      lc.setChar(0,6,s0,false); // print 6th seconds binary digit on 7 segment display 
      lc.setChar(0,0,' ',false);// digits 0 and 7 left blank
      lc.setChar(0,7,' ',false);

      // Minutes
      lc.setChar(1,1,m5,false); // print 1st minute binary digit on 7 segment display 
      lc.setChar(1,2,m4,false); // print 2nd minute binary digit on 7 segment display 
      lc.setChar(1,3,m3,false); // print 3rd minute binary digit on 7 segment display 
      lc.setChar(1,4,m2,false); // print 4th minute binary digit on 7 segment display 
      lc.setChar(1,5,m1,false); // print 5th minute binary digit on 7 segment display 
      lc.setChar(1,6,m0,false); // print 6th minute binary digit on 7 segment display 
      lc.setChar(1,0,' ',false);// digits 0 and 7 left blank
      lc.setChar(1,7,' ',false);

      // Hours
      lc.setChar(2,1,h5,false); // print 1st hour binary digit on 7 segment display 
      lc.setChar(2,2,h4,false); // print 2nd hour binary digit on 7 segment display 
      lc.setChar(2,3,h3,false); // print 3rd hour binary digit on 7 segment display 
      lc.setChar(2,4,h2,false); // print 4th hour binary digit on 7 segment display 
      lc.setChar(2,5,h1,false); // print 5th hour binary digit on 7 segment display 
      lc.setChar(2,6,h0,false); // print 6th hour binary digit on 7 segment display 
      lc.setChar(2,0,' ',false);// digits 0 and 7 left blank
      lc.setChar(2,7,' ',false);
    }

    else if (datesw == 1) // if date switch is on binary date is displayed
    {

      // Serial.println ("Showing Date");
      lcd.setCursor(0,3);
      lcd.print("Binary Date   ");
      // Date
      // Day 
      lc.setChar(2,0,d7,false);// 
      lc.setChar(2,1,d6,false); // print 1st day binary digit on 7 segment display 
      lc.setChar(2,2,d5,false); // print 2nd day binary digit on 7 segment display 
      lc.setChar(2,3,d4,false); // print 3rd day binary digit on 7 segment display 
      lc.setChar(2,4,d3,false); // print 4th day binary digit on 7 segment display 
      lc.setChar(2,5,d2,false); // print 5th day binary digit on 7 segment display 
      lc.setChar(2,6,d1,false); // print 6th day binary digit on 7 segment display 
      lc.setChar(2,7,d0,false);

      // Month
      lc.setChar(1,0,mth7,false);// digits 0 and 7 left blank
      lc.setChar(1,1,mth6,false); // print 1st month binary digit on 7 segment display 
      lc.setChar(1,2,mth5,false); // print 2nd month binary digit on 7 segment display 
      lc.setChar(1,3,mth4,false); // print 3rd month binary digit on 7 segment display 
      lc.setChar(1,4,mth3,false); // print 4th month binary digit on 7 segment display 
      lc.setChar(1,5,mth2,false); // print 5th month binary digit on 7 segment display 
      lc.setChar(1,6,mth1,false); // print 6th month binary digit on 7 segment display 
      lc.setChar(1,7,mth0,false);

      // Year
      lc.setChar(0,0,y7,false); // 
      lc.setChar(0,1,y6,false); // print 1st year binary digit on 7 segment display 
      lc.setChar(0,2,y5,false); // print 2nd year binary digit on 7 segment display 
      lc.setChar(0,3,y4,false); // print 3rd year binary digit on 7 segment display 
      lc.setChar(0,4,y3,false); // print 4th year binary digit on 7 segment display 
      lc.setChar(0,5,y2,false); // print 5th year binary digit on 7 segment display 
      lc.setChar(0,6,y1,false); // print 6th year binary digit on 7 segment display
      lc.setChar(0,7,y0,false); // print 7th year binary digit on 7 segment display

    }



    if (remote4val == 1)
    {
      lcd.setCursor(0,3);
      lcd.print("32 16 8 4 2 1");
    } 


    lcd.setCursor(6,3);



    // 7 segment


    //****************

    lcd.setCursor(0,0);

    LCDpaddedPrint(now.hour);
    lcd.print(":");
    LCDpaddedPrint(now.minute);
    lcd.print(":");
    LCDpaddedPrint(now.second);
    lcd.print("  ");

    LCDpaddedPrint(now.day);
    lcd.print("/");
    LCDpaddedPrint(now.month);
    lcd.print("/");
    lcd.print("20");
    LCDpaddedPrint(now.year);





    //****************




    // const int8_t offset_to_utc = timezone_offset + now.uses_summertime? 2: 1;
    const int8_t offset_to_utc = timezone_offset + (now.uses_summertime? 2: 1);

    summertest = (abs(offset_to_utc)); // equals 1 if summertime and 2 if wintertime 

    if (summertest ==2) // if wintertime make summertest =0
    {
      summertest = 0;
    }

    //**************
    lcd.setCursor(15,3);
    lcd.print("GMT+");
    // UTCcheck= offset_to_utc;
    // lcd.print(UTCcheck);
    lcd.print(summertest);

  }


  // Quality display on LCD

  if (seconds >= 0 && seconds <= 2)
  {
    lcd.setCursor(0,1);
    lcd.print(" DCF77 Binary Clock ");
  }

  else if (seconds == 3)
  {
    blankrow1(); //Blanks row 3
  }

  else if (seconds >= 4 && seconds <= 6)
  {
    lcd.setCursor(0,1);
    lcd.print("  Brett Oliver v41  ");
  }
  else if (seconds == 7)
  {
    blankrow1(); //Blanks row 3
  }


  else if (seconds >= 8 && seconds <= 10)
  {
    precision(); //quartz confirmed and target precision
  }

  else if (seconds == 11)
  {
    blankrow1(); //Blanks row 3
  }



  else if (seconds >= 12 && seconds <= 14)
  {
    signalmatch(); // Quality factor
  }

  else if (seconds == 15)
  {
    blankrow1(); //Blanks row 3
  }

  // repeat


  else if (seconds >= 16 && seconds <= 18)
  {
    precision(); //quartz confirmed and target precision
  }

  else if (seconds == 19)
  {
    blankrow1(); //Blanks row 3
  }



  else if (seconds >= 20 && seconds <= 22)
  {
    signalmatch(); // Quality factor
  }

  else if (seconds == 23)
  {
    blankrow1(); //Blanks row 3
  }

  // repeat


  else if (seconds >= 24 && seconds <= 26)
  {
    precision(); //quartz confirmed and target precision
  }

  else if (seconds == 27)
  {
    blankrow1(); //Blanks row 3
  }



  else if (seconds >= 28 && seconds <= 30)
  {
    signalmatch(); // Quality factor
  }

  else if (seconds == 31)
  {
    blankrow1(); //Blanks row 3
  }

  // repeat


  else if (seconds >= 32 && seconds <= 34)
  {
    precision(); //quartz confirmed and target precision
  }

  else if (seconds == 35)
  {
    blankrow1(); //Blanks row 3
  }



  else if (seconds >= 36 && seconds <= 38)
  {
    signalmatch(); // Quality factor
  }

  else if (seconds == 39)
  {
    blankrow1(); //Blanks row 3
  }

  // repeat


  else if (seconds >= 40 && seconds <= 42)
  {
    precision(); //quartz confirmed and target precision
  }

  else if (seconds == 43)
  {
    blankrow1(); //Blanks row 3
  }



  else if (seconds >= 44 && seconds <= 46)
  {
   signalmatch(); // Quality factor
  }

  else if (seconds == 47)
  {
    blankrow1(); //Blanks row 3
  }


  // repeat


  else if (seconds >= 48 && seconds <= 50)
  {
    precision(); //quartz confirmed and target precision
  }

  else if (seconds == 51)
  {
    blankrow1(); //Blanks row 3
  }



  else if (seconds >= 52 && seconds <= 54)
  {
    signalmatch(); // Quality factor
  }

  else if (seconds == 55)
  {
    blankrow1(); //Blanks row 3
  }


  // repeat


  else if (seconds >= 56 && seconds <= 58)
  {
    precision(); //quartz confirmed and target precision
  }

  else if (seconds == 59)
  {
    blankrow1(); //Blanks row 3
  }




} 





// ################################################################################

void segIntensity(int intensity){

  if(intensity < 10)  
    lcd.print("0"); // Print hour on first line
  lcd.print(intensity);
}

void monthzero(int monthval) { // leading zero on month value
  if (monthval < 10)

    lcd.print("0"); // Print hour on first line
  lcd.print(monthval);
}


void dayzero(int dayval) { // leading zero on day value
  if (dayval < 10)

    lcd.print("0"); // Print hour on first line
  lcd.print(dayval);
}



// intensity of 7 segment display
void intensityValue() { 

  if (ldrValue < 200)
  {
    intensity = 2;
  }
  

  else if (ldrValue >= 200 && ldrValue < 250)
  {
    intensity = 3;
  }

  else if (ldrValue >= 250 && ldrValue < 300)
  {
    intensity = 4;
  }


  else if (ldrValue >= 300 && ldrValue < 350)
  {
    intensity = 5;
  }


  else if (ldrValue >= 350 && ldrValue < 400)
  {
    intensity = 6;
  }


  else if (ldrValue >= 400 && ldrValue < 450 )
  {
    intensity = 7;
  }



  else if (ldrValue >= 450 && ldrValue < 500)
  {
    intensity = 8;
  }



  else if (ldrValue >= 500 && ldrValue < 550)
  {
    intensity = 9;
  }



  else if (ldrValue >= 550 && ldrValue < 600)
  {
    intensity = 10;
  }



  else if (ldrValue >= 600 && ldrValue < 700)
  {
    intensity = 11;
  }
  else if (ldrValue >= 700 && ldrValue < 800)
  {
    intensity = 12;
  }
  else if (ldrValue >= 800 && ldrValue < 900)
  {
    intensity = 13;
  }
  else if (ldrValue >= 900 && ldrValue < 999)
  {
    intensity = 14;
  }


  else if (ldrValue >= 999)
  {
    intensity = 15;
  }
} 




void blankrow1() { // blanks row 1
  lcd.setCursor(0,1);
  lcd.print("                    "); 
}

void blankrow3() { // blanks row 3
  lcd.setCursor(0,3);
  lcd.print("               "); 
}




void signalmatch() { // Out puts Signal match % on LCD display

 
  signalQual = DCF77_Clock::get_prediction_match();
  if(signalQual == 255 || signalQual == 0 )
  {
    signalQual = 00;
  }
  else
  {
    signalQual = signalQual * 2;
  }

 
  lcd.setCursor(0,1);
  lcd.print("Sig Match ");
  lcd.print(signalQual);
  lcd.print("%");
  
}

void DCFSyncMon() { // check is DCF signal is in sync then outputs 1 to geiger counter WIFI board
 
 signalDCF = DCF77_Clock::get_prediction_match();
  
   if ( signalDCF == 50 ) // 50 is 100% match
  {
    
    digitalWrite(DCFSync, HIGH); // 5 volts output to Geiger Counter WIFI module
  }
  else
  {
    
    digitalWrite(DCFSync, LOW); // 0 volts output to Geiger Counter WIFI module
  }
  
}


void precision() {
  lcd.setCursor(0,1);
  lcd.print("Qtz Accuracy ");
  lcd.print(DCF77_Frequency_Control::get_confirmed_precision());
  lcd.print("Hz "); 
}
/*
void freqadj() {
  lcd.setCursor(0,1);
  lcd.print("Qtz Freq ");
  lcd.print(16000000L - DCF77_1_Khz_Generator::read_adjustment());
  lcd.print("Hz"); 
}

*/