psychopy.org | Reference | Downloads | Github

Sending markers to EEG through serial port


#1

Hi

I am stuck with a problem related with sending triggers through serial port and I would be truly grateful if anyone could give any help / advice:

OS : Win 10

PsychoPy version : 1.90.1

What are you trying to achieve?:
I want to send triggers from a testing laptop to an EEG laptop.
The aim is to mark on the EEG trace the moment when a sound is presented, in order to subsequently analyse event-related potentials.

I am using Biosemi EEG system for EEG data collection.
I am using Biosemi USB trigger interface cable - which is recognized as a serial port https://www.biosemi.com/faq/USB%20Trigger%20interface%20cable.htm) for sending triggers from testing “Psychopy” laptop to EEG laptop.

Please find below an overview of the experiment / flow (simplified version for the purposes of solving the trigger issue):

I want to send a marker whenever sound_1 is presented.
Because I am not using a parallel port nor LabJack, I cannot use Builder’s I/O.

Therefore I introduced a code component as follows:

I want to present 3 different types of sounds, one sound per trial, in n trials.
I have 4 different conditions, which differ basically in the proportion of sound types.
I am presenting visual info at the same time.
I have defined the conditions/trials in an excel file (looptrials file) and the order of the conditions in another excel file (loopblocks file).

In the looptrials file I have 1 column identifying the type of sound as 0, 1 or 2. This column is named typesoundfile1.

With ‘‘port.write(b’$typesoundfile1’)’’ I mean that I want to send the number from column “typesoundfile1” corresponding to the trial row.

The good thing is that:

  1. There are triggers being sent every 5 seconds to the EEG trace.

The problems are:

  • The EEG laptop is receiving multiple types of triggers, but without any type of relationship with the numbers 0,1 and 2 present on column “typesoundfile1”: i.e. the numbers are different from 0,1 and 2 and vary independently from sound type.

While debugging this I have noticed that ‘‘port.write(b’1’)’’ sends the number 49 to the EEG. I have played around a bit to try finding a way to send 0, 1 and 2 but so far I have been unsuccessful…
I am also not sure about the most appropriate way to send trial-specific triggers based on info from an excel file…

Can anyone give some advice? Many thanks!!

Tiago


Does anyone have used Psycho Py and any device from Neulog Sensors?
#2

What you are currently doing is sending the bytes corresponding to the literal set of characters '$typesoundfile1'. By putting the variable name inside quotes, it is no longer a variable name pointing to a numerical value. It is just a sequence of characters.

Assuming that typesoundfile1 represents an integer variable, you could just try this directly:

port.write(typesoundfile1)

i.e. if this is an integer variable, then it is already effectively a number, not a character string that needs to be translated. But if it does need to be expressly converted to a particular byte representation, then try something like this:

port.write(typesoundfile1.to_bytes(length = 1, byteorder = 'little')) 

Note that the dollar sign has no particular meaning in the Python language: it is just a marker used in PsychoPy’s Builder interface to indicate to Builder itself that a value should not be taken literally but should be regarded as a Python expression.

NB just noticed that you use time.sleep() in your code component. You must remove that. Builder operates on a drawing cycle which requires it to actively do things on every screen refresh. By using this statement, you will be mucking up Builder’s timing control seriously and unpredictably. If you have a need for such a pause, it must be implemented differently.


#3

Hi Michael

Thank you for your advice.

Indeed ‘‘typesoundfile1’’ represents an integer variable. Please see excel spreadsheet below:

At the moment this is basically a Stroop task combined with a Odd-ball task (sounds).

In the same routine/loop, $colour or $word in the builder can correctly access the date from this spreedsheet.

I have tried:

port.write(typesoundfile1)

in the code component: it does not produce any error but unfortunately there are no triggers going through… I suspect that it is not retrieving data from the column in the excel spreedsheet.

Your other suggestion:

port.write(typesoundfile1.to_bytes(length = 1, byteorder = 'little')) 

Generated an error:

Can I ask if anyone can recommend a way to send the integers from this excel spreedsheet column as triggers?

Also thank you for your comment about time.sleep(). To be honest I was suspicious about this and was going to double check… The trigger needs to be sent 1 second after routine onset, so I will look for an alternative!

Tiago


#4

What about just port.write(bytes(typesoundfile1)) ?

To control timing, put this in the “begin routine” tab:

trigger_sent = False

and this in the “each frame” tab:

if t >= 1.0 and not trigger_sent:
    port.write(bytes(typesoundfile1)) # or whatever works
    trigger_sent = True

#5

Hi Michael

It worked quite well, very grateful for your help! And now I understand better how to code this type of tasks.

Best

Tiago