Skip to content

Commit

Permalink
Use the new screensaver class in Pam's, Logic, and Euclid scripts (#312)
Browse files Browse the repository at this point in the history
* Blank the screen

* Fix a bug in the ain on-fall callback

* Revert "Remove magic numbers for the I/O pins, replace with named constants"

This reverts commit 327c3cc.

* Show the gate length (to the nearest ms) on the screen, add the screensaver to G&T. Move the screensaver activation & blank timeouts into the Screensaver class itself instead of redefining them externally

* Add a new wrapped Oled class that automatically checks for screensaver & screen-blanking. Use this wrapper instead of europi.oled in the 3 scripts that use the screensaver

* Revert "Increase the sensitivity of the knobs for waking up the screensaver"

This reverts commit 0f21705.

* Change centre_text so it doesn't call .show() by default, add clear_first and auto_show arguments to centre_text, modify all extant calls to centre_text to use the correct auto_show behaviour

* Go back to high-sensitivity for the knobs

* More Linting. Remove the time import from euclid as it's not used anymore

* Remove lingering references to .screensaver

* Move module imports first, re-add time to deal with CI failures

* Try using utime instead of time to see if that makes CI happier

* Revert the change to make centre_text auto-show by default, revert associated changes to other scripts

* Revert screensaver-related changes & linting updates to non-essential scripts

* Use the new screensaver class in Euclid and Logic

* Use the new screensaver class in Pam's

* Revert changes to europi.py resulting from rebase

* Use the new screensaver in Kompari, add button handlers to clear the screensaver
  • Loading branch information
chrisib authored Feb 8, 2024
1 parent 129476e commit d3bcc59
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 113 deletions.
51 changes: 18 additions & 33 deletions software/contrib/euclid.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,15 @@
noted below
"""

import random

from europi import *
from europi_script import EuroPiScript

from experimental.euclid import generate_euclidean_pattern
from experimental.screensaver import Screensaver

import random
import time

## Duration before we blank the screen
SCREENSAVER_TIMEOUT_MS = 1000 * 60 * 20
from experimental.screensaver import OledWithScreensaver

ssoled = OledWithScreensaver()

class EuclidGenerator:
"""Generates the euclidean rhythm for a single output
Expand Down Expand Up @@ -150,17 +147,17 @@ def draw(self):
g = self.script.generators[generator_index]
pattern_str = str(g)

oled.fill(0)
oled.text(f"-- CV {generator_index+1} --", 0, 0)
ssoled.fill(0)
ssoled.text(f"-- CV {generator_index+1} --", 0, 0)
if len(pattern_str) > 16:
pattern_row1 = pattern_str[0:16]
pattern_row2 = pattern_str[16:]
oled.text(f"{pattern_row1}", 0, 10)
oled.text(f"{pattern_row2}", 0, 20)
ssoled.text(f"{pattern_row1}", 0, 10)
ssoled.text(f"{pattern_row2}", 0, 20)
else:
oled.text(f"{pattern_str}", 0, 10)
ssoled.text(f"{pattern_str}", 0, 10)

oled.show()
ssoled.show()

class SettingsMenu:
"""A menu screen for controlling a single setting of the generator
Expand Down Expand Up @@ -226,10 +223,10 @@ def read_knobs(self):
def draw(self):
(menu_item, lower_bound, upper_bound, current_setting, new_setting) = self.read_knobs()

oled.fill(0)
oled.text(f"-- {self.menu_items[menu_item]} --", 0, 0)
oled.text(f"{current_setting} <- {new_setting}", 0, 10)
oled.show()
ssoled.fill(0)
ssoled.text(f"-- {self.menu_items[menu_item]} --", 0, 0)
ssoled.text(f"{current_setting} <- {new_setting}", 0, 10)
ssoled.show()

def apply_setting(self):
"""Apply the current setting
Expand Down Expand Up @@ -277,12 +274,9 @@ def __init__(self):

self.channel_menu = ChannelMenu(self)
self.settings_menu = SettingsMenu(self)
self.screensaver = Screensaver()

self.active_screen = self.channel_menu

self.last_interaction_time = time.ticks_ms()

@din.handler
def on_rising_clock():
"""Handler for the rising edge of the input clock
Expand All @@ -305,11 +299,9 @@ def on_falling_clock():
def on_b1_press():
"""Handler for pressing button 1
"""
self.last_interaction_time = time.ticks_ms()
ssoled.notify_user_interaction()

if self.active_screen == self.screensaver:
self.active_screen = self.channel_menu
elif self.active_screen == self.channel_menu:
if self.active_screen == self.channel_menu:
self.activate_settings_menu()
else:
self.settings_menu.apply_setting()
Expand All @@ -319,11 +311,9 @@ def on_b1_press():
def on_b2_press():
"""Handler for pressing button 2
"""
self.last_interaction_time = time.ticks_ms()
ssoled.notify_user_interaction()

if self.active_screen == self.screensaver:
self.active_screen = self.channel_menu
elif self.active_screen == self.channel_menu:
if self.active_screen == self.channel_menu:
self.activate_settings_menu()
else:
self.activate_channel_menu()
Expand Down Expand Up @@ -381,11 +371,6 @@ def save(self):

def main(self):
while True:
# check if we've been idle for long enough to trigger the screensaver
now = time.ticks_ms()
if time.ticks_diff(now, self.last_interaction_time) > SCREENSAVER_TIMEOUT_MS:
self.active_screen = self.screensaver

self.active_screen.draw()

if __name__=="__main__":
Expand Down
14 changes: 13 additions & 1 deletion software/contrib/kompari.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
from europi import *
from europi_script import EuroPiScript

from experimental.screensaver import OledWithScreensaver

ssoled = OledWithScreensaver()

class Kompari(EuroPiScript):
"""The main Kompari script. See module comment for usage
"""
Expand All @@ -29,6 +33,14 @@ class Kompari(EuroPiScript):
def __init__(self):
super().__init__()

@b1.handler
def on_b1_press():
ssoled.notify_user_interaction()

@b2.handler
def on_b2_press():
ssoled.notify_user_interaction()

@classmethod
def display_name(cls):
return "Kompari"
Expand Down Expand Up @@ -60,7 +72,7 @@ def main(self):
cv5.voltage(min(x, upper_bound) * MAX_OUTPUT_VOLTAGE)
cv6.voltage(max(lower_bound, min(x, upper_bound)) * MAX_OUTPUT_VOLTAGE)

oled.centre_text(f"{lower_bound:0.1f} {x:0.1f} {upper_bound:0.1f}")
ssoled.centre_text(f"{lower_bound:0.1f} {x:0.1f} {upper_bound:0.1f}", clear_first=True, auto_show=True)

if __name__ == "__main__":
Kompari().main()
59 changes: 25 additions & 34 deletions software/contrib/logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@
from europi import *
from europi_script import EuroPiScript

## How many milliseconds of idleness do we need before we trigger the screensaver?
#
# =20 minutes
SCREENSAVER_TIMEOUT_MS = 1000 * 60 * 20
from experimental.screensaver import OledWithScreensaver

ssoled = OledWithScreensaver()

## Anything above this threshold is considered ON for the analog
# input
Expand All @@ -26,67 +25,59 @@ class Logic(EuroPiScript):
"""
def __init__(self):
super().__init__()

# keep track of the last time the user interacted with the module
# if we're idle for too long, start the screensaver
self.last_interaction_time = time.ticks_ms()

@classmethod
def display_name(cls):
return "Logic"

def main(self):
"""The main loop
Connects event handlers for clock-in and button presses
and runs the main loop
"""

@b1.handler
def on_b1_press():
self.last_interaction_time = time.ticks_ms()
ssoled.notify_user_interaction()

@b2.handler
def on_b2_press():
self.last_interaction_time = time.ticks_ms()
ssoled.notify_user_interaction()

while True:

# read both inputs as 0/1
x = din.value()
y = 1 if ain.read_voltage() > AIN_VOLTAGE_CUTOFF else 0

x_and_y = x & y
x_or_y = x | y
x_xor_y = x ^ y
x_nand_y = abs(x_and_y - 1) # bit of a hack to get the inverted values
x_nor_y = abs(x_or_y -1) # ~ results in some -2 results, which we don't want
x_xnor_y = abs(x_xor_y -1) # so some simple int math will suffice

cv1.value(x_and_y)
cv2.value(x_or_y)
cv3.value(x_xor_y)
cv4.value(x_nand_y)
cv5.value(x_nor_y)
cv6.value(x_xnor_y)

# check if we've been idle for too long; if so, blank the screen
# to prevent burn-in
now = time.ticks_ms()
if time.ticks_diff(now, self.last_interaction_time) > SCREENSAVER_TIMEOUT_MS:
oled.fill(0)
else:
display_txt = " &:{0} |:{1} ^:{2}\n!&:{3} !|:{4} !^:{5}".format(
x_and_y,
x_or_y,
x_xor_y,
x_nand_y,
x_nor_y,
x_xnor_y
)
oled.centre_text(display_txt)
oled.show()

display_txt = " &:{0} |:{1} ^:{2}\n!&:{3} !|:{4} !^:{5}".format(
x_and_y,
x_or_y,
x_xor_y,
x_nand_y,
x_nor_y,
x_xnor_y
)

ssoled.centre_text(display_txt)

if __name__ == "__main__":
Logic().main()

Loading

0 comments on commit d3bcc59

Please sign in to comment.