/*
  https://forum.arduino.cc/t/scetch-fur-den-rtc-ds3231-der-mit-taster-beim-drucken-die-uhrzeit-anzeigt/1161331/3
  2023-08-26 by noiasca
  code in Forum
*/

const uint8_t min1Pin[] = {2, 3, 4, 5}; // pins für die Einer
const uint8_t min5Pin = 6;              // pin für 5
const uint8_t min10Pin[] = {7, 8, 9, 10, 11}; // pins für die Zehner
const uint8_t hour1Pin = 12;
const uint8_t hour2Pin[] = {13, A0, A1, A2, A3}; // 2, 4, 6, 8, 10

uint8_t hh = 5;   // actual hour
uint8_t mm = 10;  // actual minute

// reset clock face
void deleteAll() {
  for (auto & i : min1Pin) digitalWrite(i, LOW);
  digitalWrite(min5Pin, LOW);
  for (auto & i : min10Pin) digitalWrite(i, LOW);
  digitalWrite(hour1Pin, LOW);
  for (auto & i : hour2Pin) digitalWrite(i, LOW);
}

// nur Ausgabe Minute - nur mehr für Tests
void displayMinute(byte actual = 0) {
  deleteAll();
  uint8_t min1 = actual % 5;
  uint8_t min5 = (actual % 10) >= 5;
  uint8_t min10 = actual / 10;
  if (min1) digitalWrite(min1Pin[min1 - 1], HIGH);
  if (min5) digitalWrite(min5Pin, HIGH);
  if (min10) digitalWrite(min10Pin[min10 - 1], HIGH);
  //testausgabe:
  Serial.print(actual); Serial.print("\t");
  Serial.print(min1); Serial.print("\t");
  Serial.print(min5); Serial.print("\t");
  Serial.print(min10);
  Serial.println();
}

// activates the needed LEDs according to hour and minute
void displayTime(byte hour, byte minute) {
  if (hour > 11 || minute > 59) {
    Serial.print(F("wrong time "));
    Serial.print(hour); Serial.print(":"); Serial.println(minute);
    return;
  }
  deleteAll();
  uint8_t min1 = minute % 5;
  uint8_t min5 = (minute % 10) >= 5;
  uint8_t min10 = minute / 10;
  uint8_t hour1 = hour % 2;  // switch on when odd
  uint8_t hour2 = hour / 2;
  if (min1) digitalWrite(min1Pin[min1 - 1], HIGH);
  if (min5) digitalWrite(min5Pin, HIGH);
  if (min10) digitalWrite(min10Pin[min10 - 1], HIGH);
  if (hour1) digitalWrite(hour1Pin, HIGH);
  if (hour2) digitalWrite(hour2Pin[hour2 - 1], HIGH);
  //testausgabe:
  Serial.print(hour); Serial.print(":"); Serial.print(minute); Serial.print("\t");
  Serial.print(hour1); Serial.print("\t");
  Serial.print(hour2); Serial.print("\t");
  Serial.print(min1); Serial.print("\t");
  Serial.print(min5); Serial.print("\t");
  Serial.print(min10);
  Serial.println();
}

// make the clock running
void clockRun() {
  const uint32_t interval = 2 * 1000UL; // 60*1000UL (one minute), or testwise 2*1000UL
  static uint32_t previousMillis = millis() - interval;
  if (millis() - previousMillis > interval) {
    previousMillis = millis();
    mm++;
    if (mm > 59) {
      mm = 0;
      hh++;
      if (hh > 11) hh = 0;
    }
    displayTime(hh, mm);
  }
}

void setup() {
  Serial.begin(115200);
  for (auto & i : min1Pin) pinMode(i, OUTPUT);
  pinMode(min5Pin, OUTPUT);
  for (auto & i : min10Pin) pinMode(i, OUTPUT);
  pinMode(hour1Pin, OUTPUT);
  for (auto & i : hour2Pin) pinMode(i, OUTPUT);

  //for (int i = 0; i < 60; i++) displayMinute(i);  // test
  //displayMinute(17); // test
  displayTime(11, 59); // test
  delay(3000);// dirty delay, just to make the test output visible
}

void loop() {
  clockRun();
}