Event markers to BIOPAC via serial port

Hi there,
I am trying to setup a task in Builder (using code snippets) to send event markers in a BIOPAC physiology recording. I am sending bytes via serial port from PsychoPy using pyserial and I’m not quite sure what I’m doing. I attached an image at the bottom that contains the digital acquisition channels that can be recorded in AcqKnowledge/BIOPAC. (here is a similar thread)

I have successfully opened the serial port, which sets one digital acquisition channel (upper pink, D9/D29) from 5 to 0 volts (and that channel remains at 0 until the port is closed)

import serial
ser = serial.Serial('COM4', baudrate = 115200, timeout=1)

Then the following code can set one or two different digital acquisition channels from 5 to 0 volts one time (green, D33/D13; lower pink, D34/D14). (I’m not entirely sure what this line directly below does - it seems to change based on what else is happening. I can provide more detail but I feel like I’m just missing something.)

ser.write("RR".encode())

Then, when the port is closed, the upper pink channel is set back to 5, as described in parentheses above. Also, if the ser.write(“RR”.encode()) was used, the blue channel (D32/D12) is sometimes set to 0 one time upon close.

ser.close()

So, I think I’m starting to understand some of what is happening above but if anyone could provide a better explanation I would be very appreciative. However, the biggest question that I’m having trouble with is how to trigger specific channels. It seems as if whenever I send a byte when the port is open, it only ever triggers the green channel (D33/D13). For example,

ser.write(b'36')
ser.flush()

seems to be the same channel and information as

ser.write(b'10')
ser.flush()

I know that one way to code events in AcqKnowledge would be to send triggers to specific BIOPAC channels, and then those channels could represent unique codes or they could be combined into a calculated channel. Would anyone be able to point me in the direction of how to accomplish that? Or, if there are any other ways that we could use to mark events in an AcqKnowledge recording via serial port, that would also be helpful. Thanks!

1 Like

Hi There!

I’m afraid I wouldn’t consider myself an expert in biopac or the python serial library enough to answer this question thoroughly - and we might need some more info on the type of BIOPAC system you are using - but I will try to be as helpful as possible!

My first guidance would always be towards to serial documentation, which I think you have probably already explored. For the command ser.write("RR".encode) which you ask about, the encode() part of this is encoding a string to bytes. the write part is to write those bytes to the serial port. I think without this some serial users had issues writing a string to the port without it first being converted to a byte array.

In terms of guidance how to move forward, I notice that there are some related posts on the forum. I also wonder if this blog might be helpful - you could try adding the repository folder to your experiment .psyexp file location and importing it using a code component. The code used in the blog should in theory also work from PsychoPy I believe (though it might depend on what BIOPAC system you are using). You wouldn’t need to do any of this bits relating to creating a window though, as PsychoPy will do that for you. I would be interested to hear if this works so if you do give that approach a try, it would be great if you could report back!)

Sorry I can’t be of more specific help!
Becca

Hi Becca,

Thanks for following up! You are 100% correct about the first part - and I have experienced the error when the string is not converted to a byte array first so that all makes sense.

We use a MP150, but what I’ve learned would also apply to the MP160, as far as I can tell. The other systems might be different but likely not very different.

For the record (and especially for others coming across this thread), in the comments in the blog post linked above, the author clarified that it’s not set up to send event markers (i.e., triggers, or information to specific channels) to BIOPAC. Unfortunately, as far as I can tell, AcqKnowledge (the software to accompany the MP150/MP160) cannot accept traditionally serially encoded bytes. This means that to the best of my knowledge, there must be a piece of hardware in between the serial information leaving PsychoPy and the information recorded from BIOPAC. Blackbox Toolkit manufactures a USB-TTL module (also available on BIOPAC’s website) which has been tested by the BIOPAC team and should work as the in-between. Someone with some amount of electrical engineering knowledge could probably produce a similar piece of hardware, although it might have a greater latency, since the USB-TTL was designed to send very precisely timed triggers. It is possible that a custom cable, or a custom arrangement of available cables, would also be able to replicate the connections (again with questionable latency), but I can’t vouch for cables being a realistic possibility. If anyone is interested in testing out the cables idea I can send more info (the cables would be a little over USD$200, whereas the USB-TTL module would be in the USD$350-460 range).

Will definitely keep you updated, and I’ll make code available once there’s a functional, tested task.

Hi there!

I am facing similar questions lately. Even though I could successfully add digital channel and make it work, I was unable to distribute different routines to different channels. I am wondering if you were able to make it work for your study?

Thanks!

Best,
Miranda

hi @lemonchestnutkk ,
I haven’t gotten a fully functional task yet, but I suspect that I have a method that would work using the blackbox TTL module. The idea is to create digital channels in acqknowledge that correspond to each of the 8 digital channels that can be triggered from the stimulus presentation software. Through a terribly unsophisticated method of trial and error, I managed to figure out a few serial bytes which when sent via the TTL module would trigger different channels. Then, I created composite digital channels (each channel can be the sum of two others), so there can be a handful of channels which each trigger 5 volts, so in theory there can be 8 unique event codes in one composite digital channel (a sequence from 5 to 40 by 5). This procedure is so ugly however, that I can’t help but think that there is a better way. Unfortunately, neither PsychoPy nor BIOPAC seems to have an interest in figuring out a more elegant solution. For administrative reasons, the study that I was setting up was delayed so I’ve been waiting with my fingers crossed for PsychoPy engineers to tackle the trigger export issue or BIOPAC engineers to figure out how accept text annotations via serial port (the later of which I believe would be the optimal solution). There are two disclaimers here:

  1. I do not consider myself an expert in these systems, so I could be missing critical information
  2. I haven’t worked on the experiment setup since the summer, so anything that happened in the last 6 months I wouldn’t be aware of
    I hope that helps a little bit and please post if you happen to figure out anything new on this front, as I hope to set up a task in the coming months.

PS. In addition to the ugliness of this solution, it also suffers from a critical limitation that the composite channel has a limited number of levels that can be used as event markers. I think it would be possible to create multiple channels with different combinations but that just doesn’t strike me as a good method.

Hi @plonskipe , thank you so much for your reply. By reading the application notes on biopac, I also came across the idea of TTL module which was used in E-Prime’s integration with biopac (Application Notes | BIOPAC). In the application note on biopac, they further explain how to send individual markers to biopac for different stimuli. You may find the sample codes used in the examples useful.

So far, I have tried iohub on psychopy3, but it did not work. I have decided to switch to inquisit instead of psychopy, but I have found several resources that may be helpful to you.

  1. somebody recommended the imhr package on python, it worked for parallel port in EEG-psychopy, so it may also work for psychopy-biopac.
  2. (Parallel Port Builder View - #3 by SabrinaSghirripa) some examples about communicating psychopy with EEG

Good luck with your studies!

Hi @plonskipe

I’m having an issue connecting the TTL module to Biopac and I was wondering if you could tell me a bit about how you managed to get yours working. I’m using the blackbox TTL module and while I can see that the triggers are being sent to the TTL module (the red light is coming on/off when triggers are send/stopped), I can’t seem to get Biopac to register the triggers. When I look at the Digital Inputs channels on Biopac they just flatline, irrespective of whether the TTL module is showing a red light or not.

Hi,

I’ve attached the code I’m currently using - I’ve just created a test experiment which should send a byte every time the trial_1 routine begins. This does seem to partially work as the red light on the TTL module box lights up at the right time. I have been told by a colleague that they spoke to the supplier of Biopac kit (Linton Instruments) and their technical guy (who they trust from many previous interactions) said that the BlackboxTTL module does work effectively with Biopac - so in theory we should be able to figure it out! I’ve asked the colleague for the contact details of the tech guy they spoke to and I will be speaking with him later, so I’ll let you know if anything useful comes from it. You seem to be a step ahead of me though as I’ve not been able to get Biopac to even register any triggers, let alone start worrying about sending bytes on specific channels. I’m wondering if I’ve not connected the Module to Biopac properly - did you have to remove all the screws in the gender changer to get it to fit onto both ports (see attached image)?

Thanks for taking the time to respond!

Best,

Carmen

Test_runs.zip (97.9 KB)

hi @Carmen_Daoust! I deleted my previous message because I had an idea yesterday, but it didn’t pan out this morning.

  1. We use a ribbon cable to connect the USB TTL module to the MP150, but your install looks fine to my amateur eye.
  2. You’re correct that this should work! However, the problem that I’m running into has to do with what’s happening in between PsychoPy and AcqKnowledge. One thing that I can’t figure out is which digital channels in AcqKnowledge are used as input channels for the digital signals coming from the TTL module. According to their documentation, some BIOPAC hardware uses the first 8 (D0-D7, in A5.0), while others (e.g., the MP150) uses the last 8 (D8-D15).
  3. However, when I send “FF”, which should in theory set all 8 digital channels to 0, only three channels are triggered (your test code is very similar to my test code)
ser.write("FF".encode())

I’ve also tried sending bytes like

ser.write(b'36')

Which does something on (~6?) channels
4. Also, sometimes, the channel remains at the triggered state (0 or 5), but other times the channel resets itself (with no change to the python code, other than the actual bytes being sent).
5. I think that one difference between PsychoPy and, for example, e-Prime, is that e-Prime software helps process the signals being sent to the USB TTL module, which then in turn makes more sense to AcqKnowledge.
6. I reached out to BIOPAC support this morning to request help in figuring out what’s going on in-between PsychoPy and AcqKnowledge, and will definitely continue to communicate any new information here.

Alright, I think I finally figured out a way. I’ll get a better example together soon that includes an AcqKnowledge graph template and a data export file, but for now, in case your task is time-sensitive, here’s a builder exp that sets all 8 input channels to 5V initially (code 255), drops them all to 0 (code 0), then goes “down” from default to 240 in another trial. (The actual numbers calculated are a little weird right now, as I set the baseline to 255, but I’ll fix that in a future example.)
On the MP150, a calculated “expression” channel uses D8-D15 as so:
(D8 * 128 + D9 * 64 + D10 * 32 + D11 * 16 + D12 * 8 + D13 * 4 + D14 * 2 + D15) / 5
[divide by 5 because we’re working with 5V increments]
On the MP36, the first eight channels should be the input channels, D0-D7.

test_serial_signals.zip (10.9 KB)

Hi! I’m just starting our lab’s foray into trying to connect our PsychoPy tasks with Biopac. I’m wondering what items you purchased from Biopac to try and make the connection work. Our sales rep recommended purchasing the STP100D and the USB-TTL modules, but a Biopac product manager recommended the Network Data Transfer license in a webinar as well. Do you have the NDT license? I know this is a bit off-topic, but it’s difficult to find info about this online. Thanks so much for any insight!

Hi @lbdlpsych !
I don’t think we have the Network Data Transfer license. We use the MP150, AcqKnowledge 5.0, the USB-TTL module from BlackBox, and the STP100C. The TTL module plugs into the STP100C with a ribbon cable.
Happy to help any way I can - it’s been a hassle to set this up. I’m planning to put together some more thorough documentation in the next few weeks too.
P

Great, thank you for sharing!

here’s a working example to implement event codes with the following setup: PsychoPy → BlackBox USBTTL module → STP100C → MP150, and record event codes in AcqKnowledge 5.0. Dictionary for hex strings to encode that correspond to calculated channel values is included.
psychopy_biopac_blackboxUSBTTL_documentation.zip (1.1 MB)

Hi friend,

I would be interested in testing out the latency of the cables instead of using a black box. Can you send that over?

Thanks!

hi @Brett99 , the BlackBox USB TTL module is designed to use a serial port connection, which is needed when a stimulus computer does not have a parallel port. If you have a parallel port on your computer you should be able to plug the ribbon cable from the STP100C into the computer and test that configuration. Does that answer your question?