TTL triggers in Linux


Hello,

I was wondering if there is an easy way to send TTL triggers via parallel port in Linux (I'm currently using Ubuntu 10.10).

I have seen the LabJack options, but if I understood correctly you have to use a USB DAQ device for it to work. I was using the " lptwrite" command in Windows and I was wondering if there is something similar for Linux.

Thanks in advance

--
Andre Cravo
Post-hoc Fellow
University of Sao Paulo-Brazil

Hi,


I am using this method (using ParportTTL function) to send values to the parallel port (to tag my EEG data). I did exactly the same procedure in Matlab 2012a 64bit under Debian but I encountered the following error:


Attempt to execute SCRIPT pnet as a function:
/usr/share/psychtoolbox-3/PsychHardware/iViewXToolbox/tcp_udp_ip/pnet.m

Error in ParportTTL (line 109)
        pserver = pnet('udpsocket', port);

Error in StaircaseCSFPresentaionTagged (line 3)
ParportTTL('Open', 'parallelport');


pnet.m is a script but I guess ParportTTL needs to access the pnet as a mex file.

Could you please let me know if you have any suggestions?


Thanks,

Tahereh


 



--- In psychtoolbox@yahoogroups.com, <mario.kleiner@...> wrote:

--- In psychtoolbox@yahoogroups.com, Andre Cravo <andrecravo@...> wrote:
>
> Hello,
>
> I was wondering if there is an easy way to send TTL triggers via parallel
> port in Linux (I'm currently using Ubuntu 10.10).
>
> I have seen the LabJack options, but if I understood correctly you have to
> use a USB DAQ device for it to work. I was using the " lptwrite" command in
> Windows and I was wondering if there is something similar for Linux.
>

I've just uploaded LinuxParportServer.zip to the files section of the forum. It should work ok, although there are better solutions to come. A proper implementation will be part of the IOPort driver in a future PTB beta.

This one works as follows:

1. unzip the file.
2. Compile the .cpp C file into a binary via (terminal window):

gcc -O2 -o parallelPortServer parallelPortServer.cpp

3. Run the executable in that terminal as root, e.g.:

sudo ./parallelPortServer

4. The server will wait for commands over a UDP network port. This is where you use the M-File ParportTTL.m in your matlab code:

At beginnning of your script:

ParportTTL('Open', 'localhost');

At end of your script:

ParportTTL('Close', 'localhost');

For changing the state of the output lines of the parallel port in your code:

tRoundTrip = ParportTTL('Set', level [, duration=inf]);

--> See help ParportTTL for the meaning of the parameters.

This was used for a study where the stimulation computer and computer with parallel port where different machines, therefore the network server design. You could do the same by setting the hostname of the machine with the parallelport, instead of 'localhost' if everything is running on the same machine.

Timing accuracy on a normal working local network is about 1 msec if i remember correctly, but 'tRoundTrip' will give you a good upper bound on timing error for each invocation. Last tested over 1 year ago, where the parallel port computer was a linux box and the stimulation computer was a Apple OS/X box, so i hope it still works "as is" on a modern system.

As i said, a proper implementation will follow as part of IOPort in the future - one would design this quite differently nowadays, this was just quick throwaway code for a special EEG study on a very special setup, but for the moment this should do...

best,
-mario

> Thanks in advance
>
> --
> Andre Cravo
> Post-hoc Fellow
> University of Sao Paulo-Brazil
>

Dear all, dear Mario,

I was wondering what is the current solution for sending the parallel port triggers on Linux.
We have Ubuntu 18.04 and want to send triggers to the EEG recording system.
I know that parallel port is ancient, but we have to use it.
Has the IOPort been updated to send triggers to the parallel port? If not, what is the current suggested alternative?

Many thanks!
Greetings from Graz!
Natalia

Hi Natalia!

Nope, no work done on IOPort for “the ultimate I/O support, everything and the kitchen sink” in ages. That project gets pushed off over and over by more urgent projects all the time. One fine day it will hopefully happen…

The best method atm. is using this free code from Andreas Widman:

The contained Matlab mex file should just work. The Octave mex file is outdated for the Octave version shipping in Ubuntu 18.04, but recompiling is as easy inside Octave as typing this inside Octave while being in the main folder:

mex ppdev_mex.c

We used to have more options, also for TTL trigger reception over parallel port, as listed in the FAQ:

But i just realized all other links are dead, because they pointed to the dead old yahoogroups forum :/. Probably one could find those messages again with a long enough search of this forum…

Gruessle,
-mario

1 Like

I don’t know the reason you have to stick with the obsolete parallel port.
Our RTBox probably works for any EEG systems, and supports all major operating systems. It is super easy to use. When you want to send a trigger, you will just do

RTBox('TTL', myEventCode); % myEventCode from 0 to 255

You may need to make a cable connecting RTBox port to your EEG system. Each EEG system has its own pinout for trigger bits, so unless for NeuroScan, you will likely need a customized cable.

Don’t hesitate to contact me if you need more information.

-Xiangrui

Hi Mario,

thanks a lot, your suggestion to use ppdev_mex works like magic! This is all we need.

Natalia

1 Like

It seems that ppdev is a blocking interface – i.e. that you need to write high, then wait, then write low. This means MATLAB/PTB is blocked from exectuing while the TTL is being generated. This is OK if you are not doing anything else in your loop, but what if you are updating stimuli, need to also read an eyetracker, or do some computation etc.?

If you need non-blocking TTLs, then you can use something like the RTBox that Xiangrui mentioned, or with much less functionality an Arduino or LabJack connected via USB. Because they all run on their own microprocessor, they can run independently of PTB, so that you send a command, it immediately returns to MATLAB so it can continue processing while the microprocessor handles the high-wait-low cycle. At least with the Arduino and LabJack, the latency is ~0.5ms (send commands as fast as possible in a loop, measure the voltage signal on an oscilloscope). The PTB wiki contains info on both interfaces.


Thanks for the hint on ppdev. The time between sending a trigger with ppdev and returning back to code execution on our system is on average 0.01 ms, which we can live with, I would say, since we only send a trigger once in a while.

I also hope we switch to some more modern solution (compared to a parallel port) with time.

Sorry, late but anyway:

It seems that ppdev is a blocking interface – i.e. that you need to write high, then wait, then write low. This means MATLAB/PTB is blocked from exectuing while the TTL is being generated.

In a strict sense ppdev_mex is blocking, yes, but writing a byte only introduces delays in low microsecond range (as Natalia tested and reported). The TTL cycle itself is not blocking. You may easily adapt the TTL cycle to your requirements, for example screen refreshes, high after one and low after the next flip, or use the time between high and low for other computations in timing critical situations. No waiting necessary. All EEG amplifiers I have ever used would tolerate this kind of longer duration or even variable length TTL triggers.

At least with the Arduino and LabJack, the latency is ~0.5ms (send commands as fast as possible in a loop, measure the voltage signal on an oscilloscope).

I would expect parallel port latencies to be considerably lower than 0.5 ms.

Best,
Andreas

Hi Andreas, yes it depends on your requirements. We use reward systems where the length of the TTL controls the amount of reward given, and so this demands non-blocking control. Although single TTL triggers may be flexible in terms of timing (if equipment only monitors rising time), if equipment doesn’t using rising time but state at sample, then multiple events may be triggered for long TTL pulses, and complex requirements like strobed words with a seperate strobe bit are difficult to set up unless you can do this off the main loop. But I agree that the advantage of parallel port is that it is lower-level than USB and therefore more reliable…

I have added a binary for Ubuntu 20.04/Octave 5. I do not have a Ubuntu 18.04 setup available. Natalia, if you send me the binary mex file you compiled for 18.04/Octave 4, I will also add it to the repository.

Best,
Andreas

Actually on our EEG Setup where we are using ppdev we have MATLAB, so I never tried to compile it for Octave. I can do it on a different Ubuntu setup with Octave 4 installed, though I won’t be able to test it. If you think it can still be useful, I would be happy to do it!

Best,
Natalia

Hi, I am trying to use ppdev_mex on Matlab R2021a under Ubuntu 18.04.5 on an old Optiplex 990 that has an actual parallel port (not via usb) to send the TTL signals with a BrainVision system. When I try to open the port with ppdev_mex(‘Open’,1) I get the error:
/dev/usb/lp0 No such file or directory.

This error message is correct in that the driver is at /dev/lp0 and there is no /dev/usb directory. My question is how to get it to look for the driver in the correct location.

Dear Joe,

  • Does /dev/parport0 exist?

  • Is the lp module UNloaded (not listed by lsmod; it blocks access to ppdev)? The lp module should be blacklisted automatically by the SetupPsychtoolbox (automatically calling the PsychLinuxConfiguration function) script. Did you run SetupPsychtoolbox/PsychLinuxConfiguration?

  • Do you use the original pre-compiled ppdev_mex.mexa64 function from GitHub? The /dev/parportX-address is hardcoded. Thus, I do not really have an idea why it would want to open a (usb) lpX-address. My best guess would be some interference from the lp-module.

Best,
Andreas

Thanks so much for this quick response! /dev/parport0 does indeed exist. I did not use either of the scripts you mentioned as they are not part of the current Psychtoolbox installation instructions (via subversion). I went ahead and ran SetupPsychtoolbox and it did indeed fix the problem! As well as doing a number of other things that appeared to be useful. This makes me wonder why it is no longer part of the installation instructions! I do remember having used it in the past. It is currently only mentioned in the section “Installation without Download”. Apparently, the assumption is that the “DownloadPsychtoolbox” runs this script but it doesn’t? I don’t see a function call for SetupPsychtoolbox in the DownloadPsychtoolbox script. Or something went wrong when I used it? Not sure. Another part of the problem was I was using an older version of the mex file from github so when I replaced it with the current one that fixed the remainder of the error messages (thanks for the suggestion!). That’s not to say everything is fully functional yet. It now runs through without any error messages but I’m not seeing any TTL signals appearing in PyCorder. Not sure where the problem is arising. I’ll need to do more troubleshooting tomorrow. Any suggestions are welcome!

Dear Joe,

To exclude problems with cabling and receiver side I typically first check manually with a multi-meter. Pin 2-9 (counted from right to left on female PC port, iirc) against pin 25 after writing 255 or 0, respectively.

The other thing coming to my mind: this is an ActiChamp, right? ActiChamp needs longer trigger pulse width than BrainAmps previously (> 2 x sampling interval, 4 ms at 500 Hz).

Best,
Andreas