#include <Wire.h>

#define DS3231_ADDR 0x68

byte decToBcd(byte val) {
  return ((val / 10 * 16) + (val % 10));
}

byte bcdToDec(byte val) {
  return ((val / 16 * 10) + (val % 16));
}

void setDS3231Time(
  byte second,
  byte minute,
  byte hour,
  byte dayOfWeek,
  byte dayOfMonth,
  byte month,
  byte year
) {
  Wire.beginTransmission(DS3231_ADDR);
  Wire.write(0x00);

  Wire.write(decToBcd(second));
  Wire.write(decToBcd(minute));
  Wire.write(decToBcd(hour));       // 24h-Modus
  Wire.write(decToBcd(dayOfWeek));  // 1 = Sonntag, 2 = Montag ...
  Wire.write(decToBcd(dayOfMonth));
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year));       // z.B. 26 für 2026

  Wire.endTransmission();
}

void readDS3231Time() {
  Wire.beginTransmission(DS3231_ADDR);
  Wire.write(0x00);
  Wire.endTransmission();

  Wire.requestFrom(DS3231_ADDR, 7);

  byte second     = bcdToDec(Wire.read() & 0x7F);
  byte minute     = bcdToDec(Wire.read());
  byte hour       = bcdToDec(Wire.read() & 0x3F);
  byte dayOfWeek  = bcdToDec(Wire.read());
  byte dayOfMonth = bcdToDec(Wire.read());
  byte month      = bcdToDec(Wire.read() & 0x1F);
  byte year       = bcdToDec(Wire.read());

  Serial.print("20");
  if (year < 10) Serial.print("0");
  Serial.print(year);
  Serial.print("-");

  if (month < 10) Serial.print("0");
  Serial.print(month);
  Serial.print("-");

  if (dayOfMonth < 10) Serial.print("0");
  Serial.print(dayOfMonth);
  Serial.print(" ");

  if (hour < 10) Serial.print("0");
  Serial.print(hour);
  Serial.print(":");

  if (minute < 10) Serial.print("0");
  Serial.print(minute);
  Serial.print(":");

  if (second < 10) Serial.print("0");
  Serial.print(second);

  Serial.print("  Wochentag: ");
  Serial.println(dayOfWeek);
}

float readDS3231Temperature() {
  Wire.beginTransmission(DS3231_ADDR);
  Wire.write(0x11);
  Wire.endTransmission();

  Wire.requestFrom(DS3231_ADDR, 2);

  int8_t msb = Wire.read();
  byte lsb = Wire.read();

  return msb + ((lsb >> 6) * 0.25);
}

void setup() {
  Serial.begin(115200);
  Wire.begin();

  // Nur EINMAL aktivieren, danach wieder auskommentieren!
  // Sekunden, Minuten, Stunden, Wochentag, Tag, Monat, Jahr
  // setDS3231Time(0, 30, 14, 3, 19, 5, 26);
}

void loop() {
  readDS3231Time();

  Serial.print("Temperatur: ");
  Serial.print(readDS3231Temperature());
  Serial.println(" C");

  delay(1000);
}