Files
forge-invar/i2c.py
T
2026-10-27 23:26:45 +01:00

72 lines
2.2 KiB
Python
Executable File

#!/usr/bin/env python3
# see https://electricalflux.com/mcu-raspberry/i2c-oled-display-raspberry-pi-5-wiring-code
import collections
import pathlib
import sys
from luma.core.error import DeviceNotFoundError
from luma.core.interface.serial import i2c
from luma.core.render import canvas
from luma.oled.device import sh1106
TARGET_FILE = pathlib.Path(__file__).parent / "forge_default_save.txt"
TARGET_FILE_BACKUP = pathlib.Path(__file__).parent / "forge_default_save.txt.bck"
data: dict[str, float] = collections.defaultdict(lambda: 0)
def readfile():
try:
content = TARGET_FILE.read_text()
except: # noqa: E722
return
TARGET_FILE_BACKUP.write_text(content)
for line in content.splitlines():
key, value = line.split("=", maxsplit=2)
data[key] = float(value)
def main():
if TARGET_FILE_BACKUP.exists() and TARGET_FILE.exists():
TARGET_FILE.write_text(TARGET_FILE_BACKUP.read_text())
# Pin definitions: I2C Bus 1 (SDA=GPIO2, SCL=GPIO3)
# Default SSD1306 I2C address is 0x3C
serial_interface = i2c(port=1, address=0x3C)
try:
# Initialize the device. If using SH1106, change ssd1306 to sh1106
device = sh1106(serial_interface, width=128, height=64, rotate=0)
except DeviceNotFoundError:
print("Fatal: OLED not found at 0x3C. Check wiring and run i2cdetect -y 1")
sys.exit(1)
except OSError as e:
if e.errno == 121:
print(
"Fatal: Remote I/O error. I2C bus is locked or physically disconnected."
)
else:
print(f"Fatal OS Error: {e}")
sys.exit(1)
try:
while True:
readfile()
with canvas(device) as draw:
# draw.rectangle((0, 50, 127, 60), outline="white", fill="black")
draw.text((0, 0), f"time={data['time']}", fill="white")
draw.text((0, 10), f"beats={data['beats']}", fill="white")
except KeyboardInterrupt:
print("Exiting gracefully...")
except OSError as e:
if e.errno == 121:
print("Runtime Error: I2C bus dropped. Check physical connections.")
device.cleanup()
sys.exit(1)
finally:
device.cleanup()
if __name__ == "__main__":
main()