根据值停止函数
Stopping a function based on a value
我是 运行 树莓派上的 python 脚本。
基本上,我希望相机每 5 秒拍一张照片,但前提是我将布尔值设置为 true,它会在物理按钮上切换。
最初我将它设置为 true,然后在我的 while(true) 循环中,我想检查变量是否设置为 true,如果是,则每 5 秒开始拍照。问题是如果我使用时间 time.sleep(5)
之类的东西,它基本上会冻结所有内容,包括支票。结合我正在为按钮使用去抖动的事实,我就不可能实际切换脚本,因为我必须在 5 秒等待时间后准确按下它,正确的值检查......我已经一直在四处寻找,我认为可能的解决方案必须包括线程,但我无法全神贯注。我想到的一种解决方法是查看系统时间,如果秒数是 5 的倍数,则拍照(全部在主循环内)。这似乎有点粗略。
脚本如下:
### Imports
from goprocam import GoProCamera, constants
import board
import digitalio
from adafruit_debouncer import Debouncer
import os
import shutil
import time
### GoPro settings
goproCamera = GoProCamera.GoPro()
### Button settings
pin = digitalio.DigitalInOut(board.D12)
pin.direction = digitalio.Direction.INPUT
pin.pull = digitalio.Pull.UP
switch = Debouncer(pin, interval=0.1)
save = False #this is the variable
while(True):
switch.update()
if switch.fell:
print("Pressed, toggling value")
save = not save
if save:
goproCamera.take_photo()
goproCamera.downloadLastMedia()
time.sleep(5)
这里有一些尝试:
while(True):
switch.update()
if switch.fell:
print("Pressed, toggling value")
save = not save
if save:
current_time = time.time()
if current_time - last_pic_time >= 5:
goproCamera.take_photo()
goproCamera.downloadLastMedia()
last_pic_time = current_time
具体取决于您想要的行为类型,您可能需要 fiddle 调用 time.time()
的时间和频率。
干杯!
也许是这样的?
import threading
def set_interval(func, sec):
def func_wrapper():
set_interval(func, sec)
func()
t = threading.Timer(sec, func_wrapper)
t.start()
return t
我们在主循环中调用上面的函数。
将您的 while 循环内容包装在一个函数上:
def take_photo:
goproCamera.take_photo()
goproCamera.downloadLastMedia()
现在我们创建一个最初设置为 False 的标志,以避免创建多个线程。
请注意,我在 while 循环之前执行了此操作。我们这里只需要一个起始值。
active = False
while(True):
switch.update()
if switch.fell:
print("Pressed, toggling value")
save = not save
if save: # we need to start taking photos.
if not active: # it is not active... so it is the first time it is being called or it has been toggled to save as True again.
photo_thread = set_interval(take_photo, 5) # grabbing a handle to the thread - photo_thread - so we can cancel it later when save is set to False.
active = True # marking as active to be skipped from the loop until save is False
else:
try: # photo_thread may not exist yet so I wrapped it inside a try statement here.
photo_thread.cancel() # if we have a thread we kill it
active = False #setting to False so the next time the button is pressed we can create a new one.
让我知道它是否有效。 =)
我最后做了什么:
### Imports
from goprocam import GoProCamera, constants
import board
import digitalio
from adafruit_debouncer import Debouncer
import os
import time
import threading
### GoPro settings
gopro = GoProCamera.GoPro()
### Button settings
pin = digitalio.DigitalInOut(board.D12)
pin.direction = digitalio.Direction.INPUT
pin.pull = digitalio.Pull.UP
switch = Debouncer(pin, interval=0.1)
### Picture save location
dir_path = os.path.dirname(os.path.realpath(__file__))
new_path = dir_path+"/pictures/"
save = False
### Functions
def takePhoto(e):
while e.isSet():
gopro.take_photo()
gopro.downloadLastMedia()
fname = '100GOPRO-' + gopro.getMedia().split("/")[-1]
current_file = dir_path+'/'+fname
if os.path.isfile(current_file):
os.replace(current_file, new_path+fname) #move file, would be cleaner to download the file directly to the right folder, but the API doesn't work the way I thought it did
e.wait(5)
### Initial settings
e = threading.Event()
t1 = threading.Thread(target=takePhoto, args=([e]))
print("Starting script")
while(True):
switch.update()
if switch.fell:
#toggle value
save = not save
if save:
e.set() #should be taking pictures
else:
e.clear() #not taking pictures
if not t1.is_alive(): #start the thread if it hasn't been yet
if e.is_set():
t1.start()
我是 运行 树莓派上的 python 脚本。
基本上,我希望相机每 5 秒拍一张照片,但前提是我将布尔值设置为 true,它会在物理按钮上切换。
最初我将它设置为 true,然后在我的 while(true) 循环中,我想检查变量是否设置为 true,如果是,则每 5 秒开始拍照。问题是如果我使用时间 time.sleep(5)
之类的东西,它基本上会冻结所有内容,包括支票。结合我正在为按钮使用去抖动的事实,我就不可能实际切换脚本,因为我必须在 5 秒等待时间后准确按下它,正确的值检查......我已经一直在四处寻找,我认为可能的解决方案必须包括线程,但我无法全神贯注。我想到的一种解决方法是查看系统时间,如果秒数是 5 的倍数,则拍照(全部在主循环内)。这似乎有点粗略。
脚本如下:
### Imports
from goprocam import GoProCamera, constants
import board
import digitalio
from adafruit_debouncer import Debouncer
import os
import shutil
import time
### GoPro settings
goproCamera = GoProCamera.GoPro()
### Button settings
pin = digitalio.DigitalInOut(board.D12)
pin.direction = digitalio.Direction.INPUT
pin.pull = digitalio.Pull.UP
switch = Debouncer(pin, interval=0.1)
save = False #this is the variable
while(True):
switch.update()
if switch.fell:
print("Pressed, toggling value")
save = not save
if save:
goproCamera.take_photo()
goproCamera.downloadLastMedia()
time.sleep(5)
这里有一些尝试:
while(True):
switch.update()
if switch.fell:
print("Pressed, toggling value")
save = not save
if save:
current_time = time.time()
if current_time - last_pic_time >= 5:
goproCamera.take_photo()
goproCamera.downloadLastMedia()
last_pic_time = current_time
具体取决于您想要的行为类型,您可能需要 fiddle 调用 time.time()
的时间和频率。
干杯! 也许是这样的?
import threading
def set_interval(func, sec):
def func_wrapper():
set_interval(func, sec)
func()
t = threading.Timer(sec, func_wrapper)
t.start()
return t
我们在主循环中调用上面的函数。
将您的 while 循环内容包装在一个函数上:
def take_photo:
goproCamera.take_photo()
goproCamera.downloadLastMedia()
现在我们创建一个最初设置为 False 的标志,以避免创建多个线程。 请注意,我在 while 循环之前执行了此操作。我们这里只需要一个起始值。
active = False
while(True):
switch.update()
if switch.fell:
print("Pressed, toggling value")
save = not save
if save: # we need to start taking photos.
if not active: # it is not active... so it is the first time it is being called or it has been toggled to save as True again.
photo_thread = set_interval(take_photo, 5) # grabbing a handle to the thread - photo_thread - so we can cancel it later when save is set to False.
active = True # marking as active to be skipped from the loop until save is False
else:
try: # photo_thread may not exist yet so I wrapped it inside a try statement here.
photo_thread.cancel() # if we have a thread we kill it
active = False #setting to False so the next time the button is pressed we can create a new one.
让我知道它是否有效。 =)
我最后做了什么:
### Imports
from goprocam import GoProCamera, constants
import board
import digitalio
from adafruit_debouncer import Debouncer
import os
import time
import threading
### GoPro settings
gopro = GoProCamera.GoPro()
### Button settings
pin = digitalio.DigitalInOut(board.D12)
pin.direction = digitalio.Direction.INPUT
pin.pull = digitalio.Pull.UP
switch = Debouncer(pin, interval=0.1)
### Picture save location
dir_path = os.path.dirname(os.path.realpath(__file__))
new_path = dir_path+"/pictures/"
save = False
### Functions
def takePhoto(e):
while e.isSet():
gopro.take_photo()
gopro.downloadLastMedia()
fname = '100GOPRO-' + gopro.getMedia().split("/")[-1]
current_file = dir_path+'/'+fname
if os.path.isfile(current_file):
os.replace(current_file, new_path+fname) #move file, would be cleaner to download the file directly to the right folder, but the API doesn't work the way I thought it did
e.wait(5)
### Initial settings
e = threading.Event()
t1 = threading.Thread(target=takePhoto, args=([e]))
print("Starting script")
while(True):
switch.update()
if switch.fell:
#toggle value
save = not save
if save:
e.set() #should be taking pictures
else:
e.clear() #not taking pictures
if not t1.is_alive(): #start the thread if it hasn't been yet
if e.is_set():
t1.start()