Open Aplefen1 opened 1 month ago
import time import datetime import RPi.GPIO as GPIO from configurable import Configurable import multiprocessing
class Trigger(Configurable):
def init(self,message_queue,cam_trigger,t=2.0):
super().init(message_queue)
print("Initialising Trigger Control")
self.cam_trigger = cam_trigger
self.debug = False
self.manager = multiprocessing.Manager()
self.flashselection = self.manager.list()
self.flash_power_sel = self.manager.list()
self.index = multiprocessing.Value('i',0)
self.record = self.manager.list()
self.direction = 0
self.flash_select_pins = [14,15,18,23,5,22] #[8,10,12,16] #Board->BCM pins
self.power_to_flash_pins = [27,17] #[top,bottom] only 2 available
self.trigger_pin = 24 #18 #Board->BCM pins
times_fired = []
for i in range(len(self.flash_select_pins)):
self.flashselection.append(i)
times_fired.append(0)
self.times_fired = self.manager.Array('i',times_fired)
self.flash_power_sel.append(0) # top
self.flash_power_sel.append(1) # bottom
self.t = multiprocessing.Value('d',t)
self.ds = multiprocessing.Value('d',0)
self.flashseq = multiprocessing.Value('i',0) #0 = flash all, 1 = flash 2 at a time, 1 = flash in sequence,
self.skipnoflashes = multiprocessing.Value('i',0) #how many to skip
self.max_flashes = multiprocessing.Value('i',40)
self.total_flashes = multiprocessing.Value('i',0)
self.preptime = 0.02
self.triggertime = 0.03 #this will end up at least 200us
self.seqn = 0
GPIO.setmode(GPIO.BCM) #GPIO.BOARD) #Board->BCM
GPIO.setup(self.trigger_pin, GPIO.OUT)
for pin in self.flash_select_pins:
GPIO.setup(pin, GPIO.OUT)
for pin in self.power_to_flash_pins:
GPIO.setup(pin, GPIO.OUT)
time.sleep(0.5)
for pin in self.flash_select_pins:
GPIO.output(pin, False)
for pin in self.power_to_flash_pins:
GPIO.output(pin, True)
GPIO.output(self.trigger_pin, False)
print("Running")
self.run = multiprocessing.Event()
def trigger_camera(self,fireflash,endofset):
"""
Send trigger to camera (and flash)
fireflash = boolean: true=fire flash
endofset = boolean: whether this is the last photo of a set (this will then tell the tracking system to look for the bee).
"""
self.power_control()
if self.debug:
print("Photo: Flash" if fireflash else "Photo: No Flash")
if fireflash:
if self.flashseq.value==0:
for flash in self.flashselection:
GPIO.output(self.flash_select_pins[flash],True)
self.times_fired[flash] += 1
self.total_flashes.value += 1
if self.flashseq.value==1:
GPIO.output(self.flash_select_pins[self.flashselection[self.seqn]],True)
GPIO.output(self.flash_select_pins[self.flashselection[self.seqn+1]],True)
self.times_fired[self.seqn] += 1
self.times_fired[self.seqn+1] += 1
self.total_flashes.value += 1
self.seqn+=2
if self.seqn>=len(self.flashselection):
self.seqn = 0
if self.flashseq.value==2:
GPIO.output(self.flash_select_pins[self.flashselection[self.seqn]],True)
self.times_fired[self.seqn] += 1
self.total_flashes.value += 1
self.seqn+=1
if self.seqn>=len(self.flashselection):
self.seqn = 0
if self.flashseq.value==9:
for pin in self.flash_select_pins:
GPIO.output(pin, False)
else:
for pin in self.flash_select_pins:
GPIO.output(pin, False)
time.sleep(self.preptime)
triggertime = time.time() #TODO Why are these two different?
triggertimestring = datetime.datetime.now() #need to convert to string later
triggertimestring = triggertimestring.strftime("%Y%m%d_%H:%M:%S.%f")
self.record.append({'index':self.index.value,'endofset':endofset,'direction':self.direction,'flash':fireflash,
'flashselection':list(self.flashselection),'triggertime':triggertime,'triggertimestring':triggertimestring})
print("Incrementing trigger index from %d" % self.index.value)
self.index.value = self.index.value + 1
#Software trigger...
#self.cam_trigger.set()
#Trigger via pin...
GPIO.output(self.trigger_pin,True)
time.sleep(self.triggertime)
for pin in self.flash_select_pins:
GPIO.output(pin, False)
#(trigger via pin)...
GPIO.output(self.trigger_pin,False)
def power_control(self):
#Top 2 are controlled together, bottom 4 are controlled together
#After flash 2 has fired 65 times, turn off top 2 for 2 flashes
#After flast 6 has fired 70 times, turn off top 2 for 2 flashes
if self.times_fired[1] == 25:
self.total_flashes.value = 0
GPIO.output(self.power_to_flash_pins[0], False)
print("TURNED OFF TOP")
elif self.times_fired[1] >= 25 and self.total_flashes.value >= 3:
GPIO.output(self.power_to_flash_pins[0], True)
print("TURNED ON TOP")
if self.times_fired[5] == 30:
self.total_flashes.value = 0
GPIO.output(self.power_to_flash_pins[1], False)
print("TURNED OFF BOTTOM")
elif self.times_fired[5] >= 30 and self.total_flashes.value >= 3:
GPIO.output(self.power_to_flash_pins[1], True)
print("TURNED ON BOTTOM")
print(self.times_fired)
for count in range(len(self.times_fired)):
if self.times_fired[count] > self.max_flashes.value:
self.times_fired[count] = 0
def worker(self):
skipcount = 0
while (True):
self.run.wait()
delaystart = self.ds.value*self.t.value
time.sleep(delaystart);
skipcount+=1
skipnoflashphoto = (skipcount<=self.skipnoflashes.value)
self.trigger_camera(True,skipnoflashphoto)
if not skipnoflashphoto:
self.trigger_camera(False,True)
skipcount = 0
time.sleep(self.t.value-self.triggertime*2-self.preptime*2-delaystart)
else:
time.sleep(self.t.value-self.triggertime-self.preptime-delaystart)
import time
import datetime
import RPi.GPIO as GPIO
from configurable import Configurable
import multiprocessing
class Trigger(Configurable):
def __init__(self,message_queue,cam_trigger,t=2.0):
super().__init__(message_queue)
print("Initialising Trigger Control")
self.cam_trigger = cam_trigger
self.debug = False
self.manager = multiprocessing.Manager()
self.flashselection = self.manager.list()
self.flash_power_sel = self.manager.list()
self.index = multiprocessing.Value('i',0)
self.record = self.manager.list()
self.direction = 0
self.flash_select_pins = [14,15,18,23,5,22] #[8,10,12,16] #Board->BCM pins
self.power_to_flash_pins = [27,17] #[top,bottom] only 2 available
self.trigger_pin = 24 #18 #Board->BCM pins
times_fired = []
for i in range(len(self.flash_select_pins)):
self.flashselection.append(i)
times_fired.append(0)
self.times_fired = self.manager.Array('i',times_fired)
self.flash_power_sel.append(0) # top
self.flash_power_sel.append(1) # bottom
self.t = multiprocessing.Value('d',t)
self.ds = multiprocessing.Value('d',0)
self.flashseq = multiprocessing.Value('i',0) #0 = flash all, 1 = flash 2 at a time, 1 = flash in sequence,
self.skipnoflashes = multiprocessing.Value('i',0) #how many to skip
self.max_flashes = multiprocessing.Value('i',40)
self.total_flashes = multiprocessing.Value('i',0)
self.preptime = 0.02
self.triggertime = 0.03 #this will end up at least 200us
self.seqn = 0
GPIO.setmode(GPIO.BCM) #GPIO.BOARD) #Board->BCM
GPIO.setup(self.trigger_pin, GPIO.OUT)
for pin in self.flash_select_pins:
GPIO.setup(pin, GPIO.OUT)
for pin in self.power_to_flash_pins:
GPIO.setup(pin, GPIO.OUT)
time.sleep(0.5)
for pin in self.flash_select_pins:
GPIO.output(pin, False)
for pin in self.power_to_flash_pins:
GPIO.output(pin, True)
GPIO.output(self.trigger_pin, False)
print("Running")
self.run = multiprocessing.Event()
def trigger_camera(self,fireflash,endofset):
"""
Send trigger to camera (and flash)
fireflash = boolean: true=fire flash
endofset = boolean: whether this is the last photo of a set (this will then tell the tracking system to look for the bee).
"""
self.power_control()
if self.debug:
print("Photo: Flash" if fireflash else "Photo: No Flash")
if fireflash:
if self.flashseq.value==0:
for flash in self.flashselection:
GPIO.output(self.flash_select_pins[flash],True)
self.times_fired[flash] += 1
self.total_flashes.value += 1
if self.flashseq.value==1:
GPIO.output(self.flash_select_pins[self.flashselection[self.seqn]],True)
GPIO.output(self.flash_select_pins[self.flashselection[self.seqn+1]],True)
self.times_fired[self.seqn] += 1
self.times_fired[self.seqn+1] += 1
self.total_flashes.value += 1
self.seqn+=2
if self.seqn>=len(self.flashselection):
self.seqn = 0
if self.flashseq.value==2:
GPIO.output(self.flash_select_pins[self.flashselection[self.seqn]],True)
self.times_fired[self.seqn] += 1
self.total_flashes.value += 1
self.seqn+=1
if self.seqn>=len(self.flashselection):
self.seqn = 0
if self.flashseq.value==9:
for pin in self.flash_select_pins:
GPIO.output(pin, False)
else:
for pin in self.flash_select_pins:
GPIO.output(pin, False)
time.sleep(self.preptime)
triggertime = time.time() #TODO Why are these two different?
triggertimestring = datetime.datetime.now() #need to convert to string later
triggertimestring = triggertimestring.strftime("%Y%m%d_%H:%M:%S.%f")
self.record.append({'index':self.index.value,'endofset':endofset,'direction':self.direction,'flash':fireflash,
'flashselection':list(self.flashselection),'triggertime':triggertime,'triggertimestring':triggertimestring})
print("Incrementing trigger index from %d" % self.index.value)
self.index.value = self.index.value + 1
#Software trigger...
#self.cam_trigger.set()
#Trigger via pin...
GPIO.output(self.trigger_pin,True)
time.sleep(self.triggertime)
for pin in self.flash_select_pins:
GPIO.output(pin, False)
#(trigger via pin)...
GPIO.output(self.trigger_pin,False)
def power_control(self):
#Top 2 are controlled together, bottom 4 are controlled together
#After flash 2 has fired 65 times, turn off top 2 for 2 flashes
#After flast 6 has fired 70 times, turn off top 2 for 2 flashes
if self.times_fired[1] == 25:
self.total_flashes.value = 0
GPIO.output(self.power_to_flash_pins[0], False)
print("TURNED OFF TOP")
elif self.times_fired[1] >= 25 and self.total_flashes.value >= 3:
GPIO.output(self.power_to_flash_pins[0], True)
print("TURNED ON TOP")
if self.times_fired[5] == 30:
self.total_flashes.value = 0
GPIO.output(self.power_to_flash_pins[1], False)
print("TURNED OFF BOTTOM")
elif self.times_fired[5] >= 30 and self.total_flashes.value >= 3:
GPIO.output(self.power_to_flash_pins[1], True)
print("TURNED ON BOTTOM")
print(self.times_fired)
for count in range(len(self.times_fired)):
if self.times_fired[count] > self.max_flashes.value:
self.times_fired[count] = 0
def worker(self):
skipcount = 0
while (True):
self.run.wait()
delaystart = self.ds.value*self.t.value
time.sleep(delaystart);
skipcount+=1
skipnoflashphoto = (skipcount<=self.skipnoflashes.value)
self.trigger_camera(True,skipnoflashphoto)
if not skipnoflashphoto:
self.trigger_camera(False,True)
skipcount = 0
time.sleep(self.t.value-self.triggertime*2-self.preptime*2-delaystart)
else:
time.sleep(self.t.value-self.triggertime-self.preptime-delaystart)
Current problems we have found (don't worry Mike, relax on holiday, just assigning this so you see it when you come back)
Flashes have an internal limit of 80 flashes at the power we are using a. After that they have to be physically turned off b. Current workaround is using physical switch and running around turning them off c. Ordered MOSFAT switches which can be controlled by Pi pins, 3.3v output? d. Change Trigger.py to turn off and on flashes after 60/70 flashes e. Flashes also have internal temperature limit...
Can't seem to pulse flashes under 0.5 seconds?
Flashing all 6 at the same time seems like a lot, change buck transformer, but doesn't seem like we will be getting too much more juice?
Found that increasing output voltage on BT from 12.6v to around 13.5v seems to give a bit more leeway, especially with charging batteries (limit is 14.4v)
Worringly on some of the pi hat boards, there seems to be a short on Flash 5/6, doesn't seem consistent? 2 boards with the potential problem