Skip to content

Commit 8f288c4

Browse files
authored
Merge pull request #2797 from makermelissa/main
Rewrote Wearable Time Lapse Camera script in python
2 parents 5c2fcda + d09369e commit 8f288c4

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# SPDX-FileCopyrightText: 2024 Melissa leBlanc-Williams for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
#!/usr/bin/env python3
6+
7+
import os
8+
import re
9+
import time
10+
import board
11+
import digitalio
12+
13+
# Timelapse script, because timelapse options in raspistill don't power
14+
# down the camera between captures. Script also provides a camera busy LED
15+
# (v2 cameras don't include one) and a system halt button.
16+
# 'gpio' command requires WiringPi: sudo apt-get install wiringpi
17+
# Limitations: if DEST is FAT32 filesystem, max of 65535 files in directory;
18+
# if DEST is ext4 filesystem, may have performance issues above 10K files.
19+
# For intervals <2 sec, better just to use raspistill's timelapse feature.
20+
21+
# Configurable stuff...
22+
INTERVAL = 15 # Time between captures, in seconds
23+
WIDTH = 1280 # Image width in pixels
24+
HEIGHT = 720 # Image height in pixels
25+
QUALITY = 51 # JPEG image quality (0-100)
26+
DEST = "/home/pi/timelapse" # Destination directory (MUST NOT CONTAIN NUMBERS)
27+
PREFIX = "img" # Image prefix (MUST NOT CONTAIN NUMBERS)
28+
HALT_PIN = board.D21 # Halt button GPIO pin (other end to GND)
29+
LED_PIN = board.D5 # Status LED pin (v2 Pi cam lacks built-in LED)
30+
COMMAND = "libcamera-still -n --width {width} --height {height} -q {quality} --thumb none -t 250 -o {outfile}" # pylint: disable=line-too-long
31+
# COMMAND = "raspistill -n -w {width -h {height} -q {quality} -th none -t 250 -o {outfile}"
32+
33+
def main():
34+
prevtime = 0 # Time of last capture (0 = do 1st image immediately)
35+
halt = digitalio.DigitalInOut(HALT_PIN)
36+
halt.switch_to_input(pull=digitalio.Pull.UP)
37+
led = digitalio.DigitalInOut(LED_PIN)
38+
led.switch_to_output()
39+
40+
# Create destination directory (if not present)
41+
os.makedirs(DEST, exist_ok=True)
42+
43+
# Find index of last image (if any) in directory, start at this + 1
44+
files = os.listdir(DEST)
45+
numbers = [
46+
int(re.search(r"\d+", f).group())
47+
for f in files
48+
if f.startswith(PREFIX) and re.search(r"\d+", f)
49+
]
50+
numbers.sort()
51+
frame = numbers[-1] + 1 if numbers else 1
52+
currenttime = time.monotonic()
53+
54+
while True:
55+
while time.monotonic() < prevtime + INTERVAL: # Until next image capture time
56+
currenttime = time.monotonic()
57+
# Check for halt button -- hold >= 2 sec
58+
while not halt.value:
59+
if time.monotonic() >= currenttime + 2:
60+
led.value = True
61+
os.system("shutdown -h now")
62+
outfile = f"{DEST}/{PREFIX}{frame:05}.jpg"
63+
# echo $OUTFILE
64+
led.value = True
65+
os.system(
66+
COMMAND.format(width=WIDTH, height=HEIGHT, quality=QUALITY, outfile=outfile)
67+
)
68+
led.value = False
69+
frame += 1 # Increment image counter
70+
prevtime = currenttime # Save image cap time
71+
72+
73+
if __name__ == "__main__":
74+
main()

0 commit comments

Comments
 (0)