psychopy.org | Reference | Downloads | Github

Issue sending triggers using Neurospec USB-parallel port adapter

Hi everyone

To preface, OS is windows 8.1, running psychopy 1.83.04 and have built my study using coder.

I’m having trouble getting my experiment to send triggers, and I’m thinking it may be to do with using a usb to parallel port converter (Neurospec MMB trigger box).

I’m thinking this because triggers are being sent to the EEG software (ActiView) when checked via Matlab, and I’ve followed all the advice that I’ve found online for running EEG parallel port on psychopy, including having all the appropriate drivers installed, plus inpout32 and it is placed in the same folder of my script.

The script I am using within my study is below. It could be a simple address issue (this is the address when checking device managers via control panel). However no error message is displayed, so I gather it is correct.

from psychopy import parallel
from ctypes import windll

portaddress = 0x00000008

def sendTrigger(triggerCode):
    try:
        windll.inpout32.Out32(portaddress, triggerCode)
        #core.wait(0.05)
        windll.inpout32.Out32(portaddress, 0)
    except RuntimeError: print "Trigger \ ''' + str(triggerCode) + ''\'' could not be sent"
    except WindowsError: print "inpout32.dll couldn't be found"

sendTrigger(1)

To simplify it down I’ve also tried testing via the script below, which again shows no errors but simply doesn’t send the trigger when checking via ActiView.

#!/usr/bin/env python2
from psychopy import visual, core, logging
from psychopy import parallel
from ctypes import windll

nFramesOn = 5
nFramesOff = 30
nCycles = 2
parallel.setPortAddress(0x00000008) #address for parallel port on many machines
pinNumber = 2#choose a pin to write to (2-9). 

#setup the stimuli and other objects we need
myWin = visual.Window([1280, 1024],allowGUI=False)#make a window
myWin.flip()#present it
myStim = visual.PatchStim(myWin, tex=None, mask=None, color='white', size=2)   
myClock = core.Clock() #just to keep track of time

#present a stimulus for EXACTLY 20 frames and exactly 5 cycles
for cycleN in range(nCycles):
    for frameN in range(nFramesOff):
        #don't draw, just refresh the window
        myWin.flip()
        parallel.setData(0)#sets all pins low
        
    for frameN in range(nFramesOn):
        myStim.draw()
        myWin.flip()
        #immediately *after* screen refresh set pins as desired
        parallel.setPin(2,1)#sets just this pin to be high        
        
#report the mean time afterwards
print 'total time=', myClock.getTime()
print 'avg frame rate=', myWin.fps()
#set pins back to low
myWin.flip()
parallel.setData(0)#sets all pins low again

I may be going down the wrong rabbit hole here, but Matlab runs the Neurospec usb-parallel adapter as a serial port - could this be the issue? (see URL)

Quoted from the URL below (under subheading Neurospec MMB trigger box) - “The box appears as serial port and trigger codes are sent to this serial port using PTB’s IOPort function”

https://github.com/Psychtoolbox-3/Psychtoolbox-3/wiki/FAQ:-TTL-Triggers-via-USB

Any help is massively appreciated!

Brendan

Hey Brendan,

If it’s the case that you need to interact with the serial port rather than the parallel port, then I’m afraid i’m unable to help. If it’s an issue with the parallel port, then here’s some code that I’ve used successfully, although it’s with a 64 bit windows (but i think it’s comparable in principle…)

this snippet I had at the start of my experiment to initialise the parallel port

sendtriggers = False
#set parallel port params
if sendtriggers == True:
    IOport = parallel.setPortAddress(address = '0xD010') #change the address to whatever it is for the port on the comp in use
    holdvalue = 0 #reset the port to this after every trigger to avoid repeats, and reset all pins
    #IOport.setData(triggercode) # this is the code to send a trigger to the parallel port (i.e. to amplifier)
    #IOport.setData(holdvalue)   # always send a zero value to reset all pins after a trigger to prevent repeated sending

whenever I’ve then needed to send a trigger, i simply do this:

IOport.setData(trigger_value) #whatever trigger value I have
IOport.setData(holdvalue) #this is zero

Your problem could be arising because you aren’t setting a handler for your parallel port:
if the address of the port is right, maybe consider changing

parallel.setPortAddress(0x00000008)
to
your_port_name = parallel.setPortAddress(0x00000008)

then where you have parallel.setPin(2,1) change it to your_port_name.setPin(2,1)

Hopefully that may help - if not, then hopefully somebody else can step in with some 32bit specific advice!

Hey srchekroud,

first, thanks for the response and appreciate your input. I should have clarified that I had tried using a handler, which unfortunately did not do the job.

However I seem to have got it working - turns out it will require interacting with the serial port as I’ve managed to be able to send triggers with the following:

import serial
port = serial.Serial("COM4", 9600)
port.write()
port.flush()
port.close()

Unfortunately I’m not familiar with interacting with pyserial so it’s a pretty rough job (lacking precision) until I have a better understanding of how to implement it, still it’s better than nothing!

cool, so it was an issue with you interacting with the wrong port type. Glad it’s working now, hope it goes smoothly!

Hi bmau,

I also use PsychoPy to ActiView. I’m not sure if it will be of any help but here is an example of the code that I use:

from psychopy import parallel

#parallel port handler
parallelPortID = 0xD050
portP = parallel.ParallelPort(address = parallelPortID)
portP.setData(0) # resets the port

Then I call it within my experiment with:

portP.setData(1) # for example

Originally I had a similar problem and it was an issue with the driver. I also do not use the Neurospec.

Hope this is of some help to you or any future reader.