Created
February 19, 2025 12:16
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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