Biosemi serial port triggering demo

All,
Looking back, some folks have had questions about how to get Psychopy to talk to the Biosemi-provided USB-to-parallel port cable. I’ve put together a small demo that shows how to make this work.

https://github.com/drmarcj/psychopy_biosemi_serial

-Marc-

3 Likes

Hi Marc,

Thanks a lot for this demo! Are the triggers in this demo sent at the start of each stimulus presentation (i.e. trigger sent once with each item)? I am just wondering why this is done within Each Frame tab…if it only needs to happen at the beginning of the trial, I would expect it within the Begin Routine tab (given that code_2 from the demo is added to the trial window). Why is this so?

Thanks!
Boba

You could have the trigger happen at the start of the routine. However in this case having it relative to the event is more flexible and does not assume the event happens right at the start of the trial. Consider a situation where you have three events per trial (audio stimulus, visual stimulus and keypress response). In that case you might want to send a trigger at the onset of each of these, so having a trigger just at the start of the routine will not work.

Thank you so much for sharing this Marc! This worked for sending triggers to my biosemi actiview2 via a Neurospec MBBT-S triggerbox! The only code change I made was commenting out the resetting of triggers to zero, as this is handled automatically by the triggerbox! Thank you!

I previously tried str.encode(‘1’) and bytes(chr(1), ‘utf-8’), however these were sending incoherent
and random trigger values to the biosemi actiview.

1 Like

Thanks for that reply!

Also, any idea why PsychoPy is giving me a syntax error for:

win.callOnFlip(port.write, b’\x00’) ??

Thanks!

Commenting out the resetting of triggers to zero part works with the USB trigger interface too! This is what they say about it on the biosemi webpage:
‘Because all pins of the USB Trigger Interface are reset after 8mSec, you do not need to clear the port before sending a new trigger.’

Just a question: you wrote in the documentation that the pins 1-8 are simulated. Is the same trigger always simulating the same pin? I am asking because I did the output of the events through EDFbrowser (Tools/Export annotations/events) and got the list of triggers that I assume correspond to pins, but I can’t see the mapping between a trigger and a pin…also the number of events is much bigger than my number of trials.
However mne.find_events is giving the correct number of events and trigger labels.

Thanks for the clarification on clearing codes. On at least one system I’ve used in the past this was not the case hence my abundance of caution in always clearing codes at the start, end, and between trials.

The way that the serial pins work is that each pin codes a binary digit, and so you combine pins to generate 2^8 different codes. In practice you have 255 different possible codes (2^8, minus one case where all pins are set to zero). There is some possibility for confusion here since you can specify a trigger code in binary, hexadecimal, or decimal (normal human readable i.e., base-10). I suggest just coding it in decimal as I’ve done in the sample Excel sheet. Be aware if you specify a number > 255, or a string/character code, this may lead to confusion and unexpected behaviour.

Yes, I can see across the forums and discussions that people have problems with this, so I think clearing codes should definitely be the default.

Thanks for the explanation on the serial pins. Yeah, I am using trigger codes such as 10, 20, 30 etc. (up to 100). I was just wondering, as a complete newbie, whether it matters which pins are being used and whether consequently we want to be careful about the codes (other than the restrictions that you mentioned). But it looks like it doesn’t. I ran your demo and these are the events extracted with BDFbrowser (which I assume are the pins):

Onset,Duration,Annotation
+6.7519531,,Trigger Input 1
+7.7514648,,Trigger Input 2
+7.7514648,,Trigger Input 4
+8.7519531,,Trigger Input 4
+8.7519531,,Trigger Input 5
+9.7519531,,Trigger Input 6
+10.7514648,,Trigger Input 7
+11.7514648,,Trigger Input 2
+11.7514648,,Trigger Input 4
+11.7514648,,Trigger Input 5
+11.7514648,,Trigger Input 6
+11.7514648,,Trigger Input 7
+12.7514648,,Trigger Input 1
+12.7514648,,Trigger Input 2
+12.7514648,,Trigger Input 3
+12.7514648,,Trigger Input 4
+12.7514648,,Trigger Input 5
+12.7514648,,Trigger Input 6
+12.7514648,,Trigger Input 7
+12.7514648,,Trigger Input 8

And the number of events and trigger codes recognized by the mne.find_events seem fine:

events = mne.find_events(raw)
Trigger channel has a non-zero initial value of 65536 (consider using initial_event=True to detect this event)
Removing orphaned offset at the beginning of the file.
7 events found
Event IDs: [  1  10  24  32  64 122 255]

Is the non-zero initial value expected?

Thanks!

Hi, I have another issue with triggers.
I added another block to my experiment, as a separate loop, and the triggers are not being sent after the first block/loop. Simply, the first loop goes fine, there is a break screen in between, then the second block/loop starts, the stimuli are being presented correctly but no triggers are being sent. I tried playing with opening and closing the port after every block, but it didn’t work.
I also tried to add another loop in your demo - same problem.
Any ideas?

Thanks!

Hi
Don’t even think about the pins, in my opinion. Just come up with integer numbers between 1-255 for each one of your stimulus categories. This does make per-item coding difficult.

I worry about this:

Trigger channel has a non-zero initial value of 65536

Items outside the 1-255 range are not going to work exactly because there are only 8 pins (thus 2^8 possible trigger values).

We’ve run into similar issues. If you are running two routines, one for each loop, be sure you use different control variables in the “Each Frame” portion that runs in the two routines. Specifically “stimulus_pulse_started” and “stimulus_pulse_ended” control variables should be renamed and make sure the corresponding code in the second loop is changed accordingly.

Hi, thanks for the answer. It seems to me that this trigger with value of 65536 is somehow added to the beginning of each psychopy code. Because the trigger values I am using are 10, 20 etc., I have not used that value. Also, if I run 2 experiments within the same eeg recording (i.e. run 2 codes one after another without stopping the recording), then I get 2 values of 65536, which gives me the idea these are related to the beginning of the code or something. I assume I can just ignore them in the analysis later?