Hi guys, in my PsychoPy experiment, I’ve got a “trials” loop in which a new random stimulus from a csv file is showed each loop until every one of the file has been showed once.
When the stimulus file “red_cross_shock.png” is used, I would like to trigger a parallel port that is controlling an experimental shocking device (https://www.digitimer.com/pdf/digitimer/ds7a.pdf).
I have never used an exterior device on PsychoPy and do not know how the handling of a parallel port works. Here is my corresponding code, I added a condition testing if the used stimulus was “red_cross_shock.png” (from what I’ve understood, this information is stored in the ‘stimuli2’ variable) and triggered the port accordingly (see ‘p_port updates’ part of the 'Start Routine “trials” ’ part) :
set up handler to look after randomisation of conditions etc
trials_loop = data.TrialHandler(nReps=1, method='random',
extraInfo=expInfo, originPath=-1,
trialList=data.importConditions('conditions.csv'),
seed=None, name='trials_loop')
thisExp.addLoop(trials_loop) # add the loop to the experiment
thisTrials_loop = trials_loop.trialList[0] # so we can initialise stimuli with some values
# abbreviate parameter names if possible (e.g. rgb = thisTrials_loop.rgb)
if thisTrials_loop != None:
for paramName in thisTrials_loop:
exec('{} = thisTrials_loop[paramName]'.format(paramName))
for thisTrials_loop in trials_loop:
currentLoop = trials_loop
# abbreviate parameter names if possible (e.g. rgb = thisTrials_loop.rgb)
if thisTrials_loop != None:
for paramName in thisTrials_loop:
exec('{} = thisTrials_loop[paramName]'.format(paramName))
# ------Prepare to start Routine "trials"-------
t = 0
trialsClock.reset() # clock
frameN = -1
continueRoutine = True
routineTimer.add(2.000000)
p_port.setData(255)
# update component parameters for each repeat
stimuli2.setImage(Stimulus)
# keep track of which components have finished
trialsComponents = [stimuli2, p_port]
for thisComponent in trialsComponents:
thisComponent.tStart = None
thisComponent.tStop = None
thisComponent.tStartRefresh = None
thisComponent.tStopRefresh = None
if hasattr(thisComponent, 'status'):
thisComponent.status = NOT_STARTED
# -------Start Routine "trials"-------
while continueRoutine and routineTimer.getTime() > 0:
# get current time
t = trialsClock.getTime()
frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
# update/draw components on each frame
# *stimuli2* updates
if t >= 1 and stimuli2.status == NOT_STARTED:
# keep track of start time/frame for later
stimuli2.tStart = t # not accounting for scr refresh
stimuli2.frameNStart = frameN # exact frame index
win.timeOnFlip(stimuli2, 'tStartRefresh') # time at next scr refresh
stimuli2.setAutoDraw(True)
frameRemains = 1 + 1- win.monitorFramePeriod * 0.75 # most of one frame period left
if stimuli2.status == STARTED and t >= frameRemains:
# keep track of stop time/frame for later
stimuli2.tStop = t # not accounting for scr refresh
stimuli2.frameNStop = frameN # exact frame index
win.timeOnFlip(stimuli2, 'tStopRefresh') # time at next scr refresh
stimuli2.setAutoDraw(False)
# *p_port* updates
if t >= 1 and stimuli2 == "red_cross_shock.png" and p_port.status == NOT_STARTED:
# keep track of start time/frame for later
p_port.tStart = t # not accounting for scr refresh
p_port.frameNStart = frameN # exact frame index
win.timeOnFlip(p_port, 'tStartRefresh') # time at next scr refresh
p_port.status = STARTED
win.callOnFlip(p_port.setData, int(4))
frameRemains = 1 + 1- win.monitorFramePeriod * 0.75 # most of one frame period left
if p_port.status == STARTED and t >= frameRemains:
# keep track of stop time/frame for later
p_port.tStop = t # not accounting for scr refresh
p_port.frameNStop = frameN # exact frame index
win.timeOnFlip(p_port, 'tStopRefresh') # time at next scr refresh
p_port.status = FINISHED
win.callOnFlip(p_port.setData, int(255))
# check for quit (typically the Esc key)
if endExpNow or keyboard.Keyboard().getKeys(keyList=["escape"]):
core.quit()
# check if all components have finished
if not continueRoutine: # a component has requested a forced-end of Routine
break
continueRoutine = False # will revert to True if at least one component still running
for thisComponent in trialsComponents:
if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
continueRoutine = True
break # at least one component has not yet finished
# refresh the screen
if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
win.flip()
# -------Ending Routine "trials"-------
for thisComponent in trialsComponents:
if hasattr(thisComponent, "setAutoDraw"):
thisComponent.setAutoDraw(False)
trials_loop.addData('stimuli2.started', stimuli2.tStartRefresh)
trials_loop.addData('stimuli2.stopped', stimuli2.tStopRefresh)
if p_port.status == STARTED:
win.callOnFlip(p_port.setData, int(0))
trials_loop.addData('p_port.started', p_port.tStart)
trials_loop.addData('p_port.stopped', p_port.tStop)
thisExp.nextEntry()
# completed 1 repeats of 'trials_loop'
I this a way of doing it or am I not doing this right ?
Thank you for your asnwers.