基于值停止函数

2024-10-03 23:19:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在raspberry pi上运行python脚本

基本上,我希望相机每5秒拍一张照片,但前提是我将布尔值设置为true,并在物理按钮上切换

最初我将其设置为true,然后在while(true)循环中,我想检查变量是否设置为true,如果设置为true,则每5秒开始拍照。问题是,如果我使用类似time 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)

Tags: fromimportboard脚本truetimesavepin
3条回答

干杯! 也许是这样的

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.

让我知道它是否有效。=)

这里有一些东西可以尝试:

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

根据您想要的具体行为类型,您可能需要调整调用time.time()的时间和频率

我最终做了什么:

### 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()

相关问题 更多 >