Simple test¶
Ensure your device works with this simple test.
1# SPDX-FileCopyrightText: 2023 Jeff Epler for Adafruit Industries
2# SPDX-FileCopyrightText: 2023 Limor Fried for Adafruit Industries
3#
4# SPDX-License-Identifier: Unlicense
5
6import time
7import bitmaptools
8import displayio
9import gifio
10import ulab.numpy as np
11
12import adafruit_pycamera
13
14pycam = adafruit_pycamera.PyCamera()
15# pycam.live_preview_mode()
16
17settings = (
18 None,
19 "resolution",
20 "effect",
21 "mode",
22 "led_level",
23 "led_color",
24 "timelapse_rate",
25)
26curr_setting = 0
27
28print("Starting!")
29# pycam.tone(200, 0.1)
30last_frame = displayio.Bitmap(pycam.camera.width, pycam.camera.height, 65535)
31onionskin = displayio.Bitmap(pycam.camera.width, pycam.camera.height, 65535)
32timelapse_remaining = None
33timelapse_timestamp = None
34
35while True:
36 if pycam.mode_text == "STOP" and pycam.stop_motion_frame != 0:
37 # alpha blend
38 new_frame = pycam.continuous_capture()
39 bitmaptools.alphablend(
40 onionskin, last_frame, new_frame, displayio.Colorspace.RGB565_SWAPPED
41 )
42 pycam.blit(onionskin)
43 elif pycam.mode_text == "GBOY":
44 bitmaptools.dither(
45 last_frame, pycam.continuous_capture(), displayio.Colorspace.RGB565_SWAPPED
46 )
47 pycam.blit(last_frame)
48 elif pycam.mode_text == "LAPS":
49 if timelapse_remaining is None:
50 pycam.timelapsestatus_label.text = "STOP"
51 else:
52 timelapse_remaining = timelapse_timestamp - time.time()
53 pycam.timelapsestatus_label.text = f"{timelapse_remaining}s / "
54 # Manually updating the label text a second time ensures that the label
55 # is re-painted over the blitted preview.
56 pycam.timelapse_rate_label.text = pycam.timelapse_rate_label.text
57 pycam.timelapse_submode_label.text = pycam.timelapse_submode_label.text
58
59 # only in high power mode do we continuously preview
60 if (timelapse_remaining is None) or (
61 pycam.timelapse_submode_label.text == "HiPwr"
62 ):
63 pycam.blit(pycam.continuous_capture())
64 if pycam.timelapse_submode_label.text == "LowPwr" and (
65 timelapse_remaining is not None
66 ):
67 pycam.display.brightness = 0.05
68 else:
69 pycam.display.brightness = 1
70 pycam.display.refresh()
71
72 if timelapse_remaining is not None and timelapse_remaining <= 0:
73 # no matter what, show what was just on the camera
74 pycam.blit(pycam.continuous_capture())
75 # pycam.tone(200, 0.1) # uncomment to add a beep when a photo is taken
76 try:
77 pycam.display_message("Snap!", color=0x0000FF)
78 pycam.capture_jpeg()
79 except TypeError as e:
80 pycam.display_message("Failed", color=0xFF0000)
81 time.sleep(0.5)
82 except RuntimeError as e:
83 pycam.display_message("Error\nNo SD Card", color=0xFF0000)
84 time.sleep(0.5)
85 pycam.live_preview_mode()
86 pycam.display.refresh()
87 pycam.blit(pycam.continuous_capture())
88 timelapse_timestamp = (
89 time.time() + pycam.timelapse_rates[pycam.timelapse_rate] + 1
90 )
91 else:
92 pycam.blit(pycam.continuous_capture())
93 # print("\t\t", capture_time, blit_time)
94
95 pycam.keys_debounce()
96 # test shutter button
97 if pycam.shutter.long_press:
98 print("FOCUS")
99 print(pycam.autofocus_status)
100 pycam.autofocus()
101 print(pycam.autofocus_status)
102 if pycam.shutter.short_count:
103 print("Shutter released")
104 if pycam.mode_text == "STOP":
105 pycam.capture_into_bitmap(last_frame)
106 pycam.stop_motion_frame += 1
107 try:
108 pycam.display_message("Snap!", color=0x0000FF)
109 pycam.capture_jpeg()
110 except TypeError as e:
111 pycam.display_message("Failed", color=0xFF0000)
112 time.sleep(0.5)
113 except RuntimeError as e:
114 pycam.display_message("Error\nNo SD Card", color=0xFF0000)
115 time.sleep(0.5)
116 pycam.live_preview_mode()
117
118 if pycam.mode_text == "GBOY":
119 try:
120 f = pycam.open_next_image("gif")
121 except RuntimeError as e:
122 pycam.display_message("Error\nNo SD Card", color=0xFF0000)
123 time.sleep(0.5)
124 continue
125
126 with gifio.GifWriter(
127 f,
128 pycam.camera.width,
129 pycam.camera.height,
130 displayio.Colorspace.RGB565_SWAPPED,
131 dither=True,
132 ) as g:
133 g.add_frame(last_frame, 1)
134
135 if pycam.mode_text == "GIF":
136 try:
137 f = pycam.open_next_image("gif")
138 except RuntimeError as e:
139 pycam.display_message("Error\nNo SD Card", color=0xFF0000)
140 time.sleep(0.5)
141 continue
142 i = 0
143 ft = []
144 pycam._mode_label.text = "RECORDING" # pylint: disable=protected-access
145
146 pycam.display.refresh()
147 with gifio.GifWriter(
148 f,
149 pycam.camera.width,
150 pycam.camera.height,
151 displayio.Colorspace.RGB565_SWAPPED,
152 dither=True,
153 ) as g:
154 t00 = t0 = time.monotonic()
155 while (i < 15) or not pycam.shutter_button.value:
156 i += 1
157 _gifframe = pycam.continuous_capture()
158 g.add_frame(_gifframe, 0.12)
159 pycam.blit(_gifframe)
160 t1 = time.monotonic()
161 ft.append(1 / (t1 - t0))
162 print(end=".")
163 t0 = t1
164 pycam._mode_label.text = "GIF" # pylint: disable=protected-access
165 print(f"\nfinal size {f.tell()} for {i} frames")
166 print(f"average framerate {i/(t1-t00)}fps")
167 print(f"best {max(ft)} worst {min(ft)} std. deviation {np.std(ft)}")
168 f.close()
169 pycam.display.refresh()
170
171 if pycam.mode_text == "JPEG":
172 pycam.tone(200, 0.1)
173 try:
174 pycam.display_message("Snap!", color=0x0000FF)
175 pycam.capture_jpeg()
176 pycam.live_preview_mode()
177 except TypeError as e:
178 pycam.display_message("Failed", color=0xFF0000)
179 time.sleep(0.5)
180 pycam.live_preview_mode()
181 except RuntimeError as e:
182 pycam.display_message("Error\nNo SD Card", color=0xFF0000)
183 time.sleep(0.5)
184
185 if pycam.card_detect.fell:
186 print("SD card removed")
187 pycam.unmount_sd_card()
188 pycam.display.refresh()
189 if pycam.card_detect.rose:
190 print("SD card inserted")
191 pycam.display_message("Mounting\nSD Card", color=0xFFFFFF)
192 for _ in range(3):
193 try:
194 print("Mounting card")
195 pycam.mount_sd_card()
196 print("Success!")
197 break
198 except OSError as e:
199 print("Retrying!", e)
200 time.sleep(0.5)
201 else:
202 pycam.display_message("SD Card\nFailed!", color=0xFF0000)
203 time.sleep(0.5)
204 pycam.display.refresh()
205
206 if pycam.up.fell:
207 print("UP")
208 key = settings[curr_setting]
209 if key:
210 print("getting", key, getattr(pycam, key))
211 setattr(pycam, key, getattr(pycam, key) + 1)
212 if pycam.down.fell:
213 print("DN")
214 key = settings[curr_setting]
215 if key:
216 setattr(pycam, key, getattr(pycam, key) - 1)
217 if pycam.right.fell:
218 print("RT")
219 curr_setting = (curr_setting + 1) % len(settings)
220 if pycam.mode_text != "LAPS" and settings[curr_setting] == "timelapse_rate":
221 curr_setting = (curr_setting + 1) % len(settings)
222 print(settings[curr_setting])
223 # new_res = min(len(pycam.resolutions)-1, pycam.get_resolution()+1)
224 # pycam.set_resolution(pycam.resolutions[new_res])
225 pycam.select_setting(settings[curr_setting])
226 if pycam.left.fell:
227 print("LF")
228 curr_setting = (curr_setting - 1 + len(settings)) % len(settings)
229 if pycam.mode_text != "LAPS" and settings[curr_setting] == "timelaps_rate":
230 curr_setting = (curr_setting + 1) % len(settings)
231 print(settings[curr_setting])
232 pycam.select_setting(settings[curr_setting])
233 # new_res = max(1, pycam.get_resolution()-1)
234 # pycam.set_resolution(pycam.resolutions[new_res])
235 if pycam.select.fell:
236 print("SEL")
237 if pycam.mode_text == "LAPS":
238 pycam.timelapse_submode += 1
239 pycam.display.refresh()
240 if pycam.ok.fell:
241 print("OK")
242 if pycam.mode_text == "LAPS":
243 if timelapse_remaining is None: # stopped
244 print("Starting timelapse")
245 timelapse_remaining = pycam.timelapse_rates[pycam.timelapse_rate]
246 timelapse_timestamp = time.time() + timelapse_remaining + 1
247 # dont let the camera take over auto-settings
248 saved_settings = pycam.get_camera_autosettings()
249 # print(f"Current exposure {saved_settings=}")
250 pycam.set_camera_exposure(saved_settings["exposure"])
251 pycam.set_camera_gain(saved_settings["gain"])
252 pycam.set_camera_wb(saved_settings["wb"])
253 else: # is running, turn off
254 print("Stopping timelapse")
255
256 timelapse_remaining = None
257 pycam.camera.exposure_ctrl = True
258 pycam.set_camera_gain(None) # go back to autogain
259 pycam.set_camera_wb(None) # go back to autobalance
260 pycam.set_camera_exposure(None) # go back to auto shutter