[visionegg] Triggering at the parallel port (update)
- From: Hubertus Becker <Hubertus.Becker@xxxxxxx>
- To: visionegg@xxxxxxxxxxxxx
- Date: Thu, 21 Apr 2005 22:55:39 +0200
Hi all,
unfortunately the attachment in my last email
is not visible at the mailing list side under
http://www.freelists.org/list/visionegg.
So I include it as plain text in this email.
Best,
Hubertus
================================================================
DaqLPT.py
================================================================
# The Vision Egg: DaqLPT
#
# Copyright (C) 2001-2003 Andrew Straw.
# Author: Andrew Straw <astraw@xxxxxxxxxxxxxxxxxxxxx>
# URL: <http://www.visionegg.org/>
#
# Distributed under the terms of the GNU Lesser General Public License
# (LGPL). See LICENSE.TXT that came with this file.
#
# $Id: DaqLPT.py,v 1.3 2005/04/20 17:44:15 hubertus Exp $
"""
Data acquisition and triggering over the parallel port.
This module was programmed using information from "Interfacing the
Standard Parallel Port" by Craig Peacock,
http://www.senet.com.au/~cpeacock.
You may also be interested in http://www.lvr.com/files/ibmlpt.txt.
This module only uses the Standard Parallel Port (SPP) protocol, not
ECP or EPP. You may have to set your computer's BIOS accordingly.
You may need to be root or otherwise have permission to access the
parallel port.
Example usage:
>>> from VisionEgg.DaqLPT import raw_lpt_module
>>> address = 0x378
>>> out_value = 0
>>> raw_lpt_module.out( address, out_value )
>>> in_value = raw_lpt_module.inp( address+1 )
"""
####################################################################
#
# Import all the necessary packages
#
####################################################################
import VisionEgg
import VisionEgg.Core
import VisionEgg.FlowControl
import VisionEgg.Daq
import VisionEgg.ParameterTypes as ve_types
import sys
# See the raw LPT module for your platform for direct LPT access
# without VisionEgg DAQ overhead. In particular, the inp and out
# functions are useful.
if sys.platform == 'win32':
import winioport as raw_lpt_module
elif sys.platform.startswith('linux'):
import VisionEgg._raw_lpt_linux as raw_lpt_module
elif sys.platform.startswith('irix'):
### IRIX implementation not done, but possible
raise NotImplementedError("VisionEgg.DaqLPT not implemented on IRIX")
## import VisionEgg._raw_plp_irix
## raw_lpt_module = VisionEgg._raw_plp_irix
else:
raise RuntimeError("VisionEgg.DaqLPT not supported on this platform")
__version__ = VisionEgg.release_name
__cvs__ = '$Revision: 1.3 $'.split()[1]
__date__ = ' '.join('$Date: 2005/04/20 17:44:15 $'.split()[1:3])
__author__ = 'Andrew Straw <astraw@xxxxxxxxxxxxxxxxxxxxx>'
class LPTInput(VisionEgg.Daq.Input):
def get_data(self):
"""Get status bits 0-7 of the LPT port.
The status bits were not meant for high speed digital input.
Nevertheless, for sampling one or two digital inputs at slow
rates, they work fine.
Bits 4 and 5 (pins 13 and 12, respectively) should be first
choice to sample a digital voltage. The other bits have some
oddities. Bits 0 and 1 are designated reserved. Others are
"active low"; they show a logic 0 when +5v is applied.
bit3 = value & 0x08
bit4 = value & 0x10
bit5 = value & 0x20
bit6 = value & 0x40
"""
return raw_lpt_module.inp(self.channel.device.base_address+1)
class LPTOutput(VisionEgg.Daq.Output):
def put_data(self,data):
"""Set output bits 0-7 (pins 2-9) on the LPT port."""
raw_lpt_module.out(self.channel.device.base_address,data)
def __del__(self):
"""Set output bits low when closing."""
raw_lpt_module.out(self.channel.device.base_address,0)
class LPTChannel(VisionEgg.Daq.Channel):
"""A data acquisition channel using the parallel port."""
def __init__(self,**kw):
if not 'raw_lpt_module' in globals().keys():
raise RuntimeError("LPT output not supported on this platform.")
VisionEgg.Daq.Channel.__init__(self,**kw)
signal_type = self.constant_parameters.signal_type
if not isinstance(signal_type,VisionEgg.Daq.Digital):
raise ValueError("Channel must be digital.")
daq_mode = self.constant_parameters.daq_mode
if not isinstance(daq_mode,VisionEgg.Daq.Immediate):
raise ValueError("Channel must be immediate mode.")
functionality = self.constant_parameters.functionality
if not isinstance(functionality,LPTInput):
if not isinstance(functionality,LPTOutput):
raise ValueError("Channel functionality must be instance of
LPTInput or LPTOutput.")
class LPTDevice(VisionEgg.Daq.Device):
"""A single parallel port. (Line PrinTer port.)
Typically, LPT1 has a base address of 0x0378, and LPT2 has a base
address of 0x0278."""
def __init__(self,base_address=0x378,**kw):
if not 'raw_lpt_module' in globals().keys():
raise RuntimeError("LPT output not supported on this platform.")
VisionEgg.Daq.Device.__init__(self,**kw)
for channel in self.channels:
if not isinstance(channel,LPTChannel):
raise ValueError("LPTDevice only has LPTChannels.")
self.base_address = base_address
def add_channel(self,channel):
if not isinstance(channel,LPTChannel):
raise ValueError("LPTDevice only has LPTChannels.")
VisionEgg.Daq.Device.add_channel(self,channel)
class LPTTriggerOutController(VisionEgg.FlowControl.Controller):
"""Use 8 bits of digital output for triggering and frame timing
verification.
Bit 0 (pin 2) goes high when the go loop begins and low when the
loop ends. Bits 1-7 (pins 3-9) count the frame_number (modulo
2^7) in binary. Looking at any one of these pins therefore
provides verification that your stimulus is not skipping
frames."""
def __init__(self,lpt_device=None):
if not 'raw_lpt_module' in globals().keys():
raise RuntimeError("LPT output not supported on this platform.")
VisionEgg.FlowControl.Controller.__init__(self,
return_type=ve_types.NoneType,
eval_frequency=VisionEgg.FlowControl.Controller.EVERY_FRAME)
# Initialize DAQ stuff:
self.trigger_out_channel = LPTChannel(signal_type =
VisionEgg.Daq.Digital(),
daq_mode =
VisionEgg.Daq.Immediate(),
functionality = LPTOutput())
if lpt_device is None:
self.device = LPTDevice()
else:
if not isinstance(lpt_device,LPTDevice):
raise ValueError("lpt_device must be instance of LPTDevice.")
self.device = lpt_device
self.device.add_channel(self.trigger_out_channel)
self.total_frames = 0
def during_go_eval(self):
self.total_frames = (self.total_frames + 1) % (2**7)
value = self.total_frames*2 + 1
self.trigger_out_channel.constant_parameters.functionality.put_data(value)
def between_go_eval(self):
self.total_frames = (self.total_frames + 1) % (2**7)
value = self.total_frames*2 + 0
self.trigger_out_channel.constant_parameters.functionality.put_data(value)
class LPTTriggerInController(VisionEgg.FlowControl.Controller):
def __init__(self,lpt_device=None,pin=13):
if not 'raw_lpt_module' in globals().keys():
raise RuntimeError("LPT input not supported on this platform.")
VisionEgg.FlowControl.Controller.__init__(self,
return_type=ve_types.Integer,
eval_frequency=VisionEgg.FlowControl.Controller.EVERY_FRAME)
# Initialize DAQ stuff:
self.trigger_in_channel = LPTChannel(signal_type =
VisionEgg.Daq.Digital(),
daq_mode =
VisionEgg.Daq.Immediate(),
functionality = LPTInput())
if lpt_device is None:
self.device = LPTDevice()
else:
if not isinstance(lpt_device,LPTDevice):
raise ValueError("lpt_device must be instance of LPTDevice.")
self.device = lpt_device
self.device.add_channel(self.trigger_in_channel)
if pin==15:
bit = 3
elif pin==13:
bit = 4
elif pin==12:
bit = 5
elif pin==10:
bit = 6
elif pin==11:
bit = 7
else:
raise ValueError("Only pins 10, 11, 12, 13 and 15 supported at
this time.")
self.mask = 2**bit
def during_go_eval(self):
return 1
def between_go_eval(self):
value =
self.trigger_in_channel.constant_parameters.functionality.get_data()
return (value & self.mask)
======================================
The Vision Egg mailing list
Archives: http://www.freelists.org/archives/visionegg
Website: http://www.visionegg.org/mailinglist.html
Other related posts:
- » [visionegg] Triggering at the parallel port (update)