psychopy.org | Reference | Downloads | Github

Send paralell port-signal at specific words during word-by-word sentence presentation

OS (e.g. Win10): Windows 7
PsychoPy version (e.g. 1.84.x): 1.83.04
Standard Standalone? (y/n) If not then what?: y
What are you trying to achieve?: Parallel-port signals should be sent at specific words during word-by-word sentence presentation.

I want to present the words of a sentence for 300 ms with a blank screen for 200 ms between each word. The sentences, which vary in length, are read from an external excel-file.

In a Code-component in my Trial I use this code in the Begin Routine-tab. Note that I used number of frames instead of time to display the word (18 frames) and the blank inter-stimulus-interval (12 frames).

# get the sentence for this trial and split it into a list of words:
words = sentence.split()

# count them (the length of the list):
numWords = len(words)

# how long the text component should display for:
totalDuration = 0.001 + (numWords * 0.5) # time in seconds

# loop to display the word followed by a blank:
for word in words:

    text_15.setText(word) #set current word in Builder placeholder text variable
    for frameN in range (18):
        text_15.draw() #present current word for 18 frames (at 60Hz!)
        win.flip()

    for frameN in range(12): #present blank screen for 12 frames (at 60Hz!)
        win.flip()

The presentation as such seems to work just fine.

However, I want to send a parallel port-signal that is different for every sentence at the onset of certain words. Therefore, the position of the words (trig_w1, trig_w2) and the respective signal-to-be-sent (trig_1, trig_2) are also in the excel-file.

What did you try to make it work?:

My idea was to create a frame counter in the Begin routine-tab (note that the examples below serve only to illustrate my idea, they never worked as desired), such as

# frame counter:
frame_counter = 0

and update it in the Each frame-tab

# update the frame counter with each frame:
frame_counter = frame_counter + 1

To keep track of the word that is being displayed, I thought of something like this in the Each frame-tab

# which word is displayed
current_word = frame_counter / 30 # because each word+ISI is displayed for 30 frames

If the current word is one that I want to send a trigger at, the respective code is sent through something like this:

if current_word == trig_w1:
      p_port.setData(trig_1)

What specifically went wrong when you tried that?:

Since the loop to present the sentence word by word is in the Begin routine-tab, the frame counter in the Each frame-tab doesn’t work. It seems that the code in the Each frame-tab is executed only after the loop in the Begin routine-tab is finished.

I am aware that there is some other flaws in the examples above. However, I wonder if this approach does work at all. I am completely new to python-programming, so I don’t dare to make a judgment of this and I am pretty lost with going on from here.

Thank you for your help!

test4.psyexp (163.1 KB)
expe_test.xlsx (9.4 KB)

The attached solution works, though I did not yet check if the signal is sent at the correct window flip.
Instead of counting the frames, the iterations of the loop are counted to track the number of presented words (since each word requires one iteration of the loop).

This goes into the Begin routine-tab:

# get the sentence for this trial and split it into a list of words:
words = sentence.split()

# count the words:
numWords = len(words)

# duration to display the text component:
totalDuration = 0.001 + (numWords * 0.5) # time in seconds

# loop to display words and send triggers:
for idx, word in enumerate(words):
    currentWord = idx+1 # track the current word
    text_15.setText(word) #set current word in Builder placeholder text variable
    if currentWord == trig_w1: # trigger word 1
        p_port.setData(trig_1) # send trigger 1
    if currentWord == trig_w2: # trigger word 2
        p_port.setData(trig_2) # send trigger 2
    if currentWord == trig_w3: # trigger word 3
        p_port.setData(trig_3) # send trigger 3
    for frameN in range (18):
        text_15.draw() #present current word for 18 frames (at 60Hz!)
        win.flip()
    for frameN in range(12): #present blank screen for 12 frames (at 60Hz!)
        win.flip()
        p_port.setData(0) # reset the port

test5.psyexp (161.8 KB) expe_test.xlsx (5.6 KB)