Home    Master Clock   LCD Master Clock    Kenley Weather

Section   Top  Case   Hood  Video  Dial Plate  Spandrels Dial   Chapter Rings  Movements   LCD  Controls   Pendulum   Vero Board   Schematic    Code

 

 

 

Arduino Longcase Clock

 

 

 

Arduino DCF77 controlled longcase clock

Arduino UNO/Atmega 328 built into main board

Synchronized to the Atomic clock transmitter in Germany using the DCF77 time code

DCF77 decoded using Udo Klein's DCF77 library

Hours & Minutes main analogue dial

Seconds analogue dial

Moon Phase analogue dial

20x4 secondary information display in clock hood

Automatic summer and winter correction

Electric Pendulum

 

Case

The empty longcase clock case was purchased from Ebay and is probably from the early 1900s.

 

The clock is 2.1m or 6' 10" high x 0.415m or 1' 4" wide x 0.21m or just over 8" deep and is made of Oak.

 

The removable hood will take an 8" breakarch dial and would have been accessed via the hinged door.

The case has a fully glazed door so would probably have had decorative brass weights and chains along with a brass pendulum bob.

I have fitted false weights and chain from an old clock and an electric motor to drive a false pendulum.

The 1 second tick sound is fed from my Digital Dial Clock and the chime sounds are fed from my Calendar Clock and as all the clocks are synchronised the ticking/chiming matches exactly with the displays.

 

 

Hood

The hood slides off the clock after disconnecting the 5volt power plug and DCF77 input wire.

Battery backup keeps the clock running while disconnected.

 

 

 

 

 

 

 

 

Video

 

 

 

 

 

 

 

 

 

Dial Plate

Using the wooden dial surround as a template and leaving a 20mm overlap, the dial plate is cut from a sheet of aluminium.

Hole are drilled to take miniature bolts, 4 for the hours/mins chapter ring, 2 for the moon and seconds chapter rings and 2 each for the dial, breakarch and top centre spandrels.

Holes are also drilled to take the hand shafts from the 3 modified movements.

In the original clock the dial would have been mounted in the hood separate from the dial surround door to enable the time to be set from the front of the dial by moving the minute hand.

On this clock the hands are set by remote switches so the dial can be screwed to the wooden dial surround. Holes are drilled around the edge to take these screws.

The aluminium dial plate in the animation is shown in it's unpolished state.

 

 

Brass Spandrels can be purchased from clock maker suppliers/Ebay. To give an aged effect I sprayed them with black paint then rubbed the black paint off the highlights.

         

            original bright brass spandrel left with aged spandrel right

 

Once all dials and spandrels have been test fitted the aluminium dial plate is given a final rub down in one direction only to give a grain effect and a clear lacquer is added.

 

 

Below rear view of dial showing bolts fixing chapter rings and spandrels and clock motor modules fixed to mounting bars.

The mounting bar for the seconds and Moon dial is set back from the dial plate to keep both seconds and Moon hands near the chapter rings.

Note the dial plate is shown semi transparent to show locations of chapter rings and spandrels on the front of the dial plate.

 

 

 

 

 

 

Chapter Rings

The Moon chapter ring is made from a re-labelled seconds chapter ring. The seconds lettering is removed with wire wool then the moon lettering is printed out on Lazertran Paper applied and then lacquered over.

The hour & minute chapter ring is from an old clock dial and was already drilled out for mounting bolts.

 

 

Moon

The moon dial shows the current age of the moon with a new moon at 0 a full moon at around 15.

The actual moon age in days and hours is shown on the LCD display while the moon dial moves a half segment in half a moon day.

This clock displays the Synodic month and this varies as the Earths orbit around the Sun and the Moons orbit around the Earth are elliptical.

The actual rate of Lunation, the time from new Moon to full Moon is between 29.18 to 29.93 days. The long term average is 29.530587981 days and this number is used by this clock to determine the Moons age.

The Moon dial is mechanically split into 59 segments (actually 60 but the code jumps the 60th segment) with each segment being 1/2 a Moon day.

The Arduino code steps through exactly once per second and adds 1 to the Moon Count every second.

A Lunation takes 29.530587981 days or 2551442.877 seconds.

I calculated this by the following.

29 days = 29x24hours = 696 hours

696 hours = 696x60minutes = 41760 minutes

41760 minutes =41760x60seconds = 2505600 seconds

so 29 days = 2505600 seconds

 

0.530587981 days = 0.530587981x24hours = 12.73413247 hours

12.73413247 hours = 12.73413247x60minutes = 764.0479483 minutes

764.0479483 minutes =764.0479483x60seconds = 45842.8769 seconds

so 0.530587981 days = 45842.8769 seconds

 

add the two together 2505600 seconds + 45842.8769 seconds = 2551442.877 seconds

so 29.530587981 days = 2551442.877 seconds

As the Moon display steps 59 times in a Lunation each step is

2551442.877 seconds / 59 steps = 43244.79452 seconds

I have rounded this up to 43245 seconds.

 

Every time the Arduino Moon count hits  43245 it advances the Moon display by 1 segment or 1/2 a Moon day.

At the end of the Lunation the Arduino steps 1 extra segment to return the Moon display to 0 days.

 

 

 

 

 

Seconds

The seconds chapter ring was purchased from Ebay and only needed holes drilled for the mounting bolts.

 

 

 

 

Hour & Minute

The hour and minute chapter ring can with four pre-drilled holes where it had been mounted in it's original dial.

 

 

 

 

Analogue Movements

There are three analogue movements one each for the Hours/Minutes, Moon & Seconds displays.

All the analogue displays are driven by Lavet type stepping motors.

The motors are sourced from 2 x U.T.S. quartz clock movements for seconds and moon display and a U.T.S. DCF77 Radio movement for the hour and minutes display. The motor requires very low current to drive it and can be driven direct from the Arduino output via a trimmer resistor.

The resistor is used to adjust the current to the motor so it works without being over driven.

The motor is driven by reversing the polarity to the drive coil which causes the permanent magnet toothed rotor (in red below) to turn 180°. The toothed rotor will continue to turn in the same direction each time the drive motor polarity is reversed.   2 output pins from the Arduino are used to pulse the drive motor with 1 pin always the opposite to the other.

 

The Lavet motor in the U.T.S. quartz clock movements drives the attached hand 1/60th of a turn (1 second) on each activation while the Lavet motor in the U.T.S. DCF77 Radio movement drives the min hand (the hour hand is geared down from this) 1/240th of a turn or 15 seconds.

In order for the Arduino to control the drive motors the 3 movements have to have their motors isolated from their onboard drive circuits.

 

U.T.S. DCF77 Radio Clock Movement Hack

Carefully prise the movement apart and remove the top and bottom case sections.

 

 

This will leave the movement PCB, DCF77 aerial and motors

Turn the PCB over so the solder side is visible.

Desolder the DCF77 aerial from it's solder pads as it is not required.

There are 2 drive coils on this movement, 1 for seconds and 1 for hours and minutes.

Locate the 2 drive coil solder terminals, marked 1 and 2 above. 1 is hour and minutes 2 is seconds.

Cut one of the tracks to the minute and hour solder terminal to isolate the drive coil.

Only the hour and minute coil is required so wires are soldered to coil contacts 1 and 1.

Take these 2 wires through the clock movement and out into the battery bay.

Solder the 2 wires from the hour /minute motor to the "Clk Motor Coil" terminals on the Lavet type stepping motor driver board.

Locate the PCB/motor board back in the 2 case sections making sure the wires do not foul the case and clip the case back together.

The Lavet type stepping motor driver board is "hot melt" glued in place.

 

 

 

 

 

U.T.S. Quartz Clock Movement Hack

 

 

Carefully prise the movement apart and remove the top and bottom case sections.

The Quartz PCB and motor section can then be lifted out as 1 part.

 

Turn the Quartz PCB and motor section over to reaveal the solder side of the PCB.

Cut one of the tracks to the motor coil to isolate it.

Solder wires to each of the coil solder pads and take them out of the clock into the battery bay.

 

 

Solder the wires to the "Clk Motor Coil" terminals on the Lavet type stepping motor driver board mounted in the battery bay.

Locate the PCB/motor board back in the 2 case sections making sure the wires do not foul the case and clip the case back together.

 

The Lavet type stepping motor driver board is "hot melt" glued in place.

 

 

 

 

 

LCD

The LCD is a yellow 4x20 with an I2C below module allowing 2 wire control by the Arduino.

 

The LCD Display shows the following information

Row 0

Current time and date should be identical to the hours, minutes and seconds dials.

 

Row 1

Clock Name

My Name & software version no

1 second clock total missed (fast) pulses and extra (slow) pulses. When the clock drifts and then resets a second ahead of clock time. An extra 1 second pulse (slow)  is required to keep correct time on 1 second clocks.  When the clock drifts and then resets a second behind clock time. A 1 second pulse is missed (fast) to keep correct time on 1 second clocks. The total  is reset at 06:10 in the morning.

This row also displays the Summer/Winter advance retard information when the clock is correcting the hour and minute dial.

 

Row 2

This row shows the Moon age in Days, Hours, Minutes & Seconds. This row also displays decoding status Syn, Lck, Dty and Fai

 

Row 3

This row shows the received signal accuracy in %, the Auto Tuned Quartz crystal frequency accuracy down to 1 Hz and the actual Auto Tuned Quartz crystal tuned frequency in Hz.

Summertime/wintertime indicator GMT/GMT+1

 

 

 

 

Controls

 

There are 14 control switches in the clock controlling various functions.

SW5 Arduino reset

Non locking switch that performs a reset on the Arduino.

 

SW1 Hour/Minutes dial On/Off

Locking switch mounted in the hour/minutes motor housing and provides On/Off control of the hour/minutes display.

 

SW6 Moon Phase Dial On/Off

Locking switch mounted in the Moon dial motor housing and provides On/Off control of the Moon phase display.

 

SW14 Seconds Dial On/Off

Locking switch mounted in the Seconds dial motor housing and provides On/Off control of the Seconds display.

 

SW12 Seconds set

Double pole three position non locking switch with centre off. When SW13 is set to Manual SW12 steps the second hand when moved from the 2 step positions.

 

SW13 Seconds Control

Double pole three way locking switch. Down Auto -Arduino controlled, Middle seconds off and up Manual- allow seconds stepping by SW12.

 

SW15 LCD display On/Off

Locking switch mounted on the main board. Signals the Arduino to turn on/off the LED backlight on the LCD display and LCD display itself.

 

SW11 Summer Advance

Non locking switch that when pressed starts the summer advance of the hour/mins dial.

The hour/mins dial is advance by 1/4min every 1 seconds. The LCD display changes to show the number of Summer Advance pulses sent.

On 0,15,30 and 45 seconds the advance count is not incremented to allow for normal hour/mins drive pulses (see looped animation below). This ensures that after 240 pulse counts the hour/mins clock is advanced exactly 1 hour.

The LCD display reverts back to normal stepping every 15 seconds.

 

 

SW9 Winter Retard

Non locking switch on main board. When pressed starts the winter retard of the hour/mins dial.

On the next missed hour/min drive pulse @ 0,15,30 or 45 seconds the LCD changes to show "Winter Retard".

Every time a drive pulse is missed the "Winter Retard" count increments by 1.

Once the "Winter Retard" count reaches 240 the LCD display reverts back to normal and the clock is advanced every 15 seconds as normal.

 

SW16 Hour/Minute Set

Locking switch mounted on the main board. Advances the hour/minute dial by 15 seconds every second pressed.

 

SW7 Reset Moon Count

Non locking switch on main board. When pressed resets the Moon day count and time on the LCD display to 0.

 

SW8 Moon Time Advance

Non locking switch on main board. When pressed advances the Moon Time on the LCD by 24 mins and 25 seconds.

 

SW3 Moon Phase Advance

Non locking switch on main board. When pressed advances the Moon day/phase once per second.

SW10 Moon Display Advance

Non locking switch on main board. When pressed advances the Moon display dial once per second.

 

 

 

 

 

 

 

 

 

Pendulum Drive

As this clock case has a glass trunk door the Pendulum is visible and to make the clock look like it is still mechanically operated an electric pendulum drive is added.

This heavy duty drive will dive a pendulum of 40" and weighing 8oz or more from a single D cell battery for over a year.

 

INSTRUCTIONS FOR THE ISI HEAVY DUTY PENDULUM DRIVE

 
This heavy duty pendulum drive is the first of it’s kind. It was designed to operate a 40”pendulum that weighs 8 ounces for more than a year on one D cell battery. It is
perfect for making low cost grandfather size clocks, but if you use your imagination,
it will do so much more.

 
1. When opening the device, please note that there is a separate battery well with
wires and a connector (figure B) that needs to be connected to the pendulum drive
(figure C). In most cases it is best to mount the battery well above the pendulum drive.

 
2. This heavy duty pendulum drive has a very unique feature. The part of the device
that powers the pendulum is actually “hinged” This means that if properly installed, your clock can actually be a few degrees out of level, from front to back, and still work properly. If you cut a 2” wide by 5 5/16” long hole in the board you are mounting this to (this is the measurement of the rectangle when looking at the back of the device), this will allow the hinged pendulum drive (figure A) to moveback and forth if needed.


3. Both the battery well and the heavy duty pendulum drive were designed to be installed with screws. We do not supply the screws because the type of screw you use should be determined by the material you are mounting this device to. You will need six screws. The mounting positions for these screws are indicated in the drawing to the right.


4. Mounting tips please consider how far-behind the dial of your clock you want the pendulum to swing. You will need to attach the heavy duty pendulum drive to a board
of some type that is hidden behind the dial of your clock. Please make sure that this board is installed so that this device can easily be made level.


5. Swing Adjustment: This device is operated by an electro magnet that is positioned between two magnets (D) that are on the pendulum arm. If the swing of your pendulum is too wide, then you can put a piece of tape over one or both of the magnets to reduce the width of the swing of the pendulum.

 

To complete the clock false weights and chains are added and fixed to a wooden batten behind the hood.

 

 

The wooden pendulum and brass bob are constructed from old clock parts.

                                          

 

 

 

Pendulum, weights and chain in completed clock

          

 

 

 

 

 

 

 

 

 

 

Vero Board Layouts

 

Lavet type stepping motor driver board. One required for each motor.

Below flipped down to show solder side.

 

 

 

 

Main Vero board layout,

 

 

 

 

Above flipped down to show solder side.

 

 

 

 

 

 

Schematic

 

 
 

Clearing your EEPROM

If your DCF77 library held on your Arduino has become corrupted the Arduino will not "Synchronize" to a good signal and will display a low "Signal Quality %" even though the signal is perfect.

Load this small bit of code to your Arduino to erase the EEPROM then reload the clock code below. This will allow the library to restart from fresh.

 
 
 
 
 

Code v16.0

Download code

Requires the following libraries


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

 
 
/*
v16 coded to use Udo Klein's v3 library https://github.com/udoklein/dcf77/releases/tag/v3.0.0
v15 remove moonphase advance fast add mooncountSec advance by 1465 (1/60th phase)

  Longcase Clock
  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/

*/


#include <dcf77.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
using namespace Internal;


/* 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 retardOn = 0;

//int infraredSwval = 0; // infrared value
//int infraredSw = A3; // set A3 to input ( pin 13)
int retardcount = 0;
int pulsecount = 0; // pulse counts upto required number to step forward 1 hour
int retardSw = 13; // winter retard switch pin 9
int retardSwval = 0; // value of retardSw
int advanceSw = 9; // summer advance switch pin 13
int advanceSwval = 0; // value of advanceSw
int pulseOn = 0; // 0 pulse off 1 pulse on (summer winter pulsing
int summertest = 0; // equals 1 for summertime and 0 for wintertime
int summerwinter = 0; // summer winter toggle
int extracount = 0; // where quartz seconds needs to miss a pulse
int hourextra = 00; // hour last miss pulse variable
int dayextra = 00; // day last miss pulse variable
int monthextra = 00; // month last miss pulse variable
int minuteextra = 00; // minute last miss pulse variable
int secondextra = 00; // second last miss pulse variable
int yearextra = 00;



int secondsnow = 0; // previous second
int yearmiss = 00;
int daymiss = 00; // day last extra pulse variable
int monthmiss = 00; // month last extra pulse variable
int secsmiss = 0; // works out is seconds need to an extra pulse or miss a pulse
int misscount = 0; // 1 ok 0 needs to miss a pulse 1 needs an extra pulse
int hourmiss = 00; // hour last extra pulse variable
int minutemiss = 00; // minute last extra pulse variable
int secondmiss = 00; // second last extra pulse variable
int signalQual = 0; // computed once per minute and indicates how well 
// the received signal matches the locally synthesized reference signal max 50
int monthval = 0;
int dayval = 0;
//int zero = 0;
int years = 0;
int months = 0;
int days = 0;

int hours = 0;

int minutes = 0;

int seconds = 0;
int secsval = 0;
int minsval = 0;
int hourval = 0;
int led15 = 2; //15 second pulse

int quartzmotor1 = HIGH;  // ledState used to set the quartz motor pin 7 initial state
int quartzmotor2 = LOW;   //  ledState used to set the quartz motor pin 8 initial state
int quartz01 =7;  //  Quartz clock motor pulse 01
int quartz02 =8;  //  Quartz clock motor pulse 02
int stepSecs =11; // when high seconds are advanced

int hrminmotor1 = HIGH;              // ledState used to set the quartz motor pin 1 initial state
int hrminmotor2 = LOW;              //  ledState used to set the quartz motor pin 2 initial state
int hrmin01 =12;  //  Quartz clock motor pulse 01
int hrmin02 =2;  //  Quartz clock motor pulse 02


//Moon Display
unsigned long mooncountSec = 1; // counts every sec until 43245 then moonphase is advanced by 1
unsigned long moontime = 1; 
int moonphase = 0; // advances 1 every 43245 secs and 86490 secs until 60 when it is reset to 2 (moon dial advanced to 1)
int moonphasedisp = 1; // advances 1 every 86490 secs until moonphase 60 when it is reset to 1 (moon dial advanced to 1)
int moondisAdv = 3; // advances moon phase display once per second
int moonphaseAdv = 4; //advances moon phase count once per second
//int moonphaseAdvfast = 11; //advances moon phase count 5 once per second
int mooncountSecAdv = 11; //advances mooncountSec  1465 once per second
int moonReset = A3; // resets moon phase and count to 1 new moon
int moonmotor1 = HIGH;              // ledState used to set the quartz motor pin 5 initial state
int moonmotor2 = LOW;              //  ledState used to set the quartz motor pin 6 initial state
int moon01 =5;  //  Moon clock motor pulse 01
int moon02 =6;  //  Moon clock motor pulse 02

float h, m;
int s = 0;
unsigned long over = 0;

// End Moon Display
int  LCDdispCtrl = A2;
int step15 = 10; //step hour mins forward by 15 seconds

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

namespace Timezone {
  uint8_t days_per_month(const Clock::time_t &now) {
    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) {
    // 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() {
  digitalWrite(led15, HIGH); // turn 15 sec clocks off at start
 

  lcd.begin(20,4);   // initialize the lcd for 20 chars 4 lines, turn on backlight 
 // using namespace Internal;
  //*************
 // 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 Longcase Clock");  





  //***************
  Serial.begin(9600);
  /*  Serial.println();
   Serial.println(F(" DCF77  Longcase  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); // removed v3

  pinMode(dcf77_sample_pin, INPUT);
  digitalWrite(dcf77_sample_pin, HIGH);


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

  //pinMode(led15, OUTPUT);
  pinMode(quartz01, OUTPUT);
  pinMode(quartz02, OUTPUT);
  pinMode(moon01, OUTPUT);
  pinMode(moon02, OUTPUT);
  pinMode(hrmin01, OUTPUT);
  pinMode(hrmin02, OUTPUT);
  pinMode(ledpin(dcf77_monitor_led), OUTPUT); //v3
  
 
  //pinMode(17, INPUT); // infrared switch
  pinMode(advanceSw,INPUT);
  pinMode(retardSw,INPUT);
  pinMode(moonphaseAdv,INPUT);
  //pinMode(moonphaseAdvfast,INPUT);
  pinMode(mooncountSecAdv,INPUT);
  pinMode(moondisAdv,INPUT);
  pinMode(moonReset,INPUT);
  pinMode(LCDdispCtrl,INPUT);
  pinMode(step15,INPUT); // 15 second (hour min) man advance
 // pinMode(stepSecs,INPUT); // secs man advance
  

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

  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;
         state == Clock::useless || state == Clock::dirty;
         state = DCF77_Clock::get_clock_state()) {

    // wait for next sec
    Clock::time_t now;
    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;

  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;
    // Serial.print(" day ");
    // Serial.print(now.day.val, DEC);
    //  Serial.print(" month ");
    //  Serial.print(now.month.val, DEC);
    //   Serial.print(' ');
    // get month & day values
    // Quartz clock driver
    // toggle Quartz drive 7 & 8 evey second
    secsmiss = seconds - secondsnow;

    if (secsmiss ==-59 || secsmiss ==-60 && seconds ==0) // takes account of seconds rollover -59 or leap second -60
    {
      secsmiss = 1;
    } 





 // If not andvancing seconds then use this (normal)
   if (secsmiss >=1 && seconds !=60) // if zero or less seconds pulse need to be missed. Leap second missed if seconds = 60
    {
      secondsmotor (); // function steps quartz motor
    }




    if (secsmiss < 1 || seconds == 60) //records time of extra sec second (quart motor needs to loose a second)

    {
      extracount = extracount + 1; //increment extra count total (1sec needs to miss pulse)
      hourextra = hours;
      minuteextra = minutes;
      secondextra = seconds;
      yearextra = years;
      monthextra = months;
      dayextra = days;

    }


    if (secsmiss > 1) //records time of miss second (quart motor needs to add a second)
    {
      misscount = misscount + 1; //increment Miss count total (1sec has missed extra pulse)
      hourmiss = hours;
      minutemiss = minutes;
      secondmiss = seconds;
      yearmiss = years;
      monthmiss = months;
      daymiss = days;

    } 



    secondsnow = seconds; 



    if (hours== 6 && minutes == 10 && seconds == 01) // resets miss second counter to 0 at 6:10:01
    {
      misscount = 0;
      extracount = 0;
    }


    // }
    // Enable below to analize missed pulses on serial monitor
    //Serial.print(" ");
    // Serial.print("secsmiss ");
    //  Serial.println(secsmiss);
/*

    Serial.print("Slow Seconds ");
    Serial.print(misscount);
    Serial.print(" ");
    Serial.print(hourmiss);
    Serial.print(":");
    Serial.print(minutemiss);
    Serial.print(":");
    Serial.print(secondmiss);
    Serial.print(" ");
    Serial.print(daymiss);
    Serial.print("/");
    Serial.print(monthmiss);
    Serial.print("/");
    Serial.println(yearmiss);


    Serial.print("Fast Seconds ");
    Serial.print(extracount);
    Serial.print(" ");
    Serial.print(hourextra);
    Serial.print(":");
    Serial.print(minuteextra);
    Serial.print(":");
    Serial.print(secondextra);
    Serial.print(" ");
    Serial.print(dayextra);
    Serial.print("/");
    Serial.print(monthextra);
    Serial.print("/");
    Serial.println(yearextra);


*/




    // end missing second pulse

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

    /*
 Serial.println(F("confirmed_precision [Hz], target_precision v,total_adjust [Hz], frequency [Hz]"));
     Serial.print(DCF77_Frequency_Control::get_confirmed_precision());
     Serial.print(F(", "));
     Serial.print(DCF77_Frequency_Control::get_target_precision());
     Serial.print(F(", "));
     Serial.print(DCF77_1_Khz_Generator::read_adjustment());
     Serial.print(F(", "));
     Serial.print(16000000L - DCF77_1_Khz_Generator::read_adjustment());
     Serial.print(F(" Hz, "));
     
     */

    //***************
    // signal quality

    //  signalQual = DCF77_Clock::get_prediction_match();
    //  if(signalQual == 255 || signalQual == 0 )
    //  {
    // signalQual = 00;
    //  }
    // else
    //{
    //  signalQual = (signalQual * 2) -1;
    //}
    // Serial.print (" Signal Match ");
    // Serial.print (signalQual);
    // Serial.print ("% ");

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

      // end display 7 segment intensity value on LCD   


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

  //  ldrValue = analogRead(ldr);
    
   //  Serial.print (" LDR Value ");
   //  Serial.print (ldrValue, DEC);
   //  Serial.print (" ");
  //  intensityValue();
    // Serial.print ("Intensity ");
  //   Serial.print (intensity);
  //   Serial.print (" ");
     
    //LDR finish
    //#################################
    //Serial.print (now.second.val);
    // Serial.print (" ");
    lcd.setCursor(17,2);
    //lcd.print(" Wait  ");
    switch (DCF77_Clock::get_clock_state()) {
      // case DCF77::useless: Serial.print(F("useless ")); break;
      case Clock::useless: 
      lcd.print(F(" Fail  ")); 
      break;
      // case DCF77::dirty:   Serial.print(F("dirty: ")); break;
      //  case DCF77::synced:  Serial.print(F("synced: ")); break;
      // case DCF77::locked:  Serial.print(F("locked: ")); break;
      case Clock::dirty:   
      lcd.print(F("Dty")); 
      break;
      case Clock::synced:  
      lcd.print(F("Syn")); 
      break;
      case Clock::locked:  
      lcd.print(F("Lck")); 
      break;
    }

    //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    // Get hours minutes and seconds variables
    hours = BCD::bcd_to_int(now.hour);


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


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

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

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

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


 

    /*  Serial.print (" H,M,S ");
     Serial.print (hours2);
     
     Serial.print (hours1);
     Serial.print (":");
     
     
     Serial.print (minutes2);
     
     Serial.print (minutes1);
     Serial.print (":");
     
     
     Serial.print (seconds2);
     
     Serial.print (seconds1);
     Serial.print (":");
     
     */
    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);





    //****************
    /*
    
     paddedPrint(now.hour);
     Serial.print(':');
     paddedPrint(now.minute);
     Serial.print(':');
     paddedPrint(now.second);
     Serial.print(' ');
     
     paddedPrint(now.day);
     Serial.print('/');
     paddedPrint(now.month);
     Serial.print('/');
     Serial.print(F("20"));
     paddedPrint(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);

    // Serial.print(F(" GMT"));

    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 <= 10)
  { 
    signalmatch(); // Quality factor
  }

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

else if (seconds == 12)
  {
    lcd.setCursor(0,3);
  lcd.print("Quartz         ");
  }
  else if (seconds >= 13 && seconds <= 23)
  {
    precision(); //quartz confirmed and target precision
  }

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

 else if (seconds >=25 && seconds <= 35 )
  {
      lcd.setCursor(0,3);
      
  signalmatch(); // Quality factor
  }

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


else if (seconds == 37)
  {
    lcd.setCursor(0,3);
  lcd.print("Quartz         ");
  }
  else if (seconds >= 38 && seconds <= 48)
  {
    precision(); //quartz confirmed and target precision
  }

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

 else if (seconds >=50 && seconds <= 59 )
  {
      lcd.setCursor(0,3);
      
  signalmatch(); // Quality factor
  }

 
  // End of Quality display on LCD
  //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$



  // winter to summer change // clocks go forward#################################
  advanceSwval = digitalRead(advanceSw);   // read advanceSw switch
  // 240 x 15 sec pulses need to be added to normal 15 second pulses to advance by 1 hour
  if (pulsecount < 240 && (seconds == 0 || seconds == 15 || seconds == 30 || seconds == 45) && (advanceSwval == 1 || pulseOn == 1))
    // summertest is 1 in summertime and  0 in wintertime  advance on 00 ,15,30 &45 secs does not advance pulse count

  {
    // sumwinSwval = 1;
    pulseOn = 1;
    //Serial.println(" 15 second test ");

     hrminmotor(); // function steps hr min motor

  }

  else if (pulsecount < 240 && (advanceSwval == 1 || pulseOn == 1)) // summertest is 1 in summertime and  0 in wintertime 

  {
    // sumwinSwval = 1;
    pulseOn = 1;
    pulsecount = pulsecount + 1;

     hrminmotor(); // function steps hr min motor
  }

  else  
  {
    digitalWrite(hrmin01, LOW); // set the hr min motor drive 1 pin LOW
  digitalWrite(hrmin02, LOW); // set the hr min motor drive 2 pin LOW
    pulseOn = 0; // 
    // sumwinSwval = 0;
    pulsecount = 0;
  } 

  // end winter to summer chaange advance ##############################



  //  summer to winter change clocks go back#################################
  retardSwval = digitalRead(retardSw);   // read retardSw switch

  if (retardcount < 240 && retardSwval == 1) // 240 x 15 sec pulses need to be ignored to retard by 1 hour
  {
    retardOn = 1;
  }

  else if (retardcount < 240 && (seconds == 0 || seconds == 15 || seconds == 30 || seconds == 45) && (retardSwval == 1 || retardOn == 1))
  {
    retardOn = 1;
    retardcount = retardcount + 1;
  }

  else if (retardcount < 240 && (retardSwval == 1 || retardOn == 1))
  {
    retardOn = 1;

  }

  else
  {
    retardOn = 0; 
    // sumwinSwval = 0;
    retardcount = 0;
  }  



  // end summer to winter change clocks go back#################################  





  // Display of Title and 30 second pulse correction on row 01 ##############################

  if (retardcount > 0 || retardcount == 119 ) //Prints correction pulse number
  {
    lcd.setCursor(0,1); 
    lcd.print("Winter Retard  ");
    lcd.setCursor(15,1);



    retard(retardcount); // add leading 0 <99
    retardtens(retardcount); // add another leading 0 less than 10
    lcd.print(retardcount);
  }
  else if (retardcount == 240 )  //Prints blank when correction pulse is on last number
  {
    lcd.setCursor(0,1); 
    lcd.print("                    ");
    // lcd.print(retardcount);
  } 


  else if (seconds >= 0 && seconds <= 5 && pulsecount == 0) // Ignored while clock is correcting forward or retarding
  {

    lcd.setCursor(0,1); //Start at character 0 on line 0
    lcd.print("DCF77 Longcase Clock");      

  }
  else if(seconds > 05 && seconds <= 10 && pulsecount == 0) // Ignored while clock is correcting forward or retarding
  {
    lcd.setCursor(0,1); //Start at character 0 on line 0
    //lcd.print(" DCF77 Master Clock ");  
    lcd.print(" Brett Oliver v16.0 ");
  }

  else if(seconds == 11 && pulsecount == 0) // Ignored while clock is correcting forward or retarding
  {
    lcd.setCursor(0,1); //Start at character 0 on line 0

    lcd.print("                    ");
  }

  else if(seconds > 11 && seconds <= 13 && pulsecount == 0) // Ignored while clock is correcting forward or retarding
  {
    lcd.setCursor(0,1); //Start at character 0 on line 0

    // lcd.print("       Pulses       ");
    lcd.print("   1 Second Clocks  ");

  }



  else if(seconds > 13 && seconds <=59 && pulsecount == 0) // Ignored while clock is correcting forward or retarding
  {
    lcd.setCursor(0,1); //Start at character 0 on line 0
    lcd.print("  Slow "); // miss pulse detected so extra 1 second motor pulse added
    lcd.print(misscount);

    lcd.print(" ");
    lcd.print("   Fast ");        
    lcd.print(extracount);
  }

  else if (pulsecount > 0 || pulsecount == 239 ) //Prints correction pulse number
  {
    lcd.setCursor(0,1); 
    lcd.print("Summer Advance ");
    lcd.setCursor(15,1);
    //lcd.print(pulsecount);

    advance(pulsecount); // add leading 0 <99
    advancetens(pulsecount); // add another leading 0 less than 10
    lcd.print(pulsecount);
  }
  else if (pulsecount == 240 )  //Prints blank when correction pulse is on last number
  {
    lcd.setCursor(0,1); 
    lcd.print("                    ");
    //lcd.print(pulsecount);
  } 


  // sum win test print
  //sumwinSwval = digitalRead(sumwinSw);   // read sumwinSw switch
  /* Serial.print(" Sum Win Pulse No ");
   Serial.print(pulsecount);
   Serial.print(" ");
   
   Serial.print("Sum Win SW ");
   Serial.print(sumwinSwval);
   Serial.print(" ");
   Serial.print("Pulse On ");
   Serial.print(pulseOn);
   Serial.print(" ");
   Serial.print("Retard On ");
   Serial.print(retardOn);
   Serial.print(" ");
   Serial.print("Retard Count ");
   Serial.print(retardcount);
   Serial.print(" ");
   Serial.print("Summer Test ");
   Serial.print(summertest);
   Serial.print(" ");
   */

  // end sum win test print 
  //  

  // winter to summer change // clocks go forward#################################

  // End Display of Title and 30 second pulse correction on row 01 ##############################
  //-----------------------------------------------------------------------
  // Moon Phase Dial Display
  mooncountSec = mooncountSec + 1;
 // moontime = 86490 - mooncountSec; //counts down to next phase change
  moontime = mooncountSec; // counts up to next phase change
  // calc/display hour min sec to next moon phase 
  h = int (moontime/3600);
  over = moontime % 3600;
  m = int (over/60);
  over = over % 60;
  s = int (over);
  /*
  Serial.print ("Sec Pulses: ");
  Serial.println (mooncountSec);
  Serial.print ("Sec Pulses: ");
  Serial.println (moontime);
  
  Serial.print ("Next Phase: ");
  Serial.print (h, 0);
  Serial.print ("h ");
  Serial.print (m, 0);
  Serial.print ("m ");
  Serial.print (s, 0);
  Serial.print ("s ");
  
  Serial.println ();
*/
  
  
  //
  
  
  
   // set in this order so Moon motor steps each second until 60 (0)
 /*
   if ( moonphase == 60 ) // was 61
  {
  // delay(100); // add delay so seconds mtor can operate again in the same second
    moonmotor (); // function steps moon motor
  // moonphase = moonphase + 1;
   lcd.setCursor(5,2); //Start at character  on line 2
    lcd.print("  "); // Blank old moon phase  
  moonphase = 0; //resets moonphase count so it displays day 1 (2/60th)on the dial
  moonphasedisp = 0; //resets moonphase LCD count so it displays day 1 (2/60th)on the dial
 // mooncountSec = 1;
  
  }
  */
  /*
  if ( moonphase == 60 )
  {
  // delay(100); // add delay so seconds mtor can operate again in the same second
    moonmotor (); // function steps moon motor
   moonphase = moonphase + 1; 
  }
  
  */
  
  
  // steps moon phase display to 0 and resets mooncountSec when moonphase is 59 and a half
  
  
   // if ( mooncountSec == 43245 && moonphase == 59 )
  if ( moonphase == 59 )
  {
  moonmotor (); // function steps moon motor
  lcd.setCursor(5,2); //Start at character  on line 2
    lcd.print("  "); // Blank old moon phase  
    
  //  moonphase = moonphase + 1;
  //  moonphasedisp = moonphasedisp + 1;
    
   moonphase = 0; //resets moonphase count so it displays day 1 (2/60th)on the dial
  moonphasedisp = 0; //resets moonphase LCD count so it displays day 1 (2/60th)on the dial 
 mooncountSec = 1;
  }
 
  
   if ( mooncountSec == 43245 )
 
  {
  moonmotor (); // function steps moon motor
    moonphase = moonphase + 1;
  }
  
  
  // steps moon phase display and resets mooncountSec after 86490 1 sec pulses (1 day 1min 25sec)
  else if ( mooncountSec >= 86490 )
  
  {
  moonmotor (); // function steps moon motor
    moonphase = moonphase + 1;
    moonphasedisp = moonphasedisp + 1;
   
 mooncountSec = 1;
  }
  
  
  
  
  //if ( mooncountSec == 5 )
  // turn off Moon motor unless stepping
  if ( ( mooncountSec > 5 && mooncountSec < 43240 ) || ( mooncountSec > 43250 && mooncountSec < 86485 ) && digitalRead (moonphaseAdv) == LOW && digitalRead (mooncountSecAdv) == LOW )
  {
   Serial.println("Moon Motor Off ");
   
   
  digitalWrite(moon01, LOW); // set the quartz motor drive 7 pin LOW
  digitalWrite(moon02, LOW); // set the quartz motor drive 8 pin LOW
  }
  else
  {
   Serial.println("Moon Motor On ");
  } 
  
  
   lcd.setCursor(0,2); //Start at character 0 on line 2
    lcd.print("Moon "); 
    lcd.print(moonphasedisp);
    
  lcd.setCursor(7,2); //Start at character  on line 2
    lcd.print(" ");
   //lcd.print(mooncountSec);
   moonh(h); // add leading 0 if less than 10
   lcd.print (h);
   lcd.setCursor(10,2); //Start at character  on line 2
  lcd.print (":");
   moonm(m); // add leading 0 if less than 10
  lcd.print (m);
  lcd.setCursor(13,2); //Start at character  on line 2
  lcd.print (":");
   moons(s); // add leading 0 if less than 10
  lcd.print (s);
 
     
    
  Serial.print("Moon Count ");
   Serial.println(mooncountSec);
   
   Serial.print("Moon Phase ");
   Serial.println(moonphase);
   
  Serial.print("Moon Phase Disp ");
   Serial.println(moonphasedisp);

  // End Moon Phase Dial Display
 //-------------------------------------------------------------------------------------------
 
 // Moon control switches
 
  // New Moon reset
 if ( digitalRead (moonReset) == HIGH )
 {
   //clear LCD first
  lcd.setCursor(5,2); //Start at character  on line 2
    lcd.print("  "); // Blank old moon phase  
   lcd.setCursor(8,2); //Start at character 5 on line 2
   
    lcd.print("        "); // blanks mooncountSec
   //mooncountSec = 1; //resets mooncountSec for new Moon
   mooncountSec = 1; //resets mooncountSec for new Moon test
  moonphase = 0; // resets moonphase for new Moon
  moonphasedisp = 0; // resets moonphase for new Moon
 }
 
 // Moon dialdisplay manual advance
 if ( digitalRead (moondisAdv) == HIGH )
 {
   moonmotor (); // function steps moon motor
 }
   
 // Moon phase LCD display manual advance
 if ( digitalRead (moonphaseAdv) == HIGH && moonphase > 59 ) // reset moonphase and moonphasedisp when moonphasedisp goes over 59
 {
 lcd.setCursor(5,2); //Start at character  on line 2
    lcd.print("  "); // Blank old moon phase 
   moonphase = 0; //resets moonphase for new Moon
 moonphasedisp = 0; //resets moonphase for new Moon
 mooncountSec = 1; // resets moonphase for new Moon
 }
 
 else if ( digitalRead (moonphaseAdv) == HIGH )
 {
   moonphase = moonphase + 2;
   moonphasedisp = moonphasedisp + 1;
   mooncountSec = 1;
 }
 
 //------------------------------Test
 
 // Moon count LCD display of H M S 
  if ( digitalRead (mooncountSecAdv) == HIGH && mooncountSec > 43244 && mooncountSec <= 44709 )
  {
    //add 1 to moonphase 
 moonphase = moonphase + 1;
 mooncountSec = mooncountSec + 1465;
 
  }
  
  else if ( digitalRead (mooncountSecAdv) == HIGH && mooncountSec >= 86490 ) // resets mooncount sec
  {
  // resets mooncount sec adds 1 to moonphse and moonphsedisp to keep them in sync
  mooncountSec = 1;
 moonphase = moonphase + 1;
 moonphasedisp = moonphasedisp + 1;
 
  }
 
 else if ( digitalRead (mooncountSecAdv) == HIGH )
 {
   mooncountSec = mooncountSec + 1465;
   
 }
 
 /*
 
 //------------------------------------End test
 
 // Moon count LCD display of H M S 
  
 if ( digitalRead (mooncountSecAdv) == HIGH )
 {
   mooncountSec = mooncountSec + 1465;
   
 }
 
 */
 
 
 // End Moon control switches
 //------------------------------------------------
 // LCD Display Switch
  if ( digitalRead (LCDdispCtrl) == LOW )
  {
    lcd.noDisplay(); //LCD display off
     lcd.noBacklight(); // LCD backlight off
  }
    else
    {
    lcd.display(); //display on
     lcd.backlight(); // LCD backlight on
  } 
 // LCD Display Switch
//---------------------------------------------------


  // 15 second clock pulses
  if ((retardOn == 0 && pulseOn ==0) && (seconds == 0 || seconds == 15 || seconds == 30 || seconds == 45 )) // will only pulse if retardOn = 0 ( not in winter retard mode)
  {
    hrminmotor(); // function steps hr min motor   

  }
// Step hr min motor every second
 else if ( digitalRead (step15) == HIGH )
  {
   hrminmotor(); // function steps hr min motor 
  }


  else if ((retardOn == 0 && pulseOn ==0) && (seconds != 0  || seconds != 15 || seconds !=30 || seconds != 45)) // will only pulse if retardOn = 0 ( not in winter retard mode
  {
   digitalWrite(hrmin01, LOW); // set the hr min motor drive 1 pin LOW
  digitalWrite(hrmin02, LOW); // set the hr min motor drive 2 pin LOW
  }
  


 
  // end 15 second clock pulsesvoid secondsmotor (){

  if (quartzmotor1 == LOW)
  { 
    quartzmotor1 = HIGH; 
  }
  else
    quartzmotor1 = LOW;
  {
    digitalWrite(quartz01, quartzmotor1); // set the quartz motor drive 7 pin
   
  }

  if (quartzmotor2 == HIGH)
  { 
    quartzmotor2 = LOW;
  }
  else
    quartzmotor2 = HIGH;
  {
    digitalWrite(quartz02, quartzmotor2); // set the quartz motor drive 8 pin
   
  }

}


void secondsmotorAdvance (){

 
    digitalWrite(quartz01, HIGH); // set the quartz motor drive 7 pin
 
    digitalWrite(quartz02, LOW); // set the quartz motor drive 8 pin

  
   Serial.print("quartzmotor1 ");
   Serial.println(quartzmotor1);
   Serial.print("quartzmotor2 ");
   Serial.println(quartzmotor2);
delay(200); // add delay so seconds mtor can operate again in the same second
 
 digitalWrite(quartz01, LOW); // set the quartz motor drive 7 pin
 
    digitalWrite(quartz02, HIGH); // set the quartz motor drive 8 pin

   
 
 Serial.print("quartzmotor1 ");
   Serial.println(quartzmotor1);
   Serial.print("quartzmotor2 ");
   Serial.println(quartzmotor2);
delay(100); // add delay so seconds mtor can operate again in the same second

  }
//step Moon motor
void moonmotor (){

  if (moonmotor1 == LOW)
  { 
    moonmotor1 = HIGH; 
  }
  else
    moonmotor1 = LOW;
  {
    digitalWrite(moon01, moonmotor1); // set the quartz motor drive 7 pin
   
  }

  if (moonmotor2 == HIGH)
  { 
    moonmotor2 = LOW;
  }
  else
    moonmotor2 = HIGH;
  {
    digitalWrite(moon02, moonmotor2); // set the quartz motor drive 8 pin
   
  }

}

//step hour min 15 second motor
void hrminmotor (){

  if (hrminmotor1 == LOW)
  { 
    hrminmotor1 = HIGH; 
  }
  else
    hrminmotor1 = LOW;
  {
    digitalWrite(hrmin01, hrminmotor1); // set the quartz motor drive 7 pin
   
  }

  if (hrminmotor2 == HIGH)
  { 
    hrminmotor2 = LOW;
  }
  else
    hrminmotor2 = HIGH;
  {
    digitalWrite(hrmin02, hrminmotor2); // set the quartz motor drive 8 pin
   
  }

}



// ################################################################################
/*
void segIntensity(int intensity){

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

void advance(int pulsecount){ // leading 0  on pulse count
  if (pulsecount < 100)

    lcd.print("0"); 

}

void advancetens(int pulsecount){ // leading 0  on pulse count
  if (pulsecount <10)

    lcd.print("0"); 

}
//******************************

void retard(int retardcount){ // leading 0  on pulse count
  if (retardcount < 100)

    lcd.print("0"); 

}

void retardtens(int retardcount){ // leading 0  on pulse count
  if (retardcount <10)

    lcd.print("0"); 

}




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




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





void signalmatch() {

  signalQual = DCF77_Clock::get_prediction_match();
  if(signalQual == 255 || signalQual == 0 )
  {
    signalQual = 00;
  }
  else
  {
    signalQual = signalQual * 2;
  }
  lcd.setCursor(0,3);
  lcd.print("Sig Match ");
  lcd.print(signalQual);
  lcd.print("%");
}



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

// add leading zero on moon h
void moonh(int h){ // leading 0  on pulse count
  if (h <10)

    lcd.print("0"); 

}

// add leading zero on moon m
void moonm(int m){ // leading 0  on pulse count
  if (m <10)

    lcd.print("0"); 

}

// add leading zero on moon s
void moons(int s){ // leading 0  on pulse count
  if (s <10)

    lcd.print("0"); 

}