Skip to content

Instantly share code, notes, and snippets.

@jjsanderson
Created February 19, 2025 12:16
Show Gist options
  • Save jjsanderson/17cadcaba2a868596e3d4a01488955d6 to your computer and use it in GitHub Desktop.
Save jjsanderson/17cadcaba2a868596e3d4a01488955d6 to your computer and use it in GitHub Desktop.
Pimoroni Inky Frame wake-from-sleep example code, demonstrating current quirks as of 2025-02-19
import time
import machine
import inky_frame
from pcf85063a import PCF85063A
from pimoroni_i2c import PimoroniI2C
"""
Test sketch to work out wake-from-sleep behaviour on Inky Frame.
I spent far too long trying to debug wake-from-sleep. This example code is about
as minimal as I could get to finally work out what's going on.
TL;DR: wake-from-sleep only works how you think it should if you're running off
batteries.
To test this code, save it to your Inky Frame as `main.py`. Ensure `inky_frame.py`
is also present. Try with USB power, and battery power.
Behaviours I see in my testing, on a Pico W Inky Frame 4.0 and using Pimoroni's
2024-12-03 v1.24.0-rc0 MicroPython build:
On USB power:
- Cycles the LEDs in sequence to indicate startup
- First boot is flagged as 'woken by button' (LED D)
- Wakes from sleep on timer
- Cycles the LEDs in sequence to indicate wake
- Flags that as 'Woken by button' (LED D)
- Waking with a button press does not work
- No button press match is found.
On battery power:
- Requires a button press to start up, flags that as 'woken by button' (LED D)
- Cycles the LEDs in sequence to indicate startup
- Wakes from sleep on timer
- Cycles the LEDs in sequence to indicate wake
- Flags that as 'Woken by RTC' (LED E)
- Wakes from sleep on button press
- Cycles the LEDs in sequence to indicate wake
- Flags that as 'Woken by button' (LED D)
- Correctly identifies which button is pressed. (LED A or B)
"""
I2C_SDA_PIN = 4
I2C_SCL_PIN = 5
HOLD_VSYS_EN_PIN = 2
# set up and enable vsys hold so we don't go to sleep before we're ready
hold_vsys_en_pin = machine.Pin(HOLD_VSYS_EN_PIN, machine.Pin.OUT)
hold_vsys_en_pin.value(True)
UPDATE_INTERVAL = 1 # minutes
# intialise the pcf85063a real time clock chip
i2c = PimoroniI2C(I2C_SDA_PIN, I2C_SCL_PIN, 100000)
rtc = PCF85063A(i2c)
inky_frame.pcf_to_pico_rtc() # Sync Inky RTC time to Pico's RTC
year, month, day, dow, hour, minute, second, _ = machine.RTC().datetime()
# Show that we're running
leds = [inky_frame.button_a.led, inky_frame.button_b.led, inky_frame.button_c.led, inky_frame.button_d.led, inky_frame.button_e.led]
for led in leds:
led.on()
time.sleep(0.1)
led.off()
time.sleep(0.1)
rtc.enable_timer_interrupt(True)
while True:
if inky_frame.woken_by_rtc():
print("Woken by RTC")
inky_frame.button_e.led.on()
time.sleep(1)
inky_frame.button_e.led.off()
elif inky_frame.woken_by_button():
print("Woken by button")
inky_frame.button_d.led.on()
# A button was pressed, set the display_mode
if inky_frame.button_a.read():
print("Woken by button A")
inky_frame.button_a.led.on()
time.sleep(1)
inky_frame.button_a.led.off()
elif inky_frame.button_b.read():
print("Woken by button B")
inky_frame.button_b.led.on()
time.sleep(1)
inky_frame.button_b.led.off()
elif inky_frame.button_c.read():
print("Woken by button C")
elif inky_frame.button_d.read():
print("Woken by button D")
# We're using button D led to indicate a 'wake from button'
# so don't flash it here
elif inky_frame.button_e.read():
print("Woken by button E")
# We're using button E led to indicate a 'wake from RTC'
# so don't flash it here
time.sleep(1)
inky_frame.button_d.led.off()
# print current (real) time
year, month, day, dow, hour, minute, second, _ = machine.RTC().datetime()
print(f"{year:04}/{month:02}/{day:02} {hour:02}:{minute:02}:{second:02}")
# Time to have a little nap until the next update
print(f"Sleeping for {UPDATE_INTERVAL} minutes")
# Some example code uses this construction, which I think maxes out at 255 seconds
# rtc.set_timer(UPDATE_INTERVAL)
# This call appears in more recent examples, and works in minutes - much more useful.
inky_frame.sleep_for(UPDATE_INTERVAL)
# Enable wake-from-sleep interrupts
hold_vsys_en_pin.init(machine.Pin.IN)
# Pause execution while on USB power. This is why wake-on-button doesn't work on USB, I think?
# I _think_ this isn't needed if using inky_frame.sleep_for(), as that simulates the delay already
# however, removing this line doesn't fix the wake-on-button-on-USB-power issue.
time.sleep(UPDATE_INTERVAL)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment