Hackster is hosting Hackster Holidays, Finale: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Tuesday!Stream Hackster Holidays, Finale on Tuesday!
jg53fn55
Published © GPL3+

Digital 60+12 led clock

Digital 60 led clock analog style with RTC DS3231

IntermediateProtip1,299
Digital 60+12 led clock

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1
Shift Register- Serial to Parallel
Texas Instruments Shift Register- Serial to Parallel
SN74164
×9
High Accuracy Pi RTC (DS3231)
Seeed Studio High Accuracy Pi RTC (DS3231)
DS3231
×1
5 mm LED: Green
5 mm LED: Green
×60
5 mm LED: Red
5 mm LED: Red
×12
Resistor 330 ohm
Resistor 330 ohm
×72
Microchip MM5451
×1
7 Segment LED Display, InfoVue
7 Segment LED Display, InfoVue
×5
Rotary Encoder with Push-Button
Rotary Encoder with Push-Button
×1
Toggle Switch, (On)-Off-(On)
Toggle Switch, (On)-Off-(On)
×4

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

60 led clock analog style

Analog style clock

Code

60 led clock analog style

Arduino
Analog style clock
#define PI 3.141592653589793
#define DEG_TO_RAD 0.0174532925
#define RAD_TO_DEG 57.2957795130
#include <Wire.h>
#define CLK 5
#define Latch 6
#define dataBit 7// serial data
#define CLKMM 4      // to MM5451 pin 21
#define dataBitMM 3  // to MM5451 pin 22
#define DecPunt 8    // dot display
#define SW1 12
#define SW2 11
#define SW3 10
#define SW4 9
#include "Button2.h"; //  https://github.com/LennartHennigs/Button2
#include "Rotary.h";
#define ROTARY_PIN1  A0
#define ROTARY_PIN2 A1
#define BUTTON_PIN  A2
#define CLICKS_PER_STEP 4   // this number depends on your rotary encoder
#define MIN_POS         -100
#define MAX_POS         100
#define START_POS       0
#define INCREMENT       1   // this number is the counter increment on each step
Button2 bt;
Rotary rt;

//------------------------------------------------
// 7-segment display code array MM5451
byte segCode[18] = {63, 6, 91, 79, 102, 109, 125, 7, 127, 111,
                    0b0001001, 0b1000000,
                    0b1011110, 0b0111001, 0b1011100,
                    0b1000000, 0b0000000, 0b0001000
                   };
//-----------------------------------------------
byte segCode2[12] = {
  0b1000000, 0b0001001, 0b1011110,
  0b1110111, 0b1101110, 0b0000000,
  0b0100011, 0b0100111, 0b1001001,
  0b0000000, 0b0111000, 0b1010100
};
//-------------------------------------------
byte bindec[10] = {
  16,
  8,
  4,
  2,
  1,
  16,
  8,
  4,
  2,
  1,
};

byte Maan[20] = { 2, 13, 24, 5, 16, 27, 8, 19, 30, 11, 22, 3, 14, 25, 6, 17, 29, 10, 21 };
// epacta getallen
//eerste getal 2 is het jaar 2017, maan is dan 2 dagen oud op 1 januari.
// volgende getal is 2018, maan is dan 13 dagen oud op 1 januari.
//elk jaar verschuift 11, behalve eens in de 19 jaar, dan 12.
// laatste was in 2014 dan in 2033, en in 2052, en in 2071 enz.
//
//----------------------english-------------------------------------------
//epacta numbers
// first number of array Maan[20] is 2. This number is the year 2017, the moon age in days is 2 on januari first
//The next number is 2018, the moon age in days is 13 also on januari first, etc..
// every year ads 11, except once in 19 years, then it wil be 12
// latest was in 2014, then in 2033 etc...
// moonage = 0 >> new moon, moonage = 15 >> full moon
// moonage = 7.5 >> first quarter,   moonage = 22.5 >> last quarter
// from new moon to the next new moon = 29.5 days
byte Schrikkel = 0;
int Dagtotaal[12] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
int DagtotaalS[12] = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };
byte AR;
byte second;
int minute;
int hour;
byte weekday;
byte monthDay;
byte month;
byte Test;
byte test1;
byte test2;
byte test3;
byte test4;
int year;
byte Sjaar;
byte a = 0;
byte b = 0;
byte c = 0;
byte d = 0;
byte e = 0;
byte f = 0;
byte g = 0;
byte h = 0;
byte i = 0;
byte j = 0;
byte k = 0;
byte m = 0;
byte CodeSec[15];
byte CodeMin[15];
byte CodeLedMS[15];
byte Codemaan[15];
byte Lentepunt;
int Dagen;
float ZonOp;
float ZonOnder;
float MoonAge;
float DagLengte;
byte WT = 1;
// The variables HDT,TDT,DT,HT,TT and EH are used in the subroutine Factor();
long HDT;// hundred thousand ( when number is 123456, HDT = 1)
long TDT;// ten thousand ( when number is 123456, TDT = 2)
long DT;//thousand ( when number is 123456, DT = 3)
long HT;// hundred ( when number is 123456, HT = 4)
long TT;// tens ( when the number is 123456, TT = 5)
long EH;// unity (when the number is 123456, EH = 6)
byte cc;
volatile int encoderPos = 0;
boolean buttonPressed = 0;              // a flag variabl
volatile byte secondsInterrupt = 0;
const byte interruptPin = 2;
int counter = 0;
//-------------------------------------------------------
void setup() {
  pinMode(SW1, INPUT);
  pinMode(SW2, INPUT);
  pinMode(SW3, INPUT);
  pinMode(SW4, INPUT);
  pinMode(DecPunt, OUTPUT);
  pinMode(CLK, OUTPUT);
  pinMode(Latch, OUTPUT);
  pinMode(dataBit, OUTPUT);
  pinMode(CLKMM, OUTPUT);
  pinMode(dataBitMM, OUTPUT);

  pinMode(interruptPin, INPUT_PULLUP);
  Serial.begin(9600);
  Wire.begin();
  attachInterrupt(digitalPinToInterrupt(interruptPin), secondsRTC, FALLING);
  bt.begin(BUTTON_PIN);
  bt.setPressedHandler(pressed);
  bt.setReleasedHandler(released);

  rt.begin(ROTARY_PIN1, ROTARY_PIN2, CLICKS_PER_STEP, MIN_POS, MAX_POS, START_POS, INCREMENT);
  rt.setLeftRotationHandler(showDirection);
  rt.setRightRotationHandler(showDirection);
  zet_24uurmode();
  SQW1hzOn();
  digitalWrite(DecPunt, 1);
  digitalWrite(dataBitMM, 1);
  TijdUitlezen();
  pulseCLKMM();
  zeroWrite(35);
  Reset60Led();
  Displaytest();
  Led60Test();
}
//------------------------------------------------------------------------
byte AgingRead() {
  return leesroutine(16);
}

//------------------------------------------------------------------------
void zet_24uurmode() {// set 24 hour mode
  byte uurreg;
  uurreg = leesroutine(2);

  if (uurreg > 64) { // bit 6 = 64, set to zero
    uurreg = uurreg - 64;
    instelroutine(2, uurreg);
  }
}


//------------------------------------------------------------------------
byte lees_seconde() { // read seconds
  return  BcdToDec(leesroutine(0));
}
//------------------------------------------------------------------------
byte lees_minuut() { //read minute
  return  BcdToDec(leesroutine(1));
}
//------------------------------------------------------------------------
byte lees_uur() {  // read hour
  return  BcdToDec(leesroutine(2));
}
//------------------------------------------------------------------------
byte lees_dagweek() { // read DOW
  return  BcdToDec(leesroutine(3));
}
//------------------------------------------------------------------------
byte lees_datum() { // read day of month
  return  BcdToDec(leesroutine(4));
}
//------------------------------------------------------------------------
byte lees_maand() { // read month
  return  BcdToDec(leesroutine(5));
}

//------------------------------------------------------------------------
byte lees_jaar() {  // read year
  return  BcdToDec(leesroutine(6));
}
//------------------------------------------------------------------------
byte BcdToDec(byte val) {
  return  (val / 16 * 10) + (val % 16);// bcd to decimal
}
//------------------------------------------------------------------------
byte leesroutine(byte adres) {// read register of RTC

  Wire.beginTransmission(0x68); // adress RTC DS1307 or DS3231
  Wire.write(adres);       // address  register DS3231
  Wire.endTransmission();       // einde I2C routine
  Wire.requestFrom(0x68, 1);
  return  Wire.read();
}
//------------------------------------------------------------------------
void instelroutine(byte adres, byte data1) {// set register of RTC
  Wire.beginTransmission(0x68); // adress RTC DS3231
  Wire.write(adres);       // address register DS3231
  Wire.write(data1);
  Wire.endTransmission();       // einde I2C routine
}
//------------------------------------------------------------------------
byte decToBcd(byte val) {
  return ((val / 10 * 16) + (val % 10));
}
//------------------------------------------------------------------------
void Agingadjust(byte data1) {// fine adjust the frequency of the RTC

  instelroutine(16, data1);
  /*
     Positive aging values add capacitance to the array, slowing  the
     oscillator  frequency.  Negative  values  remove  capacitance from the array,
     increasing the oscillator frequency. The change in ppm per LSB is different
     at different temperatures. The frequency vs. temperature curve is shifted by
     the  values  used  in  this  registert.  At  +25C,  one  LSB  typically
     provides about 0.1ppm change in frequency.
  */
}
//------------------------------------------------------------------------
void SQW1hzOn() {// switch the 1 Hz SQW on
  instelroutine(14, 0);
}
//------------------------------------------------------------------------
void zet_jaar(byte data1) { // set year
  instelroutine(6, decToBcd(data1));
}
//------------------------------------------------------------------------
void zet_maand(byte data1) { // set month
  instelroutine(5, decToBcd(data1));
}
//------------------------------------------------------------------------
void zet_datum(byte data1) { // set day of month
  instelroutine(4, decToBcd(data1));
}
//------------------------------------------------------------------------
void zet_dagweek(byte data1) { // set DOW
  instelroutine(3, decToBcd(data1));
}
//------------------------------------------------------------------------
void zet_uur(byte data1) { // set hour
  instelroutine(2, decToBcd(data1));
}
//------------------------------------------------------------------------
void zet_minuut(byte data1) { // set minute
  instelroutine(1, decToBcd(data1));
}
//------------------------------------------------------------------------
void zet_seconde(byte data1) { // set second
  instelroutine(0, decToBcd(data1));
}
//----------------------------------------------------------
void TijdUitlezen() {
  second = lees_seconde();
  minute = lees_minuut();
  hour = lees_uur();
  weekday = lees_dagweek();  //0-6 -> sunday - Saturday
  monthDay = lees_datum();
  month = lees_maand();
  year = lees_jaar();
  // Serial.println(year);
  Sjaar = year;
  // seconde uitlezen///
  Factor(second, false);
  a = EH;
  b = TT;
  Factor(minute, false);
  c = EH;
  d = TT;
  // uur uitlezen///
  Factor(hour, false);
  e = EH;
  f = TT;

  // dag uitlezen///
  Factor(monthDay, false);
  g = EH;
  h = TT;

  // maand uitlezen///
  Factor(month, false);
  i = EH;
  j = TT;

  // jaar uitlezen///
  Factor(year, false);
  k = EH;
  m = TT;

   //Serial.println(second);
}
// --------------------------------------------------------
void Schrikkeljaar() {

  Sjaar %= 4;  // %= is remainder --------

  if (Sjaar == 0) {
    Schrikkel = 1;
    Lentepunt = 81;
    Dagen = 366;
  } else {
    Schrikkel = 0;
    Lentepunt = 80;
    Dagen = 365;
  }
}

// ------------------------------------------------------------------
void showDirection(Rotary& rt) {
  //Serial.println(rt.getDirection());

  counter = rt.getDirection();
  if (counter == 255)
  {
    counter = -1;
  }
  else
  {
    counter = 1;
  }
  encoderPos += counter;
  //Serial.println(encoderPos);
}


//--------------------------------------------------------
void pressed(Button2& btn) {
  //Serial.print("pressed ");
  buttonPressed = 1;
  //Serial.println(buttonPressed);
}
void released(Button2& btn) {
  // Serial.print("released: ");
  buttonPressed = 0;
  //Serial.println(buttonPressed);
}

//---------------------------------------------


void Factor(long Getal, bool graden) {
  long Test;
  //Serial.println(Getal);
  Test = Getal;
  HDT = Test / 100000;
  Test = Test - (HDT * 100000);

  TDT = Test / 10000;
  Test = Test - (TDT * 10000);

  DT = Test / 1000;
  Test = Test - (DT * 1000);


  HT = Test / 100;
  Test = Test - (HT * 100);

  if (graden == true) {// if true : decimaal to degree conversion
    Test = Test * 0.6;
  }
  TT = Test / 10;
  Test = Test - (TT * 10);

  EH = Test;
}
//--------------------------------------------------------------------------------
void secondsRTC(void) {  // *** ISR iedere seconde ***
  secondsInterrupt = 1;  // ISR vlag = 1 : er was een 'seconds' interrupt.
}
//------------------------------------------------------------------------
void readtime() {

  second = lees_seconde();// read seconds
  // seconde uitlezen///
  Factor(second, false);
  a = EH;
  b = TT;

  if (second == 0) {
    minute = lees_minuut();// read minutes
    // minuut uitlezen///
    Factor(minute, false);
    c = EH;
    d = TT;
  }

  if (minute == 0 & second == 0) {
    hour = lees_uur();// read hour
    // uur uitlezen///
    Factor(hour, false);
    e = EH;
    f = TT;
  }

  if (hour == 0 & second == 0) {
    weekday = lees_dagweek();  //0-6 -> sunday - Saturday
    monthDay = lees_datum();// read day of month
    month = lees_maand();// read month
    year = lees_jaar();// read year

    // dag uitlezen///
    Factor(monthDay, false);
    g = EH;
    h = TT;
    // maand uitlezen///
    Factor(month, false);
    i = EH;
    j = TT;
    Factor(year, false);
    k = EH;
    m = TT;
  }
}
//---------------------------------------------------------
void loop() {
  test1 = digitalRead(SW1);  // read the switch
  test2 = digitalRead(SW2);
  test3 = digitalRead(SW3);
  test4 = digitalRead(SW4);
  Test = test4 * 8;
  Test += test3 * 4;
  Test += test2 * 2;
  Test += test1;


  if (secondsInterrupt == 1) {  // **** doe als ISR vlag = 1  ****
    readtime();                 // de subroutine die iedere seconde de tijd registers leest.
    if (Test == 4) {
      Reset60Led();
    } else {
      Led60AanSturen();// update 60 + 12 leds
    }
    secondsInterrupt = 0;  // zet ISR vlag terug naar '0'
  }

  switch (Test) {
    case 15:                     //1111
      digitalWrite(DecPunt, 1);  // DecPunt = display dot >> 1 = ON and 0 = OFF
      LEDDisplayBLANK();         // regel 872
      break;
    case 14:  //1110
      digitalWrite(DecPunt, 1);
      LedTijd();  //  time
      break;
    case 13:  //1101
      digitalWrite(DecPunt, 1);
      Leddatum();  // date
      break;
    case 12:  //1100
      digitalWrite(DecPunt, 0);
      LCDAzimuth();  // elevation of the sun
      break;
    case 11:  //1011
      digitalWrite(DecPunt, 1);
      LedSeconde();  // seconds
      break;
    case 10:  //1010
      digitalWrite(DecPunt, 1);
      DagNR();  // amount of days since januari first
      break;
    case 9:  //1001
      digitalWrite(DecPunt, 1);
      Zonsopgang();  // sun rise
      break;
    case 8:  //1000
      digitalWrite(DecPunt, 1);
      LedDOW();  // Dau Of Week
      break;
    case 7:  //0111
      digitalWrite(DecPunt, 1);
      Ledjaar();  // year
      break;
    case 6:  //0110
      digitalWrite(DecPunt, 0);
      DagDuur();  // Length of day in hours
      break;
    case 5:  //0101
      digitalWrite(DecPunt, 0);
      SchStand();  // tilt of earth
      break;
    case 4:  //0100
      digitalWrite(DecPunt, 1);
      Adjust();  // adjust
      break;
    case 3:  //0011
      digitalWrite(DecPunt, 0);
      LedMaanOuderdom();  // moon age in days
      break;
    case 2:  //0010
      digitalWrite(DecPunt, 1);
      DagSEC();  // seconds since midnight
      break;
    case 1:  //0001
      digitalWrite(DecPunt, 1);
      Zonsondergang();  // sun set
      break;
    case 0:  //0000
      digitalWrite(DecPunt, 0);
      HzonNU();  // present elevation of the sun
      break;
  }
}
// -------------end loop -----------------------
//------------------------------------------------------------------------------------

void Adjust() {

  rt.loop();
  bt.loop();
  if (encoderPos < 0) {
    encoderPos = 0;
  }
  if (encoderPos > 8) {
    encoderPos = 8;
  }
  switch (encoderPos) {
    case 0:
      DisplayAjust();
      break;
    case 1:
      Displaykeuze1(64);
      if (encoderPos == 1 && buttonPressed == 1) {
        encoderPos = 0;
        AdjustUUR();
      }
      break;
    case 2:
      DisplaykeuzeWT(64);
      if (encoderPos == 2 && buttonPressed == 1) {
        encoderPos = 0;
        AdjustWT();
      }
      break;
    case 3:
      Displaykeuze3(64);
      if (encoderPos == 3 && buttonPressed == 1) {
        encoderPos = 0;
        AdjustMIN();
      }
      break;
    case 4:
      Displaykeuze4(64);
      if (encoderPos == 4 && buttonPressed == 1) {
        encoderPos = 0;
        AdjustDAG();
      }
      break;
    case 5:
      Displaykeuze5(64);
      if (encoderPos == 5 && buttonPressed == 1) {
        encoderPos = 0;
        AdjustMND();
      }
      break;
    case 6:
      Displaykeuze6(64);
      if (encoderPos == 6 && buttonPressed == 1) {
        encoderPos = 0;
        AdjustYR();
      }
      break;
    case 7:
      Displaykeuze7(64);
      if (encoderPos == 7 && buttonPressed == 1) {
        encoderPos = 0;
        AdjustDOW();
      }
      break;
    case 8:
      AR = AgingRead();
      Displaykeuze8(AR);
      if (encoderPos == 8 && buttonPressed == 1) {
        encoderPos = 0;
        AdjustAging();
      }
      break;
  }
}

// ------------------------------------------------------
void DisplayAjust() {
  DDMM(120, 109, 30, 94, 119);
}

//-------------------------------------------------------------
void AdjustUUR() {
  int exx = 0;
  Displaykeuze1(73);
  encoderPos = 0;
  buttonPressed = 0;
  while (exx == 0) {
    rt.loop();
    bt.loop();
    if (encoderPos == 0) {
      Factor(hour, false);
      e = EH;
      f = TT;
      Displaykeuze1(64);  // uur
    }
    //-----------------

    if (encoderPos > 1) {
      hour = hour + 1;
      if (hour == 24) {
        hour = 0;
      }
      Factor(hour, false);
      e = EH;
      f = TT;
      Displaykeuze1(1);  // uur
      encoderPos = 1;
    }

    // --------------------------
    if (encoderPos < -1) {
      hour = hour - 1;
      if (hour < 0) {
        hour = 23;
      }

      Factor(hour, false);
      e = EH;
      f = TT;
      Displaykeuze1(8);  // uur
      encoderPos = -1;
    }
    if (buttonPressed == 1 & encoderPos != 0) {
      zet_uur(hour);// set hour
      Displaykeuze1(9);  // uur
      encoderPos = 0;
      exx = 1;
    }

  }
}


// ------------------------------------------------------
void Displaykeuze1(int x) {
  DDMM(segCode[e], segCode[f], x, 80, 116);
}
//-------------------------------------------------------------
void AdjustWT() {//daylight saving time >> 1 = summer time, 0 = winter time
  int exx = 0;
  encoderPos = 0;
  buttonPressed = 0;
  DisplaykeuzeWT(73);
  while (exx == 0) {
    rt.loop();
    bt.loop();
    if (encoderPos == 0) {
      DisplaykeuzeWT(64);
    }
    //-----------------


    if (encoderPos > 1) {
      WT = 1;
      DisplaykeuzeWT(1);
      encoderPos = 1;
    }


    // --------------------------
    if (encoderPos < -1) {

      WT = 0;
      DisplaykeuzeWT(8);
      encoderPos = -1;
    }
    if (buttonPressed == 1 & encoderPos != 0) {
      DisplaykeuzeWT(9);
      encoderPos = 0;
      exx = 1;
    }
  }
}


// ------------------------------------------------------
void DisplaykeuzeWT(int x) {
  DDMM(segCode[WT], 0, x, 120, 120);
}
//-----------------------------------------------------------
void AdjustMIN() {
  int exx = 0;
  Displaykeuze3(73);
  encoderPos = 0;
  buttonPressed = 0;
  while (exx == 0) {

    rt.loop();
    bt.loop();
    if (encoderPos == 0) {
      Displaykeuze3(64);  // min
    }
    //-----------------


    if (encoderPos > 1) {
      minute = minute + 1;
      if (minute == 60) {
        minute = 0;
      }
      Factor(minute, false);
      c = EH;
      d = TT;
      Displaykeuze3(1);  // min
      encoderPos = 1;
    }

    // --------------------------
    if (encoderPos < -1) {
      minute = minute - 1;
      if (minute < 0) {
        minute = 59;
      }
      Factor(minute, false);
      c = EH;
      d = TT;
      Displaykeuze3(8);  // uur
      encoderPos = -1;
    }
    if (buttonPressed == 1 & encoderPos != 0) {
      zet_seconde(0);// set second
      zet_minuut(minute);// set minute
      Displaykeuze3(9);  // min
      encoderPos = 0;
      exx = 1;
    }

  }
}

// ------------------------------------------------------
void Displaykeuze3(int x) {
  DDMM(segCode[c], segCode[d], x, 84, 55);
}

//----------------------------------------------------------
void AdjustDAG() {
  int exx = 0;
  Displaykeuze4(73);
  encoderPos = 0;
  buttonPressed = 0;
  while (exx == 0) {

    rt.loop();
    bt.loop();
    if (encoderPos == 0) {
      Displaykeuze4(64);  // min
    }
    //-----------------


    if (encoderPos > 1) {
      monthDay = monthDay + 1;
      if (monthDay == 32) {
        monthDay = 1;
      }
      Factor(monthDay, false);
      g = EH;
      h = TT;
      Displaykeuze4(1);  // min
      encoderPos = 1;
    }
    // --------------------------
    if (encoderPos < -1) {
      monthDay = monthDay - 1;
      if (monthDay == 0) {
        monthDay = 31;
      }

      Factor(monthDay, false);
      g = EH;
      h = TT;
      Displaykeuze4(8);  // uur
      encoderPos = -1;
    }
    if (buttonPressed == 1 & encoderPos != 0) {
      zet_datum(monthDay);// set monthday
      Displaykeuze4(9);  // min
      encoderPos = 0;
      buttonPressed = 0;
      exx = 1;
    }

  }
}
// ------------------------------------------------------
void Displaykeuze4(int x) {
  DDMM(segCode[g], segCode[h], x, 110, 94);
}

//-------------------------------------------------------
void AdjustMND() {
  int exx = 0;
  Displaykeuze5(73);
  encoderPos = 0;
  buttonPressed = 0;
  while (exx == 0) {

    rt.loop();
    bt.loop();

    if (encoderPos == 0) {
      Displaykeuze5(64);
    }
    //-----------------


    if (encoderPos > 1) {
      month = month + 1;
      if (month > 12) {
        month = 1;
      }
      Factor(month, false);
      i = EH;
      j = TT;
      Displaykeuze5(1);
      encoderPos = 1;
    }
    // --------------------------
    if (encoderPos < -1) {
      month = month - 1;
      if (month == 0) {
        month = 12;
      }

      Factor(month, false);
      i = EH;
      j = TT;
      Displaykeuze5(8);
      encoderPos = -1;
    }
    if (buttonPressed == 1 & encoderPos != 0) {
      zet_maand(month);// set month
      Displaykeuze5(9);
      encoderPos = 0;
      exx = 1;
    }

  }
}
// ------------------------------------------------------
void Displaykeuze5(int x) {
  DDMM(segCode[i], segCode[j], x, 94, 55);
}

//------------------------------------------------------
void AdjustYR() {
  int exx = 0;
  encoderPos = 0;
  buttonPressed = 0;
  Displaykeuze6(73);
  if (year > 2000) {
    year = year - 2000;
  }
  while (exx == 0) {

    rt.loop();
    bt.loop();

    if (encoderPos == 0) {
      Displaykeuze6(64);  // min
    }
    //-----------------


    if (encoderPos > 1) {
      year = year + 1;
      if (year > 99) {
        year = 0;
      }
      Factor(year, false);
      k = EH;
      m = TT;
      Displaykeuze6(1);  // min
      encoderPos = 1;
    }
    // --------------------------
    if (encoderPos < -1) {
      year = year - 1;
      if (year < 0) {
        year = 99;
      }
      Factor(year, false);
      k = EH;
      m = TT;
      Displaykeuze6(8);  // uur
      encoderPos = -1;
    }
    if (buttonPressed == 1 & encoderPos != 0) {
      zet_jaar(year);// set year
      Displaykeuze6(9);  // min
      encoderPos = 0;
      exx = 1;
    }

  }
}
// ------------------------------------------------------
void Displaykeuze6(int x) {
  DDMM(segCode[k], segCode[m], x, 80, 110);
}
//------------------------------------------------------
void AdjustDOW() {
  int exx = 0;
  encoderPos = 0;
  buttonPressed = 0;
  Displaykeuze7(73);

  while (exx == 0) {

    rt.loop();
    bt.loop();
    if (encoderPos == 0) {
      Displaykeuze7(64);  //
    }
    //-----------------


    if (encoderPos > 1) {
      weekday = weekday + 1;
      if (weekday > 7) {
        weekday = 7;  // 1 = maandag , 2 = dinsdag enz.
      }

      Displaykeuze7(1);  //
      encoderPos = 1;
    }

    // --------------------------
    if (encoderPos < -1) {
      weekday = weekday - 1;
      if (weekday < 1) {
        weekday = 1;
      }

      Displaykeuze7(8);  //
      encoderPos = -1;
    }
    if (buttonPressed == 1 & encoderPos != 0) {
      zet_dagweek(weekday);// setDOW
      Displaykeuze7(9);  //
      encoderPos = 0;
      exx = 1;
    }

  }
}
// ------------------------------------------------------
void Displaykeuze7(int x) {
  DDMM(segCode[weekday], x, 110, 119, 94);
}
//------------------------------------------------------
void AdjustAging() {
  int exx = 0;
  encoderPos = 0;
  buttonPressed = 0;

  Displaykeuze8(AR);

  AR = AgingRead();

  while (exx == 0) {
    Displaykeuze8(AR);
    rt.loop();
    bt.loop();


    if (encoderPos == 0) {
      Displaykeuze8(AR);

    }
    //-----------------

    if (encoderPos > 1) {
      AR = AR + 1;
      if (AR > 127) {
        AR = 0;
      }

      Displaykeuze8(AR);
      encoderPos = 1;
    }

    // --------------------------
    if (encoderPos < -1) {
      AR = AR - 1;
      if (AR < -128) {
        AR = 0;
      }

      Displaykeuze8(AR);
      encoderPos = -1;
    }
    if (buttonPressed == 1 & encoderPos != 0) {
      Agingadjust(AR);
      Displaykeuze8(AR);
      encoderPos = 0;
      buttonPressed = 0;
      exx = 1;
    }

  }
}
// ------------------------------------------------------
void Displaykeuze8(byte ARR) {
  int RR;
  // aging register of RTC uses two's complement, a negative number is from 128 to 255
  RR = ARR;

  if (RR >= 0 & RR < 128) {
    Factor(RR, false);
    DDMM(segCode[EH], segCode[TT], segCode[HT], 0, 119);
  }
  else
  {
    RR = RR - 256;
    RR = abs(RR);
    Factor(RR, false);
    DDMM(segCode[EH], segCode[TT], segCode[HT], 64, 119);
  }

}
//----------------------------------------------
void pulseCLK() {
  digitalWrite(CLK, 1);
  digitalWrite(CLK, 0);
}
//-------------------------------------------------
void pulseCLKMM() {
  digitalWrite(CLKMM, 1);
  digitalWrite(CLKMM, 0);
}
//-------------------------------------------------------------
// LSB out first!
void ssrWriteLSB(byte value) {
  for (int x = 0; x < 5; x++) {
    byte temp = value & 0x01;
    if (temp == 0x01) {
      digitalWrite(dataBit, 1);  // data bit HIGH
    } else {
      digitalWrite(dataBit, 0);  // data bit LOW
    }
    pulseCLK();
    value = value >> 0x01;  // shift right
  }
}
//----------------------------------------------------------
void DDMM(byte D1, byte D2, byte D3, byte D4, byte D5) {
  digitalWrite(dataBitMM, 1);
  pulseCLKMM();
  ssrWriteLSBMM(D1);
  ssrWriteLSBMM(D2);
  ssrWriteLSBMM(D3);
  ssrWriteLSBMM(D4);
  ssrWriteLSBMM(D5);
  zeroWrite(1);  // pad remaining bits with 0s (35-35)+1
}
//----------------------------------------------------------
void ssrWriteLSBMM(byte value) {
  for (int x = 0; x < 7; x++) {
    byte temp = value & 0x01;
    if (temp == 0x01) {
      digitalWrite(dataBitMM, 1);  // data bit HIGH
    } else {
      digitalWrite(dataBitMM, 0);  // data bit LOW
    }
    pulseCLKMM();
    value = value >> 0x01;  // shift right
  }
}
//------------------------------------------------------------------
// MSB out first!
void ssrWriteMSB(byte value) {
  for (int x = 0; x < 5; x++) {
    byte temp = value & 0x80;
    if (temp == 0x80) digitalWrite(dataBit, 1);  // data bit HIGH
    else
      digitalWrite(dataBit, 0);  // data bit LOW
    pulseCLK();
    value = value << 0x01;  // shift left
  }
}
//---------------------------------------------------------
void zeroWrite(byte num1) {
  digitalWrite(dataBitMM, 0);  // data bit LOW
  for (int x = 0; x < num1; x++)
    pulseCLKMM();
}
//---------------------------------------------------------
void LedSeconde() {
  DDMM(segCode[a], segCode[b], 64, 64, 64);
}
//--------------------------------------------------------
void LedTijd() {
  int test = second;
  test %= 2;  //%= is remainder  ----
  if (test == 1) {
    DDMM(segCode[c], segCode[d], 9, segCode[e], segCode[f]);
  } else {
    DDMM(segCode[c], segCode[d], 64, segCode[e], segCode[f]);
  }
}
//-----------------------------------------------------------------
void Led60AanSturen() {
  SecondenAansturen();// update seconds
  if (second == 0) {
    MinutenAanSturen();// update minutes
  }
  if (minute == 0 & second == 0) {
    UrenAansturen();// update hours
    LEDMaan();// update moon
  }
  if (CodeLedMS[0] == 0 & CodeLedMS[1] == 0 & CodeLedMS[2] == 0) {
    MinutenAanSturen();
    UrenAansturen();
    LEDMaan();
  }

  CodeOR();

  digitalWrite(Latch, 1);
  for (int x = 0; x < 15; x++) {
    ssrWriteLSB(CodeLedMS[x]);
  }
  digitalWrite(Latch, 0);
}
//---------------------------------------------------------------

void SecondenAansturen() {
  // b = seconds tenth
  //a = seconds unity

  for (byte x = 0; x < 15; x++) {
    CodeSec[x] = 0;  // 15  nullen in codeSec zetten
  }

  // a = 0 .... 9
  // b = 0,1,2,3,4 or 5
  // cc = segment 14 t/m 3
  //segment 14 = led 0 t/m 4, segment 13 = led 5 t/m 9
  //segment 12 = led 10 t/m 14, segment 11 = led 15 t/m 19
  //segment 10 = led 20 t/m 24, segment 9 = led 25 t/m 29
  //segment 8 = led 30 t/m 34, segment 7 = led 35 t/m 39
  //segment 6 = led 40 t/m 44, segment 5 = led 45 t/m 49
  //segment 4 = led 50 t/m 54, segment 3 = led 55 t/m 59
  //b=0, led 0 t/m 9,
  //b=1, led 10 t/m 19
  //b=2, led 20 t/m 29
  //b=3, led 30 t/m 39
  //b=4, led 40 t/m 49
  //b=5, led 50 t/m 59

  cc = 14 - (b * 2);
  if (a < 5) {
    CodeSec[cc] = bindec[a];
  } else {
    CodeSec[cc - 1] = bindec[a];
  }

  /*
    switch (b)// b = seconden tientallen
    {
      case 0:// ------  van 0 tot/m 9 seconden----------------
        if (a < 5)  // a = seconden eenheden
        {
          CodeSec[14] = bindec[a];    //1 x  data
        }
        else
        {
          CodeSec[13] = bindec[a];    //1 x  data
        }
        break;

      case 1:  //   van 10 tot/m 19 seconden------------------------
        if (a < 5)  // a = seconden eenheden
        {
          CodeSec[12] = bindec[a];    //1 x  data
        }
        else
        {
          CodeSec[11] = bindec[a];    //1 x  data
        }
        break;

      case 2: //   van 20 tot 29 seconden--------------------
        if (a < 5)  // a = seconden eenheden
        {
          CodeSec[10] = bindec[a];    //1 x  data
        }
        else
        {
          CodeSec[9] = bindec[a];    //1 x  data
        }
        break;

      case 3://   van 30 tot 39 seconden---------------------
        if (a < 5)  // a = seconden eenheden
        {
          CodeSec[8] = bindec[a];    //1 x  data
        }
        else
        {
          CodeSec[7] = bindec[a];    //1 x  data
        }
        break;

      case 4: //   van 40 tot 49 seconden-------------------------
        if (a < 5)  // a = seconden eenheden
        {
          CodeSec[6] = bindec[a];    //1 x  data
        }
        else
        {
          CodeSec[5] = bindec[a];    //1 x  data
        }
        break;

      case 5:  //   van 50 tot 59 seconden-------------------------
        if (a < 5)  // a = seconden eenheden
        {
          CodeSec[4] = bindec[a];    //1 x  data
        }
        else
        {
          CodeSec[3] = bindec[a];    //1 x  data
        }
        break;
    }
  */
}

//-----------------------------------------------------------------------------------
void MinutenAanSturen() {
 
  for (byte x = 0; x < 15; x++) {
    CodeMin[x] = 0;  // 15  nullen in codeMin zetten
  }
  // d = 0,1,2,3,4 of 5
  //cc = ledcode[d];
  cc = 14 - (d * 2);
  if (c < 5) {
    CodeMin[cc] = bindec[c];
  } else {
    CodeMin[cc - 1] = bindec[c];
  }
}
//-----------------------------------------------------------------------

void UrenAansturen() {
 
  byte ee;
  byte ff;
  byte uur;
  uur = hour;
  //uur = 0;

  if (uur >= 12) {
    uur = uur - 12;
  }
  // uur uitlezen///
  Factor(uur, false);
  ee = EH;  // eenheden
  ff = TT;  // tientallen
  //f=1;
  //e=1;
  CodeLedMS[0] = 0;
  CodeLedMS[1] = 0;
  CodeLedMS[2] = 0;

  switch (ff) {
    case 0:
      if (ee < 5)  // ee = uren eenheden
      {
        CodeLedMS[2] = bindec[ee];  //1 x  data
      } else {
        CodeLedMS[1] = bindec[ee];  //1 x  data
      }
      break;
    case 1:
      CodeLedMS[0] = bindec[ee];  //1 x  data
      break;
  }
}

//--------------------------------------------------------------
void CodeOR() {

  for (byte aa = 3; aa < 15; aa++) {
    // minuten met seconden  OR bewerking ------------------------------
    CodeLedMS[aa] = CodeMin[aa] | CodeSec[aa];  // "|" = OR functie
  }

  switch (Test) {
    case 15:  //1111
      // do nothing
      break;
    default:
      byte testsec = second;
      testsec %= 2;
      if (testsec == 0) {
        // minuten  en seconden met maan OR bewerking -------------------
        for (byte aa = 3; aa < 15; aa++) {
          CodeLedMS[aa] = Codemaan[aa] | CodeLedMS[aa];
        }
      }
      break;
  }



  //for (int x = 0; x < 15; x++) {
  //  Serial.print("CodeMS: ");
  //   Serial.print(x);
  //   Serial.print("  ");
  //   Serial.println(CodeLedMS[x]);
  // }
}
//--------------------------------------------------------------

void Reset60Led() {
  for (byte x = 0; x < 15; x++) {
    CodeLedMS[x] = 0;
  }
  for (byte x = 0; x < 15; x++) {
    ssrWriteLSB(CodeLedMS[x]);
  }
}
// ---------------------------------------------------------------------
void Led60Test() {

  byte aa;
  byte bb;
  byte cc1;
  for (byte x = 0; x < 60; x++) {
    Factor(x, false);
    aa = EH;
    bb = TT;
    cc1 = 14 - (bb * 2);
    if (aa < 5) {
      CodeLedMS[cc1] = bindec[aa];
    } else {
      CodeLedMS[cc1 - 1] = bindec[aa];
    }
    digitalWrite(Latch, 1);
    for (int xx = 3; xx < 15; xx++) {
      ssrWriteLSB(CodeLedMS[xx]);
    }
    digitalWrite(Latch, 0);
    delay(100);
    for (byte x = 0; x < 15; x++) {
      CodeLedMS[x] = 0;  // 15  nullen in codeledMS zetten
    }
  }

}
//--------------------------------------------------------------
void Leddatum() {
  DDMM(segCode[i], segCode[j], 64, segCode[g], segCode[h]);
}
// ---------------------------------------------------------
void Ledjaar() {
  DDMM(segCode[k], segCode[m], segCode[0], segCode[2], segCode[16]);
}
//------------------------------------------------------------
void LedDOW() {
  DDMM(segCode[weekday], segCode2[5], segCode2[4], segCode2[3], segCode2[2]);
}
//--------------------------------------------------------------
void LedMaanOuderdom() {
  LEDMaan();
  float Oud;
  Oud = MoonAge;

  Factor(Oud * 100, false);
  DDMM(segCode[EH], segCode[TT], segCode[HT], segCode[DT], segCode2[6]);
}

// -----------------------------------------------------------
void LEDDisplayBLANK() {
  DDMM(segCode[16], segCode[16], segCode[16], segCode[16], segCode[16]);
}

//--------------------------------------------------------------
byte segCode1[24] = {
  0b0000001, 0b0000010, 0b0000100,
  0b0001000, 0b0010000, 0b0100000,
  0b1000000, 0b1001001, 0b1000000,
  0b1001001, 0b1000000, 0b1001001,
  0b1000000, 0b0111111, 0b0000110,
  0b1011011, 0b1001111, 0b1100110,
  0b1101101, 0b1111101, 0b0000111,
  0b1111111, 0b1101111, 0b1110110
};
//--------------------------------------------------------------
void Displaytest() {

  // start bit
  for (int x = 0; x < 23; x++) {
    DDMM(segCode1[x], segCode1[x], segCode1[x], segCode1[x], segCode1[x]);
    delay(300);
  }
  delay(1000);
}

//-----------------------------------------------------------------
void LEDMaan() {
  float Uur1;
  float Min1;
  float MOud;
  int Index;
  float AZ;
  int v = 0;
  int w = 0;
  int Jaar;
  Schrikkeljaar();
  AZ = TotaalDagen(month);
  Min1 = minute;
  Uur1 = hour + (Min1 / 60);
  AZ = AZ + monthDay;
  AZ = AZ + (Uur1 / 24);
  Jaar = year;
  if (year > 2000) {
    year = year - 2000;
  }
  Index = year - 17;  // epactagetal ophalen
  while (Index > 18) {
    Index = Index - 19;
  }

  //Serial.println(Index);
  MOud = Maan[Index];
  //Serial.println(MOud);
  MOud = MOud + AZ;
  //Serial.println(MOud);
  while (MOud >= 29.5305885) {
    MOud -= 29.5305885;
  }

  for (int x = 0; x < 15; x++) {
    Codemaan[x] = 0;  // 15  nullen in codemaan zetten
  }
  //MOud = 0;
  MoonAge = MOud;
  MOud *= 2;
  MOud *= 1.0158896;  // = 30/29.5305885
  MOud = int(MOud);
  //Serial.print("MOud: ");
  //Serial.println(MOud);
  Factor(MOud, false);
  v = EH;
  w = TT;

  //cc = ledcode[w];

  cc = 14 - (w * 2);
  if (v < 5) {
    Codemaan[cc] = bindec[v];
  } else {
    Codemaan[cc - 1] = bindec[v];
  }
}
// ------------------------------------------------
void DagDuur() {
  float BB;
  float AZ;
  float Decc;
  Schrikkeljaar();
  AZ = TotaalDagen(month);
  AZ = AZ - Lentepunt + monthDay;
  Decc = Declinatie(AZ, Dagen);
  ZonOpOnder(Decc, 52.9);  // aanroepen routine JaarDagen();
  BB = DagLengte;

  Factor(BB * 100, true);
  digitalWrite(dataBitMM, 1);
  DDMM(segCode[EH], segCode[TT], segCode[HT], segCode[DT], segCode2[10]);
}
//----------------------------------------------------------------
void SchStand() {
  float BB;
  float BB2;
  float AZ;
  Schrikkeljaar();
  AZ = TotaalDagen(month);
  //AZ = 345;
  AZ = (AZ - Lentepunt) + monthDay;
  BB = Declinatie(AZ, Dagen);
  BB2 = BB;

  BB2 = abs(BB2);  // fabs = absoluut

  Factor(BB2 * 100, true);

  if (BB >= 0) {
    DDMM(segCode[EH], segCode[TT], segCode[HT], segCode[DT], segCode[16]);
  } else {
    DDMM(segCode[EH], segCode[TT], segCode[HT], segCode[DT], segCode[15]);
  }
}
//--------------------------------------------------------------------------
void LCDAzimuth() {
  float BB;
  float AZ;
  float Decc;
  Schrikkeljaar();
  AZ = TotaalDagen(month);
  //AZ = 180;
  AZ = (AZ - Lentepunt) + monthDay;
  Decc = Declinatie(AZ, Dagen);

  BB = Hoogte(Decc, 52.9);

  Factor(BB * 100, true);
  DDMM(segCode[EH], segCode[TT], segCode[HT], segCode[DT], segCode1[23]);
}
//-------------------------------------------------
float Tijdvereffening(float dd) {
  float Tijd;
  float TVV;
  Tijd = (7.56 * SINUS((2 * 180 * (dd - 2.7)) / Dagen));
  Tijd = Tijd + (9.85 * (SINUS((4 * 180 * (10.5 + dd)) / Dagen)));
  TVV = (Tijd / 60);
  return TVV;
}

//---------------------------------------------------------
void Zonsondergang() {
  float BB;
  float AZ;
  float Decc;
  float ZZ;
  float TVE;
  float DM;
  Schrikkeljaar();
  AZ = TotaalDagen(month);
  AZ = AZ - Lentepunt + monthDay;
  Decc = Declinatie(AZ, Dagen);
  ZonOpOnder(Decc, 52.9);  // aanroepen routine
  ZZ = ZonOnder + 0.683333;
  ZZ += WT;
  AZ += Lentepunt;

  TVE = Tijdvereffening(AZ);

  ZZ += TVE;

  Factor(ZZ * 100, true);
  DDMM(segCode[EH], segCode[TT], segCode2[1], segCode[HT], segCode[DT]);
}
//---------------------------------------------------------
void Zonsopgang() {
  float BB;
  float AZ;
  float Decc;
  float ZZ;
  float TVE;
  float DM;
  Schrikkeljaar();
  AZ = TotaalDagen(month);
  AZ = AZ - Lentepunt + monthDay;
  Decc = Declinatie(AZ, Dagen);
  ZonOpOnder(Decc, 52.9);  // aanroepen routine
  ZZ = ZonOp + 0.683333;
  ZZ += WT;
  AZ += Lentepunt;
  TVE = Tijdvereffening(AZ);
  ZZ += TVE;

  Factor(ZZ * 100, true);
  DDMM(segCode[EH], segCode[TT], segCode2[1], segCode[HT], segCode[DT]);
}
//------------------------------------------------------
void DagSEC() {
  long DS;
  long uur;
  uur = hour;
  DS = (uur * 3600);
  DS += (minute * 60);
  DS += second;

  Factor(DS, false);
  DDMM(segCode[EH], segCode[TT], segCode[HT], segCode[DT], segCode[TDT]);
}
// --------------------------------------------------------------
void DagNR() {
  long DR;
  int AA;
  int HB;
  int LB;
  int HSB;
  int LSB;
  Schrikkeljaar();
  DR = TotaalDagen(month) + monthDay;

  Factor(DR, false);
  DDMM(segCode[EH], segCode[TT], segCode[HT], segCode2[1], segCode2[2]);
}
// -------------------------------------------------------------------
int TotaalDagen(int maand) {  // dit is een functie
  int Dagen;
  int dag1 = maand - 1;
  if (Schrikkel == 1) {
    Dagen = DagtotaalS[dag1];
  } else {
    Dagen = Dagtotaal[dag1];
  }
  return Dagen;
}

//-----------------------------------------------
float Hoogte(float decl, float brg) {
  float HGT;
  float HGT2;
  HGT = (SINUS(brg) * SINUS(decl)) + (COSINUS(brg) * COSINUS(decl));
  HGT2 = ARCSINUS(HGT);
  return HGT2;
}

// ------------------------------------------------
void HzonNU() {
  float Tijd1;
  float AZ;
  float Decc;
  float TVE;
  float Tijd2;
  float HGTE;
  float Hoogte;
  float ZZ;
  Tijd1 = hour + (minute / 60.0);
  Tijd1 = Tijd1 + (second / 3600.0);
  Tijd1 = Tijd1 - WT - 0.683333;
  Schrikkeljaar();
  AZ = TotaalDagen(month);
  AZ = AZ - Lentepunt + monthDay;
  Decc = Declinatie(AZ, Dagen);
  AZ = AZ + Lentepunt;
  TVE = Tijdvereffening(AZ);
  Tijd1 = Tijd1 - TVE;
  Tijd2 = (Tijd1 * 15.0) - 180.0;
  HGTE = (SINUS(52.9) * SINUS(Decc)) + (COSINUS(52.9) * COSINUS(Decc) * COSINUS(Tijd2));
  Hoogte = ARCSINUS(HGTE);
  // Serial.print("hoogte: ");
  //Serial.println(Hoogte);
  ZZ = Hoogte;
  ZZ = abs(ZZ);  // fabs = absoluut

  Factor(ZZ * 100, true);
  if (Hoogte >= 0) {
    DDMM(segCode[EH], segCode[TT], segCode[HT], segCode[DT], segCode[16]);
  } else {
    DDMM(segCode[EH], segCode[TT], segCode[HT], segCode[DT], segCode[15]);
  }
}
//-------------------------------------------------
double ARCTANGENS(double x) {
  double XX;
  XX = x;
  return atan(XX) * RAD_TO_DEG;
}
//-------------------------------------------------
double ARCCOSINUS(double x) {
  double XX;
  XX = x;
  return acos(XX) * RAD_TO_DEG;
}
//-------------------------------------------------
double ARCSINUS(double x) {
  double XX;
  XX = x;
  return asin(XX) * RAD_TO_DEG;
}
//-------------------------------------------------
double TANGENS(double x) {
  double XX;
  XX = x * DEG_TO_RAD;
  return tan(XX);
}
//-------------------------------------------------
double COSINUS(double x) {
  double XX;
  XX = x * DEG_TO_RAD;
  return cos(XX);
}
//-------------------------------------------------
double SINUS(double x) {
  double XX;
  XX = x * DEG_TO_RAD;
  return sin(XX);
}
// -----------------------------------------------
double Declinatie(float dag, float Jaardag) {
  double DECL;
  DECL = (dag * 360.0 / Jaardag);
  DECL = SINUS(DECL);
  return DECL = DECL * 23.5;
}
//--------------------------------------------------
void ZonOpOnder(float decl, float brg) {
  float ZON;
  float ZonOpOn;
  float AA2 = 180.0;
  float BB2 = 15.0;
  float gr = -1.25;
  ZON = (SINUS(gr) - (SINUS(brg) * (SINUS(decl)))) / (COSINUS(brg) * COSINUS(decl));
  ZonOpOn = ARCCOSINUS(ZON);
  ZonOp = (AA2 - ZonOpOn) / BB2;
  ZonOnder = (AA2 + ZonOpOn) / BB2;
  DagLengte = ZonOnder - ZonOp;
}

//----------------------------------------------------

Credits

jg53fn55
0 projects • 4 followers
I am retired.

Comments