Skip to content

Commit 78dcb6f

Browse files
committed
first commit wireless osc remote for memento
1 parent 4033e68 commit 78dcb6f

File tree

1 file changed

+290
-0
lines changed

1 file changed

+290
-0
lines changed

MEMENTO/Wireless_Remote/code.py

Lines changed: 290 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,290 @@
1+
# SPDX-FileCopyrightText: 2023 Jeff Epler & John Park for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
''' Wireless remote for MEMENTO camera with TouchOSC'''
5+
6+
import time
7+
import os
8+
import bitmaptools
9+
import displayio
10+
import gifio
11+
import ulab.numpy as np
12+
import adafruit_pycamera
13+
import wifi
14+
import socketpool
15+
import microosc
16+
17+
UDP_HOST = ""
18+
UDP_PORT = 8000
19+
ssid = os.getenv("CIRCUITPY_WIFI_SSID")
20+
password = os.getenv("CIRCUITPY_WIFI_PASSWORD")
21+
print("connecting to WiFi", ssid)
22+
wifi.radio.connect(ssid, password)
23+
print("my ip address:", wifi.radio.ipv4_address)
24+
socket_pool = socketpool.SocketPool(wifi.radio)
25+
26+
pycam = adafruit_pycamera.PyCamera()
27+
pycam.autofocus_init()
28+
29+
settings = (None, "resolution", "effect", "mode", "led_level", "led_color")
30+
curr_setting = 0
31+
32+
print("Starting!")
33+
last_frame = displayio.Bitmap(pycam.camera.width, pycam.camera.height, 65535)
34+
onionskin = displayio.Bitmap(pycam.camera.width, pycam.camera.height, 65535)
35+
36+
pycam.tone(800, 0.1)
37+
pycam.tone(1200, 0.05)
38+
39+
def snap_jpeg():
40+
pycam.tone(600, 0.1)
41+
try:
42+
pycam.display_message("Snap!", color=0x0000FF)
43+
pycam.capture_jpeg()
44+
pycam.live_preview_mode()
45+
except TypeError as e:
46+
pycam.display_message("Failed", color=0xFF0000)
47+
time.sleep(0.5)
48+
pycam.live_preview_mode()
49+
except RuntimeError as e:
50+
pycam.display_message("Error\nNo SD Card", color=0xFF0000)
51+
time.sleep(0.5)
52+
53+
def snap_gboy():
54+
pycam.tone(600, 0.1)
55+
try:
56+
f = pycam.open_next_image("gif")
57+
pycam.display_message("Snap!", color=0x00ff44)
58+
except RuntimeError as e:
59+
pycam.display_message("Error\nNo SD Card", color=0xFF0000)
60+
time.sleep(0.5)
61+
62+
with gifio.GifWriter(
63+
f,
64+
pycam.camera.width,
65+
pycam.camera.height,
66+
displayio.Colorspace.RGB565_SWAPPED,
67+
dither=True,
68+
) as g:
69+
g.add_frame(last_frame, 1)
70+
71+
def snap_gif():
72+
pycam.tone(600, 0.1)
73+
try:
74+
f = pycam.open_next_image("gif")
75+
except RuntimeError as e:
76+
pycam.display_message("Error\nNo SD Card", color=0xFF0000)
77+
time.sleep(0.5)
78+
i = 0
79+
ft = []
80+
pycam._mode_label.text = "RECORDING" # pylint: disable=protected-access
81+
82+
pycam.display.refresh()
83+
with gifio.GifWriter(
84+
f,
85+
pycam.camera.width,
86+
pycam.camera.height,
87+
displayio.Colorspace.RGB565_SWAPPED,
88+
dither=True,
89+
) as g:
90+
t00 = t0 = time.monotonic()
91+
while (i < 15) or not pycam.shutter_button.value:
92+
i += 1
93+
_gifframe = pycam.continuous_capture()
94+
g.add_frame(_gifframe, 0.12)
95+
pycam.blit(_gifframe)
96+
t1 = time.monotonic()
97+
ft.append(1 / (t1 - t0))
98+
print(end=".")
99+
t0 = t1
100+
pycam._mode_label.text = "GIF" # pylint: disable=protected-access
101+
print(f"\nfinal size {f.tell()} for {i} frames")
102+
print(f"average framerate {i/(t1-t00)}fps")
103+
print(f"best {max(ft)} worst {min(ft)} std. deviation {np.std(ft)}")
104+
f.close()
105+
pycam.display.refresh()
106+
pycam.tone(1200, 0.15)
107+
108+
def snap_stop():
109+
pycam.tone(600, 0.1)
110+
pycam.capture_into_bitmap(last_frame)
111+
pycam.stop_motion_frame += 1
112+
try:
113+
pycam.display_message("Snap!", color=0x0000FF)
114+
pycam.capture_jpeg()
115+
except TypeError as e:
116+
pycam.display_message("Failed", color=0xFF0000)
117+
time.sleep(0.5)
118+
except RuntimeError as e:
119+
pycam.display_message("Error\nNo SD Card", color=0xFF0000)
120+
time.sleep(0.5)
121+
pycam.live_preview_mode()
122+
123+
def toggle_handler(msg):
124+
addr = msg.addr
125+
tog_num = int(addr.replace('/1/toggle',''))
126+
if msg.args[0] == 1.0:
127+
print(tog_num, "is ON")
128+
else:
129+
print(tog_num, "is off")
130+
131+
def fader_handler(msg): # faders
132+
"""Used to handle 'fader' OscMsgs, printing it as a '*' text progress bar
133+
:param OscMsg msg: message with one required float32 value
134+
"""
135+
osc_addr = msg.addr.split('/') # chop up the address into parts
136+
# page_num = osc_addr[1]
137+
fader_num = int(osc_addr[2].replace('fader', '')) # get the number only
138+
if fader_num == 1: # led level
139+
led_val = int(msg.args[0] * 5)
140+
pycam.led_level = led_val
141+
142+
mode_texts = ("JPEG", "GIF", "GBOY", "STOP")
143+
144+
def radio_handler(msg): # Radio buttons
145+
osc_addr = msg.addr.split('/') # chop up the address into parts
146+
print(osc_addr)
147+
page_num = osc_addr[1]
148+
print("page_num:", page_num)
149+
rad_num = int(osc_addr[2].replace('radio', '')) # get the number only
150+
print("rad_num:", rad_num)
151+
if rad_num == 1: # MODE
152+
print("switched mode to", mode_texts[msg.args[0]])
153+
pycam.mode = msg.args[0]
154+
if rad_num == 2: # resolution
155+
print("switched resolution")
156+
pycam.resolution = msg.args[0]
157+
if rad_num == 3: # LED color
158+
print("set color")
159+
pycam.led_color = msg.args[0]
160+
if rad_num == 4: # effects
161+
print("switched effect")
162+
pycam.effect = msg.args[0]
163+
164+
def button_handler(msg): # buttons
165+
addr = msg.addr
166+
button_num = int(addr.replace('/1/button',''))
167+
if msg.args[0] == 1.0:
168+
print(button_num, "is ON")
169+
if button_num == 1:
170+
pycam.tone(1200, 0.05)
171+
pycam.tone(1600, 0.05)
172+
if pycam.mode_text == "JPEG":
173+
snap_jpeg()
174+
if pycam.mode_text == "GBOY":
175+
snap_gboy()
176+
if pycam.mode_text == "GIF":
177+
snap_gif()
178+
if pycam.mode_text == "STOP":
179+
snap_stop()
180+
181+
if button_num == 2: # focus
182+
pycam.tone(1800, 0.05)
183+
print("FOCUS")
184+
print(pycam.autofocus_status)
185+
pycam.autofocus()
186+
print(pycam.autofocus_status)
187+
pycam.tone(1400, 0.05)
188+
189+
else:
190+
print(button_num, "is off")
191+
192+
dispatch_map = {
193+
"/": lambda msg: print("msg:", msg.addr, msg.args), # prints all messages
194+
"/1/fader": fader_handler,
195+
"/2/fader": fader_handler,
196+
"/1/toggle": toggle_handler,
197+
"/1/button": button_handler,
198+
"/1/radio": radio_handler,
199+
"/2/radio": radio_handler
200+
}
201+
202+
osc_server = microosc.OSCServer(socket_pool, UDP_HOST, UDP_PORT, dispatch_map)
203+
print("MicroOSC server started on ", UDP_HOST, UDP_PORT)
204+
205+
206+
while True:
207+
osc_server.poll() # check for incoming OSC messages
208+
209+
if pycam.mode_text == "STOP" and pycam.stop_motion_frame != 0:
210+
# alpha blend
211+
new_frame = pycam.continuous_capture()
212+
bitmaptools.alphablend(
213+
onionskin, last_frame, new_frame, displayio.Colorspace.RGB565_SWAPPED
214+
)
215+
pycam.blit(onionskin)
216+
elif pycam.mode_text == "GBOY":
217+
bitmaptools.dither(
218+
last_frame, pycam.continuous_capture(), displayio.Colorspace.RGB565_SWAPPED
219+
)
220+
pycam.blit(last_frame)
221+
else:
222+
pycam.blit(pycam.continuous_capture())
223+
224+
pycam.keys_debounce()
225+
226+
if pycam.shutter.long_press:
227+
print("FOCUS")
228+
print(pycam.autofocus_status)
229+
pycam.autofocus()
230+
print(pycam.autofocus_status)
231+
232+
if pycam.shutter.short_count:
233+
print("Shutter released")
234+
if pycam.mode_text == "STOP":
235+
snap_stop()
236+
237+
if pycam.mode_text == "GBOY":
238+
snap_gboy()
239+
240+
if pycam.mode_text == "GIF":
241+
snap_gif()
242+
243+
if pycam.mode_text == "JPEG":
244+
snap_jpeg()
245+
246+
if pycam.card_detect.fell:
247+
print("SD card removed")
248+
pycam.unmount_sd_card()
249+
pycam.display.refresh()
250+
if pycam.card_detect.rose:
251+
print("SD card inserted")
252+
pycam.display_message("Mounting\nSD Card", color=0xFFFFFF)
253+
for _ in range(3):
254+
try:
255+
print("Mounting card")
256+
pycam.mount_sd_card()
257+
print("Success!")
258+
break
259+
except OSError as e:
260+
print("Retrying!", e)
261+
time.sleep(0.5)
262+
else:
263+
pycam.display_message("SD Card\nFailed!", color=0xFF0000)
264+
time.sleep(0.5)
265+
pycam.display.refresh()
266+
267+
if pycam.up.fell:
268+
print("UP")
269+
key = settings[curr_setting]
270+
if key:
271+
setattr(pycam, key, getattr(pycam, key) + 1)
272+
if pycam.down.fell:
273+
print("DN")
274+
key = settings[curr_setting]
275+
if key:
276+
setattr(pycam, key, getattr(pycam, key) - 1)
277+
if pycam.left.fell:
278+
print("LF")
279+
curr_setting = (curr_setting + 1) % len(settings)
280+
print(settings[curr_setting])
281+
pycam.select_setting(settings[curr_setting])
282+
if pycam.right.fell:
283+
print("RT")
284+
curr_setting = (curr_setting - 1 + len(settings)) % len(settings)
285+
print(settings[curr_setting])
286+
pycam.select_setting(settings[curr_setting])
287+
if pycam.select.fell:
288+
print("SEL")
289+
if pycam.ok.fell:
290+
print("OK")

0 commit comments

Comments
 (0)