from machine import I2C, Pin
import time
# I2C setup with a slightly lower frequency for better stability
I2C_SDA_PIN = 0  # data pin
I2C_SCL_PIN = 1  # clock
I2C_BUS = 0
I2C_FREQUENCY = 100000  # Reduced frequency for stability
DS3231_ADDR = 0x68
print("I2C Data SDA on pin: ", I2C_SDA_PIN)
print("I2C Clock SCL on pin: ", I2C_SCL_PIN)
print("Checking for devices on Bus", I2C_BUS, "at frequency", I2C_FREQUENCY)
# Initialize I2C
i2c = I2C(I2C_BUS, scl=Pin(I2C_SCL_PIN), sda=Pin(I2C_SDA_PIN), freq=I2C_FREQUENCY)
scan_result = i2c.scan()
print(scan_result)
print("I2C addresses found:", [hex(device_address) for device_address in i2c.scan()])
def bcd2dec(bcd):
    """Convert binary coded decimal to decimal."""
    return ((bcd >> 4) * 10) + (bcd & 0x0F)
def read_ds3231_time():
    """Read time directly from DS3231 registers with robust error handling."""
    try:
        # Make multiple attempts
        for attempt in range(3):
            try:
                # Read 7 bytes from register 0x00
                data = i2c.readfrom_mem(DS3231_ADDR, 0x00, 7)
                # If we got here, the read was successful
                second = bcd2dec(data[0] & 0x7F)  # Mask out CH bit
                minute = bcd2dec(data[1] & 0x7F)
                hour_reg = data[2]
                if hour_reg & 0x40:  # 12-hour mode
                    hour = bcd2dec(hour_reg & 0x1F)
                    if hour_reg & 0x20:  # PM
                        hour += 12
                else:  # 24-hour mode
                    hour = bcd2dec(hour_reg & 0x3F)
                weekday = bcd2dec(data[3] & 0x07)
                day = bcd2dec(data[4] & 0x3F)
                month_reg = data[5]
                month = bcd2dec(month_reg & 0x1F)
                year = bcd2dec(data[6]) + 2000
                return (year, month, day, weekday, hour, minute, second)
            except Exception as e:
                print(f"Attempt {attempt+1}: Error reading time: {e}")
                time.sleep(0.1)  # Short delay before retry
        # If all attempts failed
        print("All attempts to read time failed")
        return (0, 0, 0, 0, 0, 0, 0)
    except Exception as e:
        print(f"Unexpected error: {e}")
        return (0, 0, 0, 0, 0, 0, 0)
# Main loop
print("\nAttempting to read time from DS3231...")
try:
    while True:
        # Get date and time
        year, month, day, weekday, hour, minute, second = read_ds3231_time()
        # Get weekday name
        days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
        weekday_name = days[weekday - 1] if 1 <= weekday <= 7 else "Unknown"
        # Print time even if zeros, so we can see if it ever succeeds
        print(f"Date: {year:04d}-{month:02d}-{day:02d} ({weekday_name})")
        print(f"Time: {hour:02d}:{minute:02d}:{second:02d}")
        print("-" * 40)
        # Longer delay to reduce I2C traffic
        time.sleep(2)
except KeyboardInterrupt:
    print("\nProgram stopped by user")