1515from europi_script import EuroPiScript
1616
1717from experimental .math_extras import gray_encode
18+ from experimental .screensaver import OledWithScreensaver
1819
1920import configuration
2021
2122
2223class BinaryCounter (EuroPiScript ):
2324 MAX_N = (1 << NUM_CVS ) - 1
2425
26+ MODE_DISCRETE = 0
27+ MODE_CONTINUOUS = 1
28+ N_MODES = 2
29+
2530 def __init__ (self ):
2631 super ().__init__ ()
32+ self .load_state ()
33+ self .state_dirty = False
34+
35+ self .ssoled = OledWithScreensaver ()
2736
2837 self .n = 0
2938 self .k = int (
@@ -36,9 +45,7 @@ def __init__(self):
3645
3746 din .handler (self .on_gate_rise )
3847 din .handler_falling (self .on_gate_fall )
39- b1 .handler (self .on_gate_rise )
40- b1 .handler_falling (self .on_gate_fall )
41-
48+ b1 .handler (self .cycle_mode )
4249 b2 .handler (self .reset )
4350
4451 @classmethod
@@ -51,14 +58,32 @@ def config_points(cls):
5158 ),
5259 ]
5360
61+ def load_state (self ):
62+ cfg = self .load_state_json ()
63+ self .mode = cfg .get ("mode" , self .MODE_DISCRETE )
64+
65+ def save_state (self ):
66+ cfg = {
67+ "mode" : self .mode
68+ }
69+ self .save_state_json (cfg )
70+ self .state_dirty = False
71+
72+ def cycle_mode (self ):
73+ self .mode = (self .mode + 1 ) % self .N_MODES
74+ self .state_dirty = True
75+ self .ssoled .notify_user_interaction ()
76+
5477 def on_gate_rise (self ):
5578 self .gate_recvd = True
5679
5780 def on_gate_fall (self ):
58- turn_off_all_cvs ()
81+ if self .mode == self .MODE_DISCRETE :
82+ turn_off_all_cvs ()
5983
6084 def reset (self ):
6185 self .n = 0
86+ self .ssoled .notify_user_interaction ()
6287
6388 def set_outputs (self ):
6489 if self .config .USE_GRAY_ENCODING :
@@ -74,19 +99,42 @@ def set_outputs(self):
7499
75100
76101 def main (self ):
102+ current_k1 = 0
103+ current_k2 = 0
104+ prev_k1 = 0
105+ prev_k2 = 0
106+ WIGGLE_THRESHOLD = 0.05
107+
77108 while True :
109+ current_k1 = k1 .percent ()
110+ current_k2 = k2 .percent ()
111+ if (
112+ abs (prev_k1 - current_k1 ) >= WIGGLE_THRESHOLD
113+ or abs (prev_k2 - current_k2 ) >= WIGGLE_THRESHOLD
114+ ):
115+ self .ssoled .notify_user_interaction ()
116+ prev_k1 = current_k1
117+ prev_k2 = current_k2
118+
78119 self .k = int (
79120 (
80- k1 . percent () + k2 . percent () * ain .percent ()
121+ current_k1 + current_k2 * ain .percent ()
81122 ) * self .MAX_N
82123 )
124+ # minimum of 1; k==0 will do nothing, which isn't interesting
125+ if self .k == 0 :
126+ self .k = 1
127+
128+ if self .state_dirty :
129+ self .save_state ()
83130
84131 if self .gate_recvd :
85132 self .set_outputs ()
86133 self .n = (self .n + self .k ) & self .MAX_N
87134 self .gate_recvd = False
88135
89- oled .centre_text (f"""k = { self .k }
136+ self .ssoled .centre_text (f"""{ 'Discrete' if self .mode == self .MODE_DISCRETE else 'Continuous' }
137+ k = { self .k }
90138{ self .n :06b} """ )
91139
92140
0 commit comments