241 lines
7.0 KiB
Python
Executable File
241 lines
7.0 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
RTC (Real-Time Clock) Demo.
|
|
|
|
Demonstrates PCF8523 RTC functionality:
|
|
- Read current date/time
|
|
- Set RTC time
|
|
- Sync with system time
|
|
- Set and monitor alarms
|
|
- Display continuous time updates
|
|
|
|
This example requires actual PCF8523 RTC hardware connected via I2C.
|
|
"""
|
|
|
|
import asyncio
|
|
import sys
|
|
import os
|
|
import time
|
|
|
|
# Add src to path
|
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../src'))
|
|
|
|
from dreader_hal import EReaderDisplayHAL
|
|
|
|
|
|
def format_time(t: time.struct_time) -> str:
|
|
"""Format struct_time as readable string."""
|
|
return time.strftime("%Y-%m-%d %H:%M:%S %A", t)
|
|
|
|
|
|
async def display_current_time(hal: EReaderDisplayHAL):
|
|
"""Display current RTC time continuously."""
|
|
print("\nDisplaying current time (Ctrl+C to stop)...\n")
|
|
|
|
try:
|
|
while True:
|
|
current = await hal.get_datetime()
|
|
if current:
|
|
print(f"\rCurrent time: {format_time(current)}", end="", flush=True)
|
|
else:
|
|
print("\rRTC not available", end="", flush=True)
|
|
|
|
await asyncio.sleep(1.0)
|
|
|
|
except KeyboardInterrupt:
|
|
print("\n")
|
|
|
|
|
|
async def set_time_demo(hal: EReaderDisplayHAL):
|
|
"""Demonstrate setting RTC time."""
|
|
print("\n=== Setting RTC Time ===")
|
|
|
|
# Show current time
|
|
current = await hal.get_datetime()
|
|
if current:
|
|
print(f"Current RTC time: {format_time(current)}")
|
|
|
|
# Set to system time
|
|
print("\nSetting RTC to current system time...")
|
|
system_time = time.localtime()
|
|
await hal.set_datetime(system_time)
|
|
print(f"System time: {format_time(system_time)}")
|
|
|
|
# Verify
|
|
await asyncio.sleep(0.5)
|
|
new_time = await hal.get_datetime()
|
|
if new_time:
|
|
print(f"New RTC time: {format_time(new_time)}")
|
|
print("✓ Time updated successfully!")
|
|
|
|
|
|
async def alarm_demo(hal: EReaderDisplayHAL):
|
|
"""Demonstrate RTC alarm functionality."""
|
|
print("\n=== RTC Alarm Demo ===")
|
|
|
|
# Get current time
|
|
current = await hal.get_datetime()
|
|
if not current:
|
|
print("Error: RTC not available")
|
|
return
|
|
|
|
print(f"Current time: {format_time(current)}")
|
|
|
|
# Set alarm for 2 minutes from now
|
|
alarm_minute = (current.tm_min + 2) % 60
|
|
alarm_hour = current.tm_hour
|
|
if alarm_minute < current.tm_min:
|
|
alarm_hour = (alarm_hour + 1) % 24
|
|
|
|
print(f"\nSetting alarm for {alarm_hour:02d}:{alarm_minute:02d}...")
|
|
await hal.set_alarm(hour=alarm_hour, minute=alarm_minute)
|
|
print("✓ Alarm set!")
|
|
|
|
print("\nNote: Alarm functionality requires checking alarm status")
|
|
print("via the low-level RTC driver (hal.rtc.check_alarm())")
|
|
|
|
|
|
async def interactive_menu(hal: EReaderDisplayHAL):
|
|
"""Interactive menu for RTC operations."""
|
|
while True:
|
|
print("\n" + "="*50)
|
|
print("RTC Demo Menu")
|
|
print("="*50)
|
|
print("1. Display current time")
|
|
print("2. Set time to system time")
|
|
print("3. Set custom time")
|
|
print("4. Set alarm")
|
|
print("5. Display time continuously")
|
|
print("6. Exit")
|
|
print("="*50)
|
|
|
|
choice = input("\nEnter choice (1-6): ").strip()
|
|
|
|
if choice == "1":
|
|
current = await hal.get_datetime()
|
|
if current:
|
|
print(f"\nCurrent RTC time: {format_time(current)}")
|
|
else:
|
|
print("\nRTC not available")
|
|
|
|
elif choice == "2":
|
|
await set_time_demo(hal)
|
|
|
|
elif choice == "3":
|
|
print("\nEnter date/time (or press Enter to cancel):")
|
|
year = input("Year (YYYY): ").strip()
|
|
if not year:
|
|
continue
|
|
|
|
try:
|
|
year = int(year)
|
|
month = int(input("Month (1-12): "))
|
|
day = int(input("Day (1-31): "))
|
|
hour = int(input("Hour (0-23): "))
|
|
minute = int(input("Minute (0-59): "))
|
|
second = int(input("Second (0-59): "))
|
|
|
|
# Create struct_time (weekday and yearday are calculated)
|
|
custom_time = time.struct_time((
|
|
year, month, day, hour, minute, second, 0, 0, -1
|
|
))
|
|
|
|
print(f"\nSetting RTC to: {format_time(custom_time)}")
|
|
await hal.set_datetime(custom_time)
|
|
|
|
# Verify
|
|
await asyncio.sleep(0.5)
|
|
new_time = await hal.get_datetime()
|
|
if new_time:
|
|
print(f"Verified: {format_time(new_time)}")
|
|
print("✓ Time updated successfully!")
|
|
|
|
except (ValueError, OverflowError) as e:
|
|
print(f"\nError: Invalid date/time - {e}")
|
|
|
|
elif choice == "4":
|
|
await alarm_demo(hal)
|
|
|
|
elif choice == "5":
|
|
await display_current_time(hal)
|
|
|
|
elif choice == "6":
|
|
print("\nExiting...")
|
|
break
|
|
|
|
else:
|
|
print("\nInvalid choice. Please enter 1-6.")
|
|
|
|
|
|
async def main():
|
|
"""Main example function."""
|
|
|
|
# Create HAL with RTC enabled
|
|
hal = EReaderDisplayHAL(
|
|
width=800,
|
|
height=1200,
|
|
virtual_display=True, # Virtual display for testing
|
|
enable_orientation=False,
|
|
enable_rtc=True, # Enable RTC
|
|
enable_power_monitor=False,
|
|
)
|
|
|
|
print("="*50)
|
|
print("DReader HAL - RTC Demo")
|
|
print("="*50)
|
|
print("\nInitializing HAL with RTC...")
|
|
|
|
try:
|
|
await hal.initialize()
|
|
print("✓ HAL initialized!")
|
|
|
|
if not hal.rtc:
|
|
print("\n⚠️ Warning: RTC not available!")
|
|
print("\nThis example requires PCF8523 RTC hardware on I2C bus.")
|
|
print("RTC should be at address 0x68 on I2C bus 1.")
|
|
print("\nCheck connections:")
|
|
print(" - VCC → 3.3V (Pin 1)")
|
|
print(" - GND → GND (Pin 6)")
|
|
print(" - SDA → GPIO2 (Pin 3)")
|
|
print(" - SCL → GPIO3 (Pin 5)")
|
|
print("\nVerify with: i2cdetect -y 1")
|
|
return
|
|
|
|
print("✓ RTC initialized!")
|
|
|
|
# Show initial time
|
|
current = await hal.get_datetime()
|
|
if current:
|
|
print(f"\nCurrent RTC time: {format_time(current)}")
|
|
system_time = time.localtime()
|
|
print(f"System time: {format_time(system_time)}")
|
|
|
|
# Check if times differ
|
|
time_diff = abs(time.mktime(current) - time.mktime(system_time))
|
|
if time_diff > 2: # More than 2 seconds difference
|
|
print(f"\n⚠️ RTC differs from system time by {time_diff:.0f} seconds")
|
|
|
|
# Run interactive menu
|
|
await interactive_menu(hal)
|
|
|
|
except RuntimeError as e:
|
|
print(f"\n❌ Error: {e}")
|
|
print("\nNote: This example requires PCF8523 RTC hardware on I2C bus.")
|
|
return
|
|
|
|
except KeyboardInterrupt:
|
|
print("\n\nInterrupted by user")
|
|
|
|
finally:
|
|
# Cleanup
|
|
print("\nCleaning up...")
|
|
await hal.cleanup()
|
|
print("Done!")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
try:
|
|
asyncio.run(main())
|
|
except KeyboardInterrupt:
|
|
print("\nExiting...")
|