Additions:
**Note: //there are several other solutions (mostly via USB devices, which are slower than the parallel port) to send out digital pulses which work on OS X and Linux as well as Windows; these are listed at [[FaqTTLTriggerOSXLinux]].//**
**Q:** How to send TTL triggers via parallel port (Win 2k/XP/Vista/7)?
1) To access the parallel port under NT/2k/XP/Vista/7 a kernel ring 0 driver is required. We use PortTalk by Craig Peacock you can download from http://www.beyondlogic.org/porttalk/porttalk.htm. **This works for 32 bit windows only (see below for 64 bit solution).** Copy the porttalk.sys driver enclosed in the zip archive to your windows\system32\drivers directory. Edit the porttalk.reg file replacing "Start"=dword:00000002 by "Start"=dword:00000000 (to load the driver at boot time not constantly requiring administrative privileges). As user with administrative privileges double-click the edited porttalk.reg to write the contents into the Windows registry and reboot your machine.
**For 64 bit windows**, use [[http://people.usd.edu/~schieber/psyc770/IO64.html]].
**Q:** How to send TTL triggers via parallel port (Win 2k/XP/Vista/7)?
1) To access the parallel port under NT/2k/XP/Vista/7 a kernel ring 0 driver is required. We use PortTalk by Craig Peacock you can download from http://www.beyondlogic.org/porttalk/porttalk.htm. **This works for 32 bit windows only (see below for 64 bit solution).** Copy the porttalk.sys driver enclosed in the zip archive to your windows\system32\drivers directory. Edit the porttalk.reg file replacing "Start"=dword:00000002 by "Start"=dword:00000000 (to load the driver at boot time not constantly requiring administrative privileges). As user with administrative privileges double-click the edited porttalk.reg to write the contents into the Windows registry and reboot your machine.
**For 64 bit windows**, use [[http://people.usd.edu/~schieber/psyc770/IO64.html]].
Deletions:
**Q:** How to send TTL triggers via parallel port (Win 2k/XP/Vista/7, 32 bit only)?
1) To access the parallel port under NT/2k/XP/Vista/7 a kernel ring 0 driver is required. We use PortTalk by Craig Peacock you can download from http://www.beyondlogic.org/porttalk/porttalk.htm. This works for 32 bit windows only. Copy the porttalk.sys driver enclosed in the zip archive to your windows\system32\drivers directory. Edit the porttalk.reg file replacing "Start"=dword:00000002 by "Start"=dword:00000000 (to load the driver at boot time not constantly requiring administrative privileges). As user with administrative privileges double-click the edited porttalk.reg to write the contents into the Windows registry and reboot your machine.
For 64 bit windows, use [[http://people.usd.edu/~schieber/psyc770/IO64.html]].
Additions:
=== [[http://psychtoolbox.org/wikka.php?wakka=PsychtoolboxFaq FAQ]] - TTL triggers via parallel port (Win 2k/XP/Vista/7) ===
**Q:** How to send TTL triggers via parallel port (Win 2k/XP/Vista/7, 32 bit only)?
1) To access the parallel port under NT/2k/XP/Vista/7 a kernel ring 0 driver is required. We use PortTalk by Craig Peacock you can download from http://www.beyondlogic.org/porttalk/porttalk.htm. This works for 32 bit windows only. Copy the porttalk.sys driver enclosed in the zip archive to your windows\system32\drivers directory. Edit the porttalk.reg file replacing "Start"=dword:00000002 by "Start"=dword:00000000 (to load the driver at boot time not constantly requiring administrative privileges). As user with administrative privileges double-click the edited porttalk.reg to write the contents into the Windows registry and reboot your machine.
4) (Vista/7 only) Under Vista, [[http://en.wikipedia.org/wiki/User_Account_Control UAC]] prevents PortTalk from starting. Right-click MATLAB and choose "run as administrator" to allow PortTalk to start. You don't need to do this for additional MATLAB sessions until next time you reboot. You can also turn off UAC completely in the user account control panel.
For 64 bit windows, use [[http://people.usd.edu/~schieber/psyc770/IO64.html]].
An alternative is [[http://tech.groups.yahoo.com/group/psychtoolbox/message/9328]] (note calllib is not as fast as mex, so if performance is an issue, use the dll described there with the mex approach described here)
**Q:** How to send TTL triggers via parallel port (Win 2k/XP/Vista/7, 32 bit only)?
1) To access the parallel port under NT/2k/XP/Vista/7 a kernel ring 0 driver is required. We use PortTalk by Craig Peacock you can download from http://www.beyondlogic.org/porttalk/porttalk.htm. This works for 32 bit windows only. Copy the porttalk.sys driver enclosed in the zip archive to your windows\system32\drivers directory. Edit the porttalk.reg file replacing "Start"=dword:00000002 by "Start"=dword:00000000 (to load the driver at boot time not constantly requiring administrative privileges). As user with administrative privileges double-click the edited porttalk.reg to write the contents into the Windows registry and reboot your machine.
4) (Vista/7 only) Under Vista, [[http://en.wikipedia.org/wiki/User_Account_Control UAC]] prevents PortTalk from starting. Right-click MATLAB and choose "run as administrator" to allow PortTalk to start. You don't need to do this for additional MATLAB sessions until next time you reboot. You can also turn off UAC completely in the user account control panel.
For 64 bit windows, use [[http://people.usd.edu/~schieber/psyc770/IO64.html]].
An alternative is [[http://tech.groups.yahoo.com/group/psychtoolbox/message/9328]] (note calllib is not as fast as mex, so if performance is an issue, use the dll described there with the mex approach described here)
Deletions:
**Q:** How to send TTL triggers via parallel port (Win 2k/XP/Vista only)?
1) To access the parallel port under NT/2k/XP/Vista a kernel ring 0 driver is required. We use PortTalk by Craig Peacock you can download from http://www.beyondlogic.org/porttalk/porttalk.htm. Copy the porttalk.sys driver enclosed in the zip archive to your windows\system32\drivers directory. Edit the porttalk.reg file replacing "Start"=dword:00000002 by "Start"=dword:00000000 (to load the driver at boot time not constantly requiring administrative privileges). As user with administrative privileges double-click the edited porttalk.reg to write the contents into the Windows registry and reboot your machine.
4) (Vista only) Under Vista, [[http://en.wikipedia.org/wiki/User_Account_Control UAC]] prevents PortTalk from starting. Right-click MATLAB and choose "run as administrator" to allow PortTalk to start. You don't need to do this for additional MATLAB sessions until next time you reboot. You can also turn off UAC completely in the user account control panel.
5) (win64 only) See [[http://tech.groups.yahoo.com/group/psychtoolbox/message/9328]] (note calllib is not as fast as mex, so if performance is an issue, use the dll described there with the mex approach described here)
Revision [1691]
Edited on 2011-08-03 04:34:41 by IanA [reworded link to other methods to generate TTLs]Additions:
**Note: //there are several other solutions (mostly via USB devices) to send out digital pulses which work on OS X and Linux as well as Windows; these are listed at [[FaqTTLTriggerOSXLinux]].//**
Deletions:
Additions:
(for potential OS X / Linux solutions, see [[FaqTTLTriggerOSXLinux]])
Additions:
3) Find out the port address of the parallel port your cable is attached by right clicking on My Computer (for XP), select Manage then Device Manager, expand 'Ports (COM & LPT)', right click on the item that is named 'Printer Port (LPT1)' (or the like) and select properties. Select the Resources tab of the properties dialog and check the I/O Range, the first value of the 'Setting' column should be the actual port address. For LPT1 this is supposed to be 888 (hex378) on most standard setups, however, for add-on parallel port cards this is not necessarily the case. A STAR TECH 1 Port PCI Express add-on card can be called LPT1 but have a port address of 8192 (hex2000) for example. Now you can set the output bits 0-7 (pin 2-9) of your parallel port with "lptwrite(portAddress, byteValue)" e.g. lptwrite(888, 255). To achieve a TTL trigger wait the time your EEG system requires (usually min 1/sampling rate) before resetting the port to zero, e.g.
mexErrMsgTxt("Two input arguments required.");
mexErrMsgTxt("Too many output arguments.");
mrows = mxGetM(prhs[arg]);
ncols = mxGetN(prhs[arg]);
if (!mxIsDouble(prhs[arg]) || mxIsComplex(prhs[arg]) || !(mrows == 1 && ncols == 1)) {
mexErrMsgTxt("Input must be noncomplex scalar double.");
}
mexErrMsgTxt("Two input arguments required.");
mexErrMsgTxt("Too many output arguments.");
mrows = mxGetM(prhs[arg]);
ncols = mxGetN(prhs[arg]);
if (!mxIsDouble(prhs[arg]) || mxIsComplex(prhs[arg]) || !(mrows == 1 && ncols == 1)) {
mexErrMsgTxt("Input must be noncomplex scalar double.");
}
Deletions:
mexErrMsgTxt("Two input arguments required.");
mexErrMsgTxt("Too many output arguments.");
mrows = mxGetM(prhs[arg]);
ncols = mxGetN(prhs[arg]);
if (!mxIsDouble(prhs[arg]) || mxIsComplex(prhs[arg]) || !(mrows == 1 && ncols == 1)) {
mexErrMsgTxt("Input must be noncomplex scalar double.");
}
Additions:
[[http://logix4u.net/Legacy_Ports/Parallel_Port/How_to_read_Parallel_Serial_Port_address_from_BIOS.html hwinterface32]] knows how to access physical memory. The following code types out the addresses for LPT1-3. Unfortunately, like Matlab, it does not see PCI or PCMCIA add-on cards. Anyone know where to look up their addresses in physical memory? It seems that Windows must know, since it has assigned them LPT numbers.
path = 'C:\Documents and Settings\rlab\Desktop\Hwinterface32Beta01\Release\bin\'; %edit this for your location
[notfound, warnings] = loadlibrary([path lib '.dll'],[path lib '.h']);
%%(c;hwinterface32B01.h)
path = 'C:\Documents and Settings\rlab\Desktop\Hwinterface32Beta01\Release\bin\'; %edit this for your location
[notfound, warnings] = loadlibrary([path lib '.dll'],[path lib '.h']);
%%(c;hwinterface32B01.h)
Deletions:
path = 'C:\Documents and Settings\rlab\Desktop\Hwinterface32Beta01\Release\bin\';
[notfound, warnings] = loadlibrary([path lib '.dll'],[path lib '.h'])
libfunctions(lib,'-full')
%%(c;hwinterface32B01.c)
Revision [1527]
Edited on 2009-05-20 02:02:06 by ErikFlister [solution for discovering parallel port addresses]Additions:
UPDATE
[[http://logix4u.net/Legacy_Ports/Parallel_Port/How_to_read_Parallel_Serial_Port_address_from_BIOS.html hwinterface32]] knows how to access physical memory. The following code types out the addresses for LPT1-3.
path = 'C:\Documents and Settings\rlab\Desktop\Hwinterface32Beta01\Release\bin\';
lib='hwinterface32B01';
[notfound, warnings] = loadlibrary([path lib '.dll'],[path lib '.h'])
libfunctions(lib,'-full')
for i=0:2
dec2hex(calllib(lib,'ReadMemShort',hex2dec('408')+2*i))
end
unloadlibrary(lib)
You'll need to make this header:
%%(c;hwinterface32B01.c)
long __stdcall ReadMemShort(unsigned long addr);
[[http://logix4u.net/Legacy_Ports/Parallel_Port/How_to_read_Parallel_Serial_Port_address_from_BIOS.html hwinterface32]] knows how to access physical memory. The following code types out the addresses for LPT1-3.
path = 'C:\Documents and Settings\rlab\Desktop\Hwinterface32Beta01\Release\bin\';
lib='hwinterface32B01';
[notfound, warnings] = loadlibrary([path lib '.dll'],[path lib '.h'])
libfunctions(lib,'-full')
for i=0:2
dec2hex(calllib(lib,'ReadMemShort',hex2dec('408')+2*i))
end
unloadlibrary(lib)
You'll need to make this header:
%%(c;hwinterface32B01.c)
long __stdcall ReadMemShort(unsigned long addr);
Revision [1526]
Edited on 2009-05-19 23:28:15 by ErikFlister [note on how to accelerate matlab's data acq toolbox dio putvalue/getvalue]Additions:
-Cris Niell of Stryker lab found that matlab's public digitalio methods putvalue/getvalue can be accelerated from ~1ms to ~20us by caching out the value of daqgetfield(dio,'uddobject'):
dio = digitalio('parallel')
addline(dio,7,0,'out') %pin 9
putvalue(dio,1) %~700us
putvalue(dio.Line,1) %~150us
uddobj = daqgetfield(dio,'uddobject')
putvalue(uddobj,1,1); %~20us (undocumented use demo in @dioline\putvalue.m and @digitalio\putvalue.m - args are: uddobj, vals [, lineInds])
getvalue(uddobj,1); %~20us (undocumented use demo in @dioline\getvalue.m and @digitalio\getvalue.m - args are: uddobj [, lineInds])
dio = digitalio('parallel')
addline(dio,7,0,'out') %pin 9
putvalue(dio,1) %~700us
putvalue(dio.Line,1) %~150us
uddobj = daqgetfield(dio,'uddobject')
putvalue(uddobj,1,1); %~20us (undocumented use demo in @dioline\putvalue.m and @digitalio\putvalue.m - args are: uddobj, vals [, lineInds])
getvalue(uddobj,1); %~20us (undocumented use demo in @dioline\getvalue.m and @digitalio\getvalue.m - args are: uddobj [, lineInds])
Revision [1524]
Edited on 2009-03-26 21:38:59 by ErikFlister [added info for win64 from forum msg 9328]Additions:
5) (win64 only) See [[http://tech.groups.yahoo.com/group/psychtoolbox/message/9328]] (note calllib is not as fast as mex, so if performance is an issue, use the dll described there with the mex approach described here)
- loadlibrary (not as fast as mex) http://tech.groups.yahoo.com/group/psychtoolbox/message/9328
- loadlibrary (not as fast as mex) http://tech.groups.yahoo.com/group/psychtoolbox/message/9328
Revision [1445]
Edited on 2008-08-27 21:22:54 by ErikFlister [added info for win64 from forum msg 9328]Additions:
Unfortunately, the data acquisition toolbox costs extra, is slower (~1ms) than lptwrite/lptread (~10us), and cannot address add-on ports (PCI/PCMCIA), which are a very inexpensive dio option (~US$15). Charitably, Mathworks support showed me the method they use. Use the [[http://www.internals.com/utilities_main.htm WinIO driver]] to eg determine the first parallel port base address:
- You can use a PCI or PCMCIA add-on parallel port. I have run into cards that were not standards compliant and did not work with lptread/lptwrite, but unfortunately didn't keep track of which cards failed. I have tested the following and verified that they do work:
[[http://en.wikipedia.org/wiki/Peripheral_Component_Interconnect PCI]] or [[http://en.wikipedia.org/wiki/PCI-X PCI-X]]: [[http://www.softio.com/pcieppprinterportuniv.htm axxon IC0534KB]]
[[http://en.wikipedia.org/wiki/Pc_card PCMCIA]]: [[http://www.quatech.com/catalog/parallel_pcmcia.php quatech spp-100]]
PCI adaptor for PCMCIA cards (for using laptop PCMCIA cards in a desktop): [[http://sewelldirect.com/PCItoPCMCIA.asp SD-PCI-PCM-G]] ([[http://www.ricoh.com/LSI/product_pcif/pcc/5c485/index.html Ricoh R5C485 chipset]])
- You can use a PCI or PCMCIA add-on parallel port. I have run into cards that were not standards compliant and did not work with lptread/lptwrite, but unfortunately didn't keep track of which cards failed. I have tested the following and verified that they do work:
[[http://en.wikipedia.org/wiki/Peripheral_Component_Interconnect PCI]] or [[http://en.wikipedia.org/wiki/PCI-X PCI-X]]: [[http://www.softio.com/pcieppprinterportuniv.htm axxon IC0534KB]]
[[http://en.wikipedia.org/wiki/Pc_card PCMCIA]]: [[http://www.quatech.com/catalog/parallel_pcmcia.php quatech spp-100]]
PCI adaptor for PCMCIA cards (for using laptop PCMCIA cards in a desktop): [[http://sewelldirect.com/PCItoPCMCIA.asp SD-PCI-PCM-G]] ([[http://www.ricoh.com/LSI/product_pcif/pcc/5c485/index.html Ricoh R5C485 chipset]])
Deletions:
- you can use a pci or pcmcia add-on parallel port. i have tested the following to work with lptread/lptwrite:
[[http://en.wikipedia.org/wiki/Peripheral_Component_Interconnect pci]] or [[http://en.wikipedia.org/wiki/PCI-X pci-x]]: [[http://www.softio.com/pcieppprinterportuniv.htm axxon IC0534KB]]
[[http://en.wikipedia.org/wiki/Pc_card pcmcia]]: [[http://www.quatech.com/catalog/parallel_pcmcia.php quatech spp-100]]
pci adaptor for pcmcia cards (for using laptop pcmcia cards in a desktop): [[http://sewelldirect.com/PCItoPCMCIA.asp SD-PCI-PCM-G]] ([[http://www.ricoh.com/LSI/product_pcif/pcc/5c485/index.html Ricoh R5C485 chipset]])
Revision [1444]
Edited on 2008-08-27 21:13:55 by ErikFlister [added info for win64 from forum msg 9328]Additions:
[[http://en.wikipedia.org/wiki/Peripheral_Component_Interconnect pci]] or [[http://en.wikipedia.org/wiki/PCI-X pci-x]]: [[http://www.softio.com/pcieppprinterportuniv.htm axxon IC0534KB]]
[[http://en.wikipedia.org/wiki/Pc_card pcmcia]]: [[http://www.quatech.com/catalog/parallel_pcmcia.php quatech spp-100]]
pci adaptor for pcmcia cards (for using laptop pcmcia cards in a desktop): [[http://sewelldirect.com/PCItoPCMCIA.asp SD-PCI-PCM-G]] ([[http://www.ricoh.com/LSI/product_pcif/pcc/5c485/index.html Ricoh R5C485 chipset]])
[[http://en.wikipedia.org/wiki/Pc_card pcmcia]]: [[http://www.quatech.com/catalog/parallel_pcmcia.php quatech spp-100]]
pci adaptor for pcmcia cards (for using laptop pcmcia cards in a desktop): [[http://sewelldirect.com/PCItoPCMCIA.asp SD-PCI-PCM-G]] ([[http://www.ricoh.com/LSI/product_pcif/pcc/5c485/index.html Ricoh R5C485 chipset]])
Deletions:
pcmcia: [[http://www.quatech.com/catalog/parallel_pcmcia.php quatech spp-100]]
pci card for pcmcia cards (for using laptop pcmcia cards in a desktop): [[http://sewelldirect.com/PCItoPCMCIA.asp SD-PCI-PCM-G]] ([[http://www.ricoh.com/LSI/product_pcif/pcc/5c485/index.html Ricoh R5C485 chipset]])
Revision [1443]
Edited on 2008-08-27 21:10:40 by ErikFlister [added info for win64 from forum msg 9328]Additions:
- you can use a pci or pcmcia add-on parallel port. i have tested the following to work with lptread/lptwrite:
pci or pci-x: [[http://www.softio.com/pcieppprinterportuniv.htm axxon IC0534KB]]
pcmcia: [[http://www.quatech.com/catalog/parallel_pcmcia.php quatech spp-100]]
pci card for pcmcia cards (for using laptop pcmcia cards in a desktop): [[http://sewelldirect.com/PCItoPCMCIA.asp SD-PCI-PCM-G]] ([[http://www.ricoh.com/LSI/product_pcif/pcc/5c485/index.html Ricoh R5C485 chipset]])
pci or pci-x: [[http://www.softio.com/pcieppprinterportuniv.htm axxon IC0534KB]]
pcmcia: [[http://www.quatech.com/catalog/parallel_pcmcia.php quatech spp-100]]
pci card for pcmcia cards (for using laptop pcmcia cards in a desktop): [[http://sewelldirect.com/PCItoPCMCIA.asp SD-PCI-PCM-G]] ([[http://www.ricoh.com/LSI/product_pcif/pcc/5c485/index.html Ricoh R5C485 chipset]])
Revision [1433]
Edited on 2008-08-07 01:20:58 by ErikFlister [added info for win64 from forum msg 9328]Additions:
An alternative is to use the DOS debug command to read the same area in memory (described [[http://www.doc.ic.ac.uk/~ih/doc/par/doc/findd.html here]]), but I can't figure out how to use an interactive DOS program from inside matlab (for instance using the "dos," "system", or "!" commands - any ideas?)
Deletions:
Revision [1432]
Edited on 2008-08-07 01:19:34 by ErikFlister [added info for win64 from forum msg 9328]Additions:
An alternative is to use the DOS debug command to read the same area in memory (described [[http://www.doc.ic.ac.uk/~ih/doc/par/doc/findd.html here]]), but i can't figure out how to get this to work from inside matlab (any ideas?)
Revision [1426]
Edited on 2008-07-22 22:15:35 by ErikFlister [added info for win64 from forum msg 9328]Additions:
(lcc is picky that this file ends in a blank line)
Copyright (C) 2006 Erik Flister, UCSD, e_flister@REMOVEME.yahoo.com
Adapted from Andreas Widmann.
=== lptread.m ===
%%(matlab;lptread.m)
function value=lptread(port)
% LPTREAD read from port
%
% Description:
% IOCTL call to porttalk.sys kernel mode driver (required) by Craig Peacock
%
% Installation:
% See http://psychtoolbox.org/wikka.php?wakka=FaqTTLTrigger
% http://www.logix4u.net/parallelport1.htm is a good parallel port reference
%
% Usage:
% value = lptread(port)
%
% Arguments:
% port - double Port address (e.g., 889 = 0x1 + 0x378 for status register of LPT1
% on many machines, which corresponds to pins 10, 11, 12, 13, and 15 of a DB25
% parallel port -- note pin 11 is hardware inverted!)
%
% Examples:
% val = lptread(1+hex2dec(0x378));
% dec2bin(val,8) %the second argument uses leading zeros to keep bits in consistent locations
%
% Author: Erik Flister, UCSD, 2006 (C). Adapted from Andreas Widmann.
Copyright (C) 2006 Erik Flister, UCSD, e_flister@REMOVEME.yahoo.com
Adapted from Andreas Widmann.
=== lptread.m ===
%%(matlab;lptread.m)
function value=lptread(port)
% LPTREAD read from port
%
% Description:
% IOCTL call to porttalk.sys kernel mode driver (required) by Craig Peacock
%
% Installation:
% See http://psychtoolbox.org/wikka.php?wakka=FaqTTLTrigger
% http://www.logix4u.net/parallelport1.htm is a good parallel port reference
%
% Usage:
% value = lptread(port)
%
% Arguments:
% port - double Port address (e.g., 889 = 0x1 + 0x378 for status register of LPT1
% on many machines, which corresponds to pins 10, 11, 12, 13, and 15 of a DB25
% parallel port -- note pin 11 is hardware inverted!)
%
% Examples:
% val = lptread(1+hex2dec(0x378));
% dec2bin(val,8) %the second argument uses leading zeros to keep bits in consistent locations
%
% Author: Erik Flister, UCSD, 2006 (C). Adapted from Andreas Widmann.
Revision [1425]
Edited on 2008-07-22 22:01:31 by ErikFlister [added info for win64 from forum msg 9328]Additions:
=== lptread.c ===
%%(c;lptread.c)
lptread.c
Compile in MATLAB with mex lptread.c [-O] [-g] [-v]
For description see lptread.m
void __cdecl mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[])
double *port;
int mrows, ncols;
double *val;
/* Check for proper number of arguments. */
if (nrhs != 1) {
mexErrMsgTxt("One input argument required.");
} else if (nlhs != 1) {
mexErrMsgTxt("One output argument required.");
/* The input must be noncomplex scalar double.*/
mrows = mxGetM(prhs[0]);
ncols = mxGetN(prhs[0]);
if (!mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]) || !(mrows == 1 && ncols ==1)) {
mexErrMsgTxt("Input must be noncomplex scalar double.");
/* Assign pointers. */
plhs[0] = mxCreateScalarDouble(0);
val = mxGetPr(plhs[0]);
/* Call PortTalk. */
*val = inportb(*port);
%%(c;lptread.c)
lptread.c
Compile in MATLAB with mex lptread.c [-O] [-g] [-v]
For description see lptread.m
void __cdecl mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[])
double *port;
int mrows, ncols;
double *val;
/* Check for proper number of arguments. */
if (nrhs != 1) {
mexErrMsgTxt("One input argument required.");
} else if (nlhs != 1) {
mexErrMsgTxt("One output argument required.");
/* The input must be noncomplex scalar double.*/
mrows = mxGetM(prhs[0]);
ncols = mxGetN(prhs[0]);
if (!mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]) || !(mrows == 1 && ncols ==1)) {
mexErrMsgTxt("Input must be noncomplex scalar double.");
/* Assign pointers. */
plhs[0] = mxCreateScalarDouble(0);
val = mxGetPr(plhs[0]);
/* Call PortTalk. */
*val = inportb(*port);
Revision [1424]
Edited on 2008-07-21 17:32:53 by ErikFlister [added info for win64 from forum msg 9328]Additions:
- Matlab's [[http://www.mathworks.com/access/helpdesk/help/techdoc/ref/hex2dec.html hex2dec()]] is unreasonably slow and can lead to frame drops if you poll the parallel port between every flip -- cache out the dec value. [[http://www.mathworks.com/access/helpdesk/help/techdoc/ref/bin2dec.html bin2dec()]] and [[http://www.mathworks.com/access/helpdesk/help/techdoc/ref/dec2bin.html dec2bin(.,8)]] are obviously useful and fast enough (tho about twice as slow as the fastest implementation). Easy mistakes: you can only write whole bytes, not individual bits, so if you want to leave certain bits unaffected during a write, read them first. Also, to keep consistent bit locations, you want to include leading zeros, so don't forget the second argument to dec2bin.
Deletions:
Revision [1423]
Edited on 2008-07-21 17:28:44 by ErikFlister [added info for win64 from forum msg 9328]Additions:
- Be sure to use a [[http://www.winford.com/products/ext25.php straight-thru cable]], not a [[http://en.wikipedia.org/wiki/Null_modem#Null_modem_cable_pin_mapping null-modem cable]] (which often have both db-9 and db-25 connectors, and contain crossed over lines).
Deletions:
Revision [1422]
Edited on 2008-07-21 17:27:47 by ErikFlister [added info for win64 from forum msg 9328]Additions:
- Be sure to use a straight-thru cable, not a [[http://en.wikipedia.org/wiki/Null_modem#Null_modem_cable_pin_mapping null-modem cable]] (which often have both db-9 and db-25 connectors, and contain crossed over lines).
- [[http://www.winford.com/products/brk25mf.php Breakout cards with terminal blocks]] are very useful.
- [[http://www.winford.com/products/brk25mf.php Breakout cards with terminal blocks]] are very useful.
Revision [1421]
Edited on 2008-07-21 17:17:32 by ErikFlister [added info for win64 from forum msg 9328]Additions:
- Matlab's [[http://www.mathworks.com/access/helpdesk/help/techdoc/ref/hex2dec.html hex2dec()]] is unreasonably slow and can lead to frame drops if you poll the parallel port between every flip -- cache out the dec value. [[http://www.mathworks.com/access/helpdesk/help/techdoc/ref/bin2dec.html bin2dec()]] and [[http://www.mathworks.com/access/helpdesk/help/techdoc/ref/dec2bin.html dec2bin(.,8)]] are obviously useful and fast enough (tho about twice as slow as the fastest implementation).
- A good summary at [[http://en.wikipedia.org/wiki/Parallel_port wikipedia]]
- A good summary at [[http://en.wikipedia.org/wiki/Parallel_port wikipedia]]
Deletions:
Additions:
- Matlab's hex2dec() is unreasonably slow and can lead to frame drops if you poll the parallel port between every flip -- cache out the dec value. bin2dec() and dec2bin(.,8) are obviously useful and fast enough (tho about twice as slow as the fastest implementation).
Deletions:
Additions:
- Matlab's hex2dec() is unreasonably slow and can lead to frame drops if you poll the parallel port between every Flip -- cache out the dec value. bin2dec() and dec2bin(.,8) are obviously useful and fast enough (tho about twice as slow as the fastest implementation).
Deletions:
Additions:
- Matlab's hex2dec is unreasonably slow and can lead to frame drops if you poll the parallel port between every Flip -- cache out the dec value. bin2dec and dec2bin(.,8) are obviously useful and fast enough (tho about twice as slow as the fastest implementation).
Additions:
- The electrical characteristics of ports, and even pins/registers within a port, vary ([[http://www.epanorama.net/circuits/parallel_output.html ref1]] [[http://www.lvr.com/files/ibmlpt.txt ref2]]). I have the best luck with totem-pole outputs (you generally need a buffer, not just a raw transistor). The raw output of totem-pole [[http://www.optekinc.com/datasheets/OPB960-990_SERIES.PDF Optologic]] devices can be used directly.
Deletions:
Additions:
- The electrical characteristics of ports vary, and even pins/registers within a port. I have the best luck with totem pole outputs (you generally need a buffer, not just a raw transistor). The raw output of totem-pole [[http://www.optekinc.com/datasheets/OPB960-990_SERIES.PDF Optologic]] devices can be used directly.
Deletions:
No Differences
Additions:
- Matlab's data acquisition toolbox knows how to automatically read the port address from a protected area of windows memory that contains BIOS data:
Unfortunately, the data acquisition toolbox costs extra, is slower (~1ms) than lptwrite/lptread (~10us), and cannot address add-on ports (pci/pcmcia), which are a very inexpensive dio option (~US$15). Charitably, Mathworks support showed me the method they use. Use the [[http://www.internals.com/utilities_main.htm WinIO driver]] to eg determine the first parallel port base address:
-I find I have the best luck using the SPP mode setting in the BIOS, rather than ECP or EPP, especially when reading from the control register. However, note that the [[http://www.beyondlogic.org/spp/parallel.htm#11 extended control register]] under ECP is supposed to be able to set to emulate SPP (I couldn't get this to work). Note that to enable bi-directional use (reading from, in addition to writing to, the data and control registers), you must both set bit 5 (counting from zero) of the control register and set the pin you want to read from must be set to the high +5V TTL setting, counting inversions ([[http://www.beyondlogic.org/spp/parallel.htm ref]]).
- The electrical characteristics of ports vary, and even pins/registers within a port. I have the best luck with totem pole outputs (you generally need a buffer, not just a raw transistor). [[http://www.optekinc.com/datasheets/OPB960-990_SERIES.PDF Optologic]] devices are super useful.
Unfortunately, the data acquisition toolbox costs extra, is slower (~1ms) than lptwrite/lptread (~10us), and cannot address add-on ports (pci/pcmcia), which are a very inexpensive dio option (~US$15). Charitably, Mathworks support showed me the method they use. Use the [[http://www.internals.com/utilities_main.htm WinIO driver]] to eg determine the first parallel port base address:
-I find I have the best luck using the SPP mode setting in the BIOS, rather than ECP or EPP, especially when reading from the control register. However, note that the [[http://www.beyondlogic.org/spp/parallel.htm#11 extended control register]] under ECP is supposed to be able to set to emulate SPP (I couldn't get this to work). Note that to enable bi-directional use (reading from, in addition to writing to, the data and control registers), you must both set bit 5 (counting from zero) of the control register and set the pin you want to read from must be set to the high +5V TTL setting, counting inversions ([[http://www.beyondlogic.org/spp/parallel.htm ref]]).
- The electrical characteristics of ports vary, and even pins/registers within a port. I have the best luck with totem pole outputs (you generally need a buffer, not just a raw transistor). [[http://www.optekinc.com/datasheets/OPB960-990_SERIES.PDF Optologic]] devices are super useful.
Deletions:
Unfortunately, the data acquisition toolbox costs money, is slower (~1ms) than lptwrite/lptread (~10us), and cannot address add-on ports (pci/pcmcia), which are a very inexpensive dio option (~US$15). Charitably, Mathworks support showed me the method they use. Use the [[http://www.internals.com/utilities_main.htm WinIO driver]] to eg determine the first parallel port base address:
Additions:
Unfortunately, the data acquisition toolbox costs money, is slower (~1ms) than lptwrite/lptread (~10us), and cannot address add-on ports (pci/pcmcia), which are a very inexpensive dio option (~US$15). Charitably, Mathworks support showed me the method they use. Use the [[http://www.internals.com/utilities_main.htm WinIO driver]] to eg determine the first parallel port base address:
Deletions:
- Mathworks support showed me how to use the [[http://www.internals.com/utilities_main.htm WinIO driver]] to eg determine the first parallel port base address:
Additions:
- To find your port address, right click 'my computer', 'properties', 'hardware', 'device manager', 'ports (com & lpt)', double click an lpt port, 'resources', 'i/o range'. The first value listed is the port's base hex address.
Deletions:
Additions:
- To find your port address, right click 'my computer', 'properties', 'hardware', 'device manager', 'ports (com & lpt)', double click an lpt port, 'resources', 'i/o range'. The first value listed is the port's hex address.
Deletions:
Additions:
- Matlab knows how to automatically read the port address from a protected area of windows memory that contains BIOS data:
get(digitalio('parallel'),'PortAddress')
Unfortunately, the data acquisition toolbox costs money, is slower (~1ms) than lptwrite/lptread (~10us), and cannot address add-on ports (pci/pcmcia), which are a very inexpensive dio option (~US$15).
- Mathworks support showed me how to use the [[http://www.internals.com/utilities_main.htm WinIO driver]] to eg determine the first parallel port base address:
get(digitalio('parallel'),'PortAddress')
Unfortunately, the data acquisition toolbox costs money, is slower (~1ms) than lptwrite/lptread (~10us), and cannot address add-on ports (pci/pcmcia), which are a very inexpensive dio option (~US$15).
- Mathworks support showed me how to use the [[http://www.internals.com/utilities_main.htm WinIO driver]] to eg determine the first parallel port base address:
Deletions:
- Mathworks support showed me how to use the [[http://www.internals.com/utilities_main.htm WinIO driver]]. To determine the first parallel port base address:
Additions:
- You cannot prevent other processes from accessing the port. In particular, Windows periodically/unpredictably writes to the port to poll for devices, especially in the first few minutes after reboots and after you first start addressing the port. A registry key can (partially) disable this behavior ([[http://www.lvr.com/jansfaq.htm ref]]):
- To find your port address, right click 'my computer', 'properties', 'hardware', 'device manager', 'ports (com & lpt)', double click an lpt port, 'resources', 'i/o range'. The first value listed is the hex address.
- Matlab knows how to automatically read the port address from a protected area of windows memory that contains BIOS data: get(digitalio('parallel'),'PortAddress'). Unfortunately, the data acquisition toolbox costs money, is slower (~1ms) than lptwrite/lptread (~10us), and cannot address add-on ports (pci/pcmcia), which are a very inexpensive dio option (~US$15).
- Mathworks support showed me how to use the [[http://www.internals.com/utilities_main.htm WinIO driver]]. To determine the first parallel port base address:
%%(c)
bresult = GetPhysLong((PBYTE)0x0408, &port);
- To find your port address, right click 'my computer', 'properties', 'hardware', 'device manager', 'ports (com & lpt)', double click an lpt port, 'resources', 'i/o range'. The first value listed is the hex address.
- Matlab knows how to automatically read the port address from a protected area of windows memory that contains BIOS data: get(digitalio('parallel'),'PortAddress'). Unfortunately, the data acquisition toolbox costs money, is slower (~1ms) than lptwrite/lptread (~10us), and cannot address add-on ports (pci/pcmcia), which are a very inexpensive dio option (~US$15).
- Mathworks support showed me how to use the [[http://www.internals.com/utilities_main.htm WinIO driver]]. To determine the first parallel port base address:
%%(c)
bresult = GetPhysLong((PBYTE)0x0408, &port);
Deletions:
Additions:
- You cannot prevent other processes from accessing the port. In particular, Windows periodically/unpredictably writes to the port to poll for devices, especially in the first few minutes after reboots and after you first start addressing the port. A registry key can disable this behavior:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Parport\Parameters]
"DisableWarmPoll"=dword:00000001
- [[http://www.mathworks.com/products/daq/ MATLAB Data Acquisition Toolbox]] (see 'parallel port characteristics' under [[http://www.mathworks.com/access/helpdesk/help/toolbox/daq/f11-8000.html#f11-22871 'line and port characteristics']])
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Parport\Parameters]
"DisableWarmPoll"=dword:00000001
- [[http://www.mathworks.com/products/daq/ MATLAB Data Acquisition Toolbox]] (see 'parallel port characteristics' under [[http://www.mathworks.com/access/helpdesk/help/toolbox/daq/f11-8000.html#f11-22871 'line and port characteristics']])
Deletions:
Additions:
4) (Vista only) Under Vista, [[http://en.wikipedia.org/wiki/User_Account_Control UAC]] prevents PortTalk from starting. Right-click MATLAB and choose "run as administrator" to allow PortTalk to start. You don't need to do this for additional MATLAB sessions until next time you reboot. You can also turn off UAC completely in the user account control panel.
Deletions:
Additions:
4) (Vista only) To use this approach under Vista, there are two options. [[http://en.wikipedia.org/wiki/User_Account_Control UAC]] prevents PortTalk from starting. After any reboot, you can right-click matlab and choose "run as administrator" to allow PortTalk to start. You don't need to do this for additional matlab sessions until next time you reboot. You can also turn off UAC completely in the user account control panel.
Deletions:
Additions:
=== [[http://psychtoolbox.org/wikka.php?wakka=PsychtoolboxFaq FAQ]] - TTL triggers via parallel port (Win 2k/XP/Vista) ===
**Q:** How to send TTL triggers via parallel port (Win 2k/XP/Vista only)?
1) To access the parallel port under NT/2k/XP/Vista a kernel ring 0 driver is required. We use PortTalk by Craig Peacock you can download from http://www.beyondlogic.org/porttalk/porttalk.htm. Copy the porttalk.sys driver enclosed in the zip archive to your windows\system32\drivers directory. Edit the porttalk.reg file replacing "Start"=dword:00000002 by "Start"=dword:00000000 (to load the driver at boot time not constantly requiring administrative privileges). As user with administrative privileges double-click the edited porttalk.reg to write the contents into the Windows registry and reboot your machine.
4) (Vista only) To use this approach under Vista, there are two options. [[http://en.wikipedia.org/wiki/User_Account_Control UAC]] prevents porttalk from starting. After any reboot, you can right-click matlab and choose "run as administrator" to allow porttalk to start. You don't need to do this for additional matlab sessions until next time you reboot. You can also turn off UAC completely in the user account control panel.
**Q:** How to send TTL triggers via parallel port (Win 2k/XP/Vista only)?
1) To access the parallel port under NT/2k/XP/Vista a kernel ring 0 driver is required. We use PortTalk by Craig Peacock you can download from http://www.beyondlogic.org/porttalk/porttalk.htm. Copy the porttalk.sys driver enclosed in the zip archive to your windows\system32\drivers directory. Edit the porttalk.reg file replacing "Start"=dword:00000002 by "Start"=dword:00000000 (to load the driver at boot time not constantly requiring administrative privileges). As user with administrative privileges double-click the edited porttalk.reg to write the contents into the Windows registry and reboot your machine.
4) (Vista only) To use this approach under Vista, there are two options. [[http://en.wikipedia.org/wiki/User_Account_Control UAC]] prevents porttalk from starting. After any reboot, you can right-click matlab and choose "run as administrator" to allow porttalk to start. You don't need to do this for additional matlab sessions until next time you reboot. You can also turn off UAC completely in the user account control panel.
Deletions:
**Q:** How to send TTL triggers via parallel port (Win 2k/XP only)?
1) To access the parallel port under NT/2k/XP a kernel ring 0 driver is required. We use PortTalk by Craig Peacock you can download from http://www.beyondlogic.org/porttalk/porttalk.htm. Copy the porttalk.sys driver enclosed in the zip archive to your windows\system32\drivers directory. Edit the porttalk.reg file replacing "Start"=dword:00000002 by "Start"=dword:00000000 (to load the driver at boot time not constantly requiring administrative privileges). As user with administrative privileges double-click the edited porttalk.reg to write the contents into the Windows registry and reboot your machine.
Additions:
%%(matlab)
- A "lptread" counterpart for reading bytes from parallel port was contributed by Erik: http://tech.groups.yahoo.com/group/psychtoolbox/message/4851
- In case you are still using Psychtoolbox 2.54 take care to use the patched WaitSecs version available here: http://psychtoolbox.org/PTB-2/download/Win254Updates/WaitSecs254update1.zip
- First check whether pt_ioctl.c has a final newline if you experience errors while compiling lptwrite.c (http://tech.groups.yahoo.com/group/psychtoolbox/message/5130)
=== lptwrite.c ===
%%(c;lptwrite.c)
/*
lptwrite.c
Compile in MATLAB with mex lptwrite.c [-O] [-g] [-v]
For description see lptwrite.m
Copyright (C) 2006 Andreas Widmann, University of Leipzig, widmann@uni-leipzig.de
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "stdio.h"
#include "windows.h"
#include "pt_ioctl.c"
#include "mex.h"
void __cdecl mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
double *port, *value;
int mrows, ncols, arg;
/* Check for proper number of arguments. */
if (nrhs != 2) {
mexErrMsgTxt("Two input arguments required.");
} else if (nlhs > 0) {
mexErrMsgTxt("Too many output arguments.");
}
/* The input must be noncomplex scalar double.*/
for (arg = 0; arg < 2; arg++) {
mrows = mxGetM(prhs[arg]);
ncols = mxGetN(prhs[arg]);
if (!mxIsDouble(prhs[arg]) || mxIsComplex(prhs[arg]) || !(mrows == 1 && ncols == 1)) {
mexErrMsgTxt("Input must be noncomplex scalar double.");
}
}
/* Assign pointers to each input and output. */
port = mxGetData(prhs[0]);
value = mxGetData(prhs[1]);
OpenPortTalk();
outportb(*port, *value);
ClosePortTalk();
}
- A "lptread" counterpart for reading bytes from parallel port was contributed by Erik: http://tech.groups.yahoo.com/group/psychtoolbox/message/4851
- In case you are still using Psychtoolbox 2.54 take care to use the patched WaitSecs version available here: http://psychtoolbox.org/PTB-2/download/Win254Updates/WaitSecs254update1.zip
- First check whether pt_ioctl.c has a final newline if you experience errors while compiling lptwrite.c (http://tech.groups.yahoo.com/group/psychtoolbox/message/5130)
=== lptwrite.c ===
%%(c;lptwrite.c)
/*
lptwrite.c
Compile in MATLAB with mex lptwrite.c [-O] [-g] [-v]
For description see lptwrite.m
Copyright (C) 2006 Andreas Widmann, University of Leipzig, widmann@uni-leipzig.de
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "stdio.h"
#include "windows.h"
#include "pt_ioctl.c"
#include "mex.h"
void __cdecl mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
double *port, *value;
int mrows, ncols, arg;
/* Check for proper number of arguments. */
if (nrhs != 2) {
mexErrMsgTxt("Two input arguments required.");
} else if (nlhs > 0) {
mexErrMsgTxt("Too many output arguments.");
}
/* The input must be noncomplex scalar double.*/
for (arg = 0; arg < 2; arg++) {
mrows = mxGetM(prhs[arg]);
ncols = mxGetN(prhs[arg]);
if (!mxIsDouble(prhs[arg]) || mxIsComplex(prhs[arg]) || !(mrows == 1 && ncols == 1)) {
mexErrMsgTxt("Input must be noncomplex scalar double.");
}
}
/* Assign pointers to each input and output. */
port = mxGetData(prhs[0]);
value = mxGetData(prhs[1]);
OpenPortTalk();
outportb(*port, *value);
ClosePortTalk();
}
Deletions:
- In case you are still using Psychtoolbox 2.54 take care to use the patched WaitSecs version available here: http://www.psychtoolbox.org/download/Win_v2.55/prerelease_patches/WaitSecs.dll.zip
Additions:
=== [[http://psychtoolbox.org/wikka.php?wakka=PsychtoolboxFaq FAQ]] - TTL triggers via parallel port (Win 2k/XP) ===
**Q:** How to send TTL triggers via parallel port (Win 2k/XP only)?
**A:** This is only one of several possible solutions used in several labs (described first in the Psychtoolbox forum http://tech.groups.yahoo.com/group/psychtoolbox/message/4825).
2) Copy the attached C-code (also available here [[http://www.uni-leipzig.de/~biocog/widmann/matlab/lptwrite.c lptwrite.c]] with additional documentation in [[http://www.uni-leipzig.de/~biocog/widmann/matlab/lptwrite.m lptwrite.m]]), PortTalk_IOCTL.h and pt_ioctl.c (in IoExample subdirectory) from the porttalk zip archive into a directory on your machine. Change your MATLAB directory into this directory and execute "mex -v lptwrite.c" which should result in an additional file in your directory (either lptwrite.dll or lptwrite.mexw32 depending on your MATLAB version).
=== Additional information ===
=== Alternatives ===
- A similar approach was described here: http://tech.groups.yahoo.com/group/psychtoolbox/message/8032
- [[http://www.mathworks.com/products/daq/ MATLAB Data Acquisition Toolbox]]
**Q:** How to send TTL triggers via parallel port (Win 2k/XP only)?
**A:** This is only one of several possible solutions used in several labs (described first in the Psychtoolbox forum http://tech.groups.yahoo.com/group/psychtoolbox/message/4825).
2) Copy the attached C-code (also available here [[http://www.uni-leipzig.de/~biocog/widmann/matlab/lptwrite.c lptwrite.c]] with additional documentation in [[http://www.uni-leipzig.de/~biocog/widmann/matlab/lptwrite.m lptwrite.m]]), PortTalk_IOCTL.h and pt_ioctl.c (in IoExample subdirectory) from the porttalk zip archive into a directory on your machine. Change your MATLAB directory into this directory and execute "mex -v lptwrite.c" which should result in an additional file in your directory (either lptwrite.dll or lptwrite.mexw32 depending on your MATLAB version).
=== Additional information ===
=== Alternatives ===
- A similar approach was described here: http://tech.groups.yahoo.com/group/psychtoolbox/message/8032
- [[http://www.mathworks.com/products/daq/ MATLAB Data Acquisition Toolbox]]
Deletions:
2) Copy the attached C-code ([[http://www.uni-leipzig.de/~biocog/widmann/matlab/lptwrite.c lptwrite.c]]), PortTalk_IOCTL.h and pt_ioctl.c (in IoExample subdirectory) from the porttalk zip archive into a directory on your machine. Change your MATLAB directory into this directory and execute "mex -v lptwrite.c" which should result in an additional file in your directory (either lptwrite.dll or lptwrite.mexw32 depending on your MATLAB version).
===== Additional information =====