Can't send trigger during first 500ms of a 2750ms trial

I’m struggling with the parallel port component in the builder.

Within a single trial, I show four images. I sync a trigger with the occurrence of each of the image onsets. A single trial is 2.75s long. Blank screen for 250ms, 1st Image - 500ms, 2nd - 500ms, 3rd - 500ms, 4th - 1000ms.

The 2nd, 3rd, and 4th trigger are sent just fine. But, for some reason, I can’t send a trigger in the first 500ms of the trial, that is, I can’t sync a trigger with the onset of the first image.

When I move the parallel port component into anything after 500ms in a trial, the trigger sends just fine. But, if I move it back to the beginning of the trial, then my software doesn’t pick it up (ActiView - Biosemi).

Any pointers?

EDIT: I moved around the calls to p_port.setData(0) and added some sleeping into my script, and things work well now.

Have you got the Static Component in the Routine? That’s the pink box labelled ISI. That says to PsychoPy “This period has nothing happening in it so use it for other processing, like image loading” but it also means that PsychoPy isn’t doing other things during that period (because it things everything is static).

Try right-clicking the pink area and removing

EDIT: for telling what I’ve tried to solve the issue.

I have no static components in the experiment. As I said in my original post, changing the timing for the parallel port to 500ms after the onset of a new trial worked – at least, it did, for some blocks. Now, it is apparent that it works for some blocks, but not for other blocks. I have no clue what is going wrong.

I have also noticed that upon compiling the script, the address for one parallel port trigger was set to a unicode type, i.e. "address = u’0078’. I am not sure if that caused the following problem: in all of my blocks, I send a trigger to start saving my EEG data file. But, in on block, even though the exact components are duplicated, the save does not start. It’s as if my acquisition software is not playing nicely with psychopy.

What to do now? Write the entire script from scratch without the builder?

I’m afraid it’s impossible to know from this what the problem might be. It is certainly possible to send triggers in the first 500ms (within Builder) if you don’t have a static period running at that point. I suggest you strip your experiment down and get the timing/triggers working in something simple first. If you have a minimal version for us to see then we might be able to work out what’s wrong.

I’ve decided to take your advice and get out of the builder. I modified my EEG configuration file to accept different trigger values as my TURN-ON and TURN-OFF save function. This seems to work fine. However, my triggers during a trial are still very, very random. Sometimes, the first number doesn’t appear, and rarely I see the correct decimal showing on my EEG software. Here’s a simplified code I’m working with.

    from psychopy import visual, core, data, parallel
    import block2dict #house written module for trial randomization, and block balancing 

    mywin = visual.Window(size=(1280, 1024), fullscr=True, screen=1, allowGUI=False,               allowStencil=False,
    monitor=u'SyncMaster', color=[-1,-1,-1], colorSpace='rgb',
    blendMode='avg', useFBO=True,
    )

    block1 = block2dict.block2dict("block1.csv") 

    #Block One
    thisTrial=0 #index to stop the test blocks.
    mysize=1 #size of the stimulus 

    #p_port=parallel.PParallelInpOut32() #tried this with no effect
    p_port=parallel.ParallelPort() #set up a class
    p_port.setData(0) #clear out the pport

    framerate = 60 

    #main loop for testing the trigger and the synchronization
    for n in range(10):
    stimulus_1 = visual.ImageStim(win=mywin,image= block1['image_one'][n], pos=[0,0], size=[mysize ,mysize])
    stimulus_2 = visual.ImageStim(win=mywin,image = block1['image_two'][n], pos=[0,0],size=[mysize ,mysize])
    stimulus_3 = visual.ImageStim(win=mywin,image = block1['image_three'][n], pos=[0,0],size=[mysize ,mysize])
    stimulus_4 = visual.ImageStim(win=mywin,image = block1['image_four'][n], pos=[0,0],size=    [mysize ,mysize])
    trig1=block1['trig1'][n] #corresponds to a unique code for the stimulus 
    trig2=block1['trig2'][n]
    trig3=block1['trig3'][n]
    trig4=block1['trig4'][n]
    
    #first level
    stimulus_1.setAutoDraw(True)
    mywin.callOnFlip(p_port.setData, int(trig1)) #need to convert the string to an integer
    for frame in range(framerate*1):
        mywin.flip()
    mywin.callOnFlip(p_port.setData, 0)
    stimulus_1.setAutoDraw(False)
    
    #second level
    stimulus_2.setAutoDraw(True)
    mywin.callOnFlip(p_port.setData, int(trig2))
    for frame in range(framerate*1):
        mywin.flip()
    mywin.callOnFlip(p_port.setData, 0)
    stimulus_2.setAutoDraw(False)
    
    #third level 
    stimulus_3.setAutoDraw(True)
    mywin.callOnFlip(p_port.setData, int(trig3))
    for frame in range(framerate*1):
        mywin.flip()
    mywin.callOnFlip(p_port.setData, 0)
    stimulus_3.setAutoDraw(False)
    
    #fourth level
    stimulus_4.setAutoDraw(True)
    mywin.callOnFlip(p_port.setData, int(trig4))
    for frame in range(framerate*1):
        mywin.flip()
    mywin.callOnFlip(p_port.setData, 0)
    stimulus_4.setAutoDraw(False)
    
    thisTrial = thisTrial+1
	
    mywin.close() 

I will update with a link to a video of the trigger output on the acquisition software when I get to the lab later today. Best Wishes from Berlin everyone!

Dan

OK, so now it sounds like your triggers are being sent. From your script you’re doing things right for good timing of trigger with visual stimulus so that’s fine. One thing that’s a little odd is that you’ve got no interstimulus interval above, so no period where the parallel port is set to 0. Your code above will set to 0 and then almost instantly set it to the next trigger value. If everything works perfectly then the result might be a tiny pulse of zero for a microsecond or two, but conceivably that will cause a problem. I’d insert some inter-stimulus intervals or remove the setData(0) calls for now.

It sounds like your problem is now that the value being sent doesn’t match the value you requested. Are the numbers at least reliable? Can you tell us what values of trig1 correspond to what value on the recording? Also make sure:

  • that int(trig1) is exactly what you think with print(int(trig1)) as automatic type conversions occasionally do surprising things
  • that your parallel port is on the correct address
  • that the port/cable has not been reconfigured to do something else. e.g. my EEG lab uses one of the lines in the parallel port to control another device (it doesn’t connect to the EEG amps) so we can only send even-number integers to the amp. That’s fine if you know the rule! Do you have other software running on this that works?

Hi Again,

I took your advice, and I inserted a few calls to sleep function in the python time module. This seems to have cleared up all issues, and things are looking great! Below, I provide the code in case anyone needs snippets. Thanks so much for the help!

from psychopy import visual, core, data, parallel
import block2dict #in house module 
import block_generate #in house module 
import time

block_generate.block_generate()

mywin = visual.Window(size=(1280, 1024), fullscr=True, screen=1, allowGUI=False,     allowStencil=False,
monitor=u'SyncMaster', color=[-1,-1,-1], colorSpace='rgb',
blendMode='avg', useFBO=True,
)

block1 = block2dict.block2dict("block1.csv")

#Block One
thisTrial=0
mysize=1

p_port=parallel.ParallelPort()

p_port.setData(0)
p_port.setData(254)
time.sleep(1)
framerate = 60 
p_port.setData(0)

for n in range(10):
    stimulus_1 = visual.ImageStim(win=mywin,image= block1['image_one'][n], pos=[0,0], size=[mysize ,mysize])
    stimulus_2 = visual.ImageStim(win=mywin,image = block1['image_two'][n], pos=[0,0],size=[mysize ,mysize])
    stimulus_3 = visual.ImageStim(win=mywin,image = block1['image_three'][n], pos=[0,0],size=[mysize ,mysize])
    stimulus_4 = visual.ImageStim(win=mywin,image = block1['image_four'][n], pos=[0,0],size=[mysize ,mysize])
    trig1=block1['trig1'][n]
    trig2=block1['trig2'][n]
    trig3=block1['trig3'][n]
    trig4=block1['trig4'][n]
    time.sleep(0.5)

#first level
    stimulus_1.setAutoDraw(True)
    mywin.callOnFlip(p_port.setData, int(trig1))
    for frame in range(framerate):
        mywin.flip()
    stimulus_1.setAutoDraw(False)
    p_port.setData(0)

#second level
    stimulus_2.setAutoDraw(True)
    mywin.callOnFlip(p_port.setData, int(trig2))
    for frame in range(framerate*1):
        mywin.flip()
    stimulus_2.setAutoDraw(False)
    p_port.setData(0)

#third level 
    stimulus_3.setAutoDraw(True)
    mywin.callOnFlip(p_port.setData, int(trig3))
    for frame in range(framerate*1):
        mywin.flip()
    stimulus_3.setAutoDraw(False)
    p_port.setData(0)

#fourth level
    stimulus_4.setAutoDraw(True)
    mywin.callOnFlip(p_port.setData, int(trig4))
    for frame in range(framerate*1):
        mywin.flip()
    stimulus_4.setAutoDraw(False)
    p_port.setData(0)

    thisTrial = thisTrial+1

mywin.close()
p_port.setData(255)
time.sleep(1)
p_port.setData(0)