EEG Triggers via Labjack: How to do the Parallel Port DB25 connection

I am programming EEG experiments using Psychopy and the Brain Products EEG system. As an interface to send event triggers from my experiment to the EEG system, I am using the parallel port (DB25 connector).

I have seen several posts across the new and the old psychopy forum about using a Labjack U3 device instead of the parallel port and I am interested in this solution for two reasons:

  1. Modern computers often ship without parallel ports and I want to replace that technology while still being able to interface with my current EEG equipment. The timing properties of the parallel port should be preserved or improved.
  2. Existing solutions to replace the parallel port via a serial connection that emulates a parallel port usually only have drivers for Windows or at most OSX … but I would prefer to use Linux

What prevents me from ordering a Labjack U3 is that I am at a loss how I would connect it to a parallel port cable with db25 connectors. According to the data sheet, the Labjack only has a DB15 connector. How do the psychopy users of the Labjack U3 solve this? Do I HAVE to get my hands dirty, open a DB25 cable and connect the single cable ends to the single IO pins?

From the forums I know that at least @jon has used this successfully and also tested the timing - so I’d be grateful for a short reply.

1 Like

I’m afraid our technician did make a converter cable for us. I guess you could buy a labjack U12 instead? That appears to have a DB25 connector built in.

1 Like

Alright - thanks for the reply. Now at least I know what needs to be done …

I guess you could buy a labjack U12 instead? That appears to have a DB25 connector built in.

Yes - however it seems that the U12 is discontinued (at least it’s listed as “legacy”). I’ll see whether I can find somebody who could build an adapter to DB25 from the U3 device :slight_smile: For that I’ll start by asking LabJack whether they can provide one.

We have an Arduino Leonardo (as suggested in the Psychtoolbox FAQ) that’s connected to the BrainAmp via a DB25 terminal adapter. It shows up as serial port and requires no additional drivers on Linux.

The code for the arduino is as follows:

const int outputPins[] = {0,1,2,3,4,5,6,7};

void setup() {
  for(auto pin: outputPins) pinMode(pin, OUTPUT);

void loop() {
  if(!Serial.available()) return;
  uint8_t inChar =;

void setOutputs(uint8_t outChar) {
  for(int i=0;i<8;i++) digitalWrite(outputPins[i], outChar&(1<<i));
void clearOutputs() {
  for(auto pin: outputPins) digitalWrite(pin, LOW);

1 Like

Hi @tstenner thanks for your answer. Using the arduino sounds very interesting and the DB25 terminal adapter you linked looks straight forward. This would be a low-cost solution indeed (and it would work under every OS I assume).

Two questions:

  1. Would you mind sharing the wiring of the Arduino Leonardo with that said adapter?
  2. Have you performed timing tests?

Browsing through your other answers in this forum, I also found this topic, in which an adapter by the BlackBoxToolKit company is also mentioned:

BBTK says this one can be used under Linux as well, albeit their “validation software” only works under Windows apparently. Perhaps this would be yet another solution.

I’m currently not at the lab, but the wiring is quite simple - the Arduino has the output numbers printed on it, and the parallel port numbering is available e.g. on Wikipedia.

The timing mostly depends on 2 things: your serial port latency and the waiting time in the loop (2x8ms, so any triggers closer than 16ms together will be delayed). You can time the serial roundtrip (e.g. here), with both Arduino Leonardos, Arduino Micros and Teensys we’re well below 1ms on Linux.

Hi @tstenner,

when checking the pin out of a parallel port, there are a lot of pins that do not seem to have a direct correspondence to the ones available on e.g., the arduino micro, such as:

  • INIT
  • SEL
  • PE
  • BUSY
  • ACK

parallel port pinout

Can I leave all of these pins alone and just connect a GROUND and the DATA pins (2,3,4,5,6,7,8,9) for BITS 0 to 7?

Apart from that, there seems to be an excessive amount of GROUND pins in the DB25 connector. Does it suffice to only connect to one GROUND pin via the arduino ground? Is it irrelevant, which of the GROUNDS I pick?

Lastly, I assume that I use the arduino “DIGITAL PINS” to connect to the parallel port data pins? That is:

  • Arduino DIGITAL PIN 2 → DB25 PIN 2 (corresponding to bit 0)
  • Arduino DIGITAL PIN 3 → DB25 PIN 3 (corresponding to bit 1)
  • … and so on

For reference, here is the pin out of the arduino micro



*Update: I just went ahead and tried to implement this with the Arduino Uno that I had at home. I simply connected the wiring for pins 2 to 9 on the db25 connector with their counterparts on the UNO (digital pins 2 to 9) and a single ground on db25 pin 18 to my Arduino Uno ground.

then I used @tstenner’s code with the nice bitwise operator function (took me a bit to understand how that works … really efficient!) and hooked the interface up to the EEG equipment.

Using python and pyserial, I could send bytes using port.write(bytes([1])) and it worked like a charm :slight_smile:

The latency on the Arduino Uno is about 3ms for a roundtrip so I am ordering an Arduino Leonardo now to get sub-millisecond precision.

I’ll do an in-depth write-up of this and share it as a tutorial somewhere. Thanks again!

The wiring depends on your EEG amplifier with most EEGs using the ports 2-9 for data and 25 for ground, the other grounds might be used otherwise. The wiring should be Arduino digital 0 -> DB25 Pin2 (data0), etc.

When you get it running, I’d be especially happy about the raw latency data.
The delay is much less important than the variance in latency, and even a constant 1.5ms (so 3ms roundtrip) would be much better than the usual latencies with keyboard / mouse responses and screen flip times.

The Leonardo / Micro (same controller but different form factor) should be much faster than the Uno, and the Teensys (both Teensy LC and 3.2) have the potential to be even faster without any code change. The Teensys can also set 8 outputs at once, but the digital output switching won’t be a bottleneck.

Quick update: With a Teensy 3.2 connected to a Windows 7 PC I get the following roundtrip latencies (all in ms): M=0.149, SD=0.171, Range=.055-.155

Many years later tstenner and I are finally ready to share a preprint and documentation of the work we continued to do in the direction of this thread:


Now published open access in Behavior Research Methods:

Hi @sappelhoff, @tstenner ,

Fantastic job!

I am looking for a way to send triggers via USB from my behavioral computer to a Natus Quantum EEG amplifier, which comes with a DB15 8-bit digital trigger input. After reading your USB-to-TTL paper and website, it seems that is relatively easy to build such a device.

Which of the MCUs you reviewed would you recommend me? Does it make sense to purchase a Labjack U3 instead and avoid part of the messy process?

Thanks in advance,

1 Like

Which of the MCUs you reviewed would you recommend me? Does it make sense to purchase a Labjack U3 instead and avoid part of the messy process?

I don’t think there is a right or wrong answer about rolling your own vs. buying prebuilt for this type of device these days. It depends on the lab / person asking the question: how much time / interest is there for making the device yourself vs. buying one and focussing on your research.

If you want to get into the details and make your own USB Serial → ttl converter, then the Teensy 3.2 is excellent. It is the MCU I use inside the USB2TTL8 device and can confirm the USB Serial timing is excellent.

If you want a pre built product, the LabHackers USB2TTL8 or LabJack U3, are options that can be used with the PsychoPy Builder Parallel Out Component or by writing a little python code.

1 Like

I agree with Sol’s answer, and in fact we have a LabHackers USB2TTL8 device in our lab and it works great and is affordable.