-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
All files compatible with Python 2 and Python 3 (remove 2to3)
- Loading branch information
Showing
17 changed files
with
438 additions
and
437 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,47 +1,47 @@ | ||
import weakref | ||
import DAQmxConfig | ||
|
||
""" This package import helper functions to pass data to call back functions | ||
See examples | ||
""" | ||
|
||
#if DAQmxConfig.NIDAQmxBase: | ||
# raise NotImplementedError, 'Call back function are not available with the NIDAQmxBase driver' | ||
|
||
# NIDAQmx allow to pass a pointer to a data structure in callback function | ||
# If this function is implemented in Python, we would like this data to be a Python object. | ||
# This object will not (and will not) be used in C but we want to pass a reference to it. | ||
# A workaround is to use the weakref module | ||
# | ||
# Define a weakref dictionnary to be able to remember objects and retrieve them by ID | ||
_id2obj_dict = weakref.WeakValueDictionary() | ||
|
||
def create_callbackdata_id(obj): | ||
""" | ||
Uses the weakref module to create and store a reference to obj | ||
output value: reference to the object | ||
It is not possible to directly uses python object through a Callback function because | ||
with ctypes there is no pointer to python object. | ||
This function store in a dictionary a reference to an object | ||
This object can be retrieved using the get_callbackdata_from_id function | ||
For python object that cannot be weakreferenced, one can creat a dummy class to wrap | ||
the python object : | ||
def MyList(list) | ||
pass | ||
data = MyList() | ||
id = create_callbackdata_id(data) | ||
""" | ||
oid = id(obj) | ||
_id2obj_dict[oid] = obj | ||
return oid | ||
|
||
def get_callbackdata_from_id(oid): | ||
"""Retrieve an object stored using create_callbackdata_id | ||
""" | ||
return _id2obj_dict[oid] | ||
import weakref | ||
from . import DAQmxConfig | ||
|
||
""" This package import helper functions to pass data to call back functions | ||
See examples | ||
""" | ||
|
||
#if DAQmxConfig.NIDAQmxBase: | ||
# raise NotImplementedError, 'Call back function are not available with the NIDAQmxBase driver' | ||
|
||
# NIDAQmx allow to pass a pointer to a data structure in callback function | ||
# If this function is implemented in Python, we would like this data to be a Python object. | ||
# This object will not (and will not) be used in C but we want to pass a reference to it. | ||
# A workaround is to use the weakref module | ||
# | ||
# Define a weakref dictionnary to be able to remember objects and retrieve them by ID | ||
_id2obj_dict = weakref.WeakValueDictionary() | ||
|
||
def create_callbackdata_id(obj): | ||
""" | ||
Uses the weakref module to create and store a reference to obj | ||
output value: reference to the object | ||
It is not possible to directly uses python object through a Callback function because | ||
with ctypes there is no pointer to python object. | ||
This function store in a dictionary a reference to an object | ||
This object can be retrieved using the get_callbackdata_from_id function | ||
For python object that cannot be weakreferenced, one can creat a dummy class to wrap | ||
the python object : | ||
def MyList(list) | ||
pass | ||
data = MyList() | ||
id = create_callbackdata_id(data) | ||
""" | ||
oid = id(obj) | ||
_id2obj_dict[oid] = obj | ||
return oid | ||
|
||
def get_callbackdata_from_id(oid): | ||
"""Retrieve an object stored using create_callbackdata_id | ||
""" | ||
return _id2obj_dict[oid] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,88 +1,88 @@ | ||
import PyDAQmx | ||
from PyDAQmx import Task, DAQmxResetDevice, int32 | ||
from ctypes import byref | ||
import numpy | ||
|
||
|
||
class AIParameters(object): | ||
limits = (-10, 10) | ||
physicalChannel = ["/Dev1/ai0"] | ||
|
||
def __init__(self, sample_rate, sample_number, channels=None, limits=None): | ||
self.sampleRate = sample_rate | ||
self.sampleNumber = sample_number | ||
if limits is None: | ||
limits = self.limits | ||
self.limit_inf= limits[0] | ||
self.limit_sup= limits[1] | ||
if channels is not None: | ||
if type(channels) is str: | ||
physicalChannel = [channels] | ||
self.physicalChannel = channels | ||
|
||
@property | ||
def device_name(self): | ||
device_name = self.physicalChannel[0].split('/')[0] | ||
if device_name == '' : | ||
device_name = self.physicalChannel[0].split('/')[1] | ||
return device_name | ||
|
||
class Trigger(object): | ||
def __init__(self, terminal): | ||
self.terminal = terminal | ||
|
||
class RisingTrigger(Trigger): | ||
direction = PyDAQmx.DAQmx_Val_Rising | ||
|
||
class FallingTrigger(Trigger): | ||
direction = PyDAQmx.DAQmx_Val_Falling | ||
|
||
|
||
class AIVoltageChan(Task): | ||
def __init__(self, ai_param, reset=True, terminalConfig=PyDAQmx.DAQmx_Val_RSE, trigger=None): | ||
if reset: | ||
DAQmxResetDevice(ai_param.device_name) | ||
super(AIVoltageChan, self).__init__() | ||
self.sampleNumber = ai_param.sampleNumber | ||
self.sampleRate = ai_param.sampleRate | ||
self.limit_inf = ai_param.limit_inf | ||
self.limit_sup = ai_param.limit_sup | ||
self.physicalChannel = ai_param.physicalChannel | ||
self.numberOfChannel = len(ai_param.physicalChannel) | ||
if isinstance(terminalConfig, basestring): | ||
terminalConfig = getattr(PyDAQmx, terminalConfig) | ||
self.terminalConfig = terminalConfig | ||
self.trigger = trigger | ||
self.configure() | ||
def configure(self): | ||
channel_string = ','.join(self.physicalChannel) | ||
self.CreateAIVoltageChan(channel_string,"",self.terminalConfig, | ||
self.limit_inf,self.limit_sup, | ||
PyDAQmx.DAQmx_Val_Volts,None) | ||
def start(self): | ||
n = self.sampleNumber | ||
sampleRate = self.sampleRate | ||
self.CfgSampClkTiming("",sampleRate,PyDAQmx.DAQmx_Val_Rising,PyDAQmx.DAQmx_Val_FiniteSamps,n) | ||
if self.trigger is not None: | ||
self.CfgDigEdgeRefTrig(self.trigger.terminal,self.trigger.direction,10) | ||
self.StartTask() | ||
def read(self): | ||
n = self.sampleNumber | ||
data = numpy.zeros((n,self.numberOfChannel), dtype=numpy.float64) | ||
read = int32() | ||
self.ReadAnalogF64(n,10.0,PyDAQmx.DAQmx_Val_GroupByScanNumber,data,n*self.numberOfChannel,byref(read),None) | ||
return data | ||
def stop(self): | ||
self.StopTask() | ||
def wait(self, timeout=10): | ||
self.WaitUntilTaskDone(timeout) | ||
|
||
|
||
if __name__=="__main__": | ||
ai = AIVoltageChan(ai_param=AIParameters(100000, 10000, ['/dev1/ai0', '/dev1/ai1']), | ||
terminalConfig="DAQmx_Val_PseudoDiff", | ||
trigger=RisingTrigger('/dev1/PFI0')) | ||
ai.start() | ||
ai.wait() | ||
ai.read() | ||
ai.stop() | ||
import PyDAQmx | ||
from PyDAQmx import Task, DAQmxResetDevice, int32 | ||
from ctypes import byref | ||
import numpy | ||
|
||
|
||
class AIParameters(object): | ||
limits = (-10, 10) | ||
physicalChannel = ["/Dev1/ai0"] | ||
|
||
def __init__(self, sample_rate, sample_number, channels=None, limits=None): | ||
self.sampleRate = sample_rate | ||
self.sampleNumber = sample_number | ||
if limits is None: | ||
limits = self.limits | ||
self.limit_inf= limits[0] | ||
self.limit_sup= limits[1] | ||
if channels is not None: | ||
if type(channels) is str: | ||
physicalChannel = [channels] | ||
self.physicalChannel = channels | ||
|
||
@property | ||
def device_name(self): | ||
device_name = self.physicalChannel[0].split('/')[0] | ||
if device_name == '' : | ||
device_name = self.physicalChannel[0].split('/')[1] | ||
return device_name | ||
|
||
class Trigger(object): | ||
def __init__(self, terminal): | ||
self.terminal = terminal | ||
|
||
class RisingTrigger(Trigger): | ||
direction = PyDAQmx.DAQmx_Val_Rising | ||
|
||
class FallingTrigger(Trigger): | ||
direction = PyDAQmx.DAQmx_Val_Falling | ||
|
||
|
||
class AIVoltageChan(Task): | ||
def __init__(self, ai_param, reset=True, terminalConfig=PyDAQmx.DAQmx_Val_RSE, trigger=None): | ||
if reset: | ||
DAQmxResetDevice(ai_param.device_name) | ||
super(AIVoltageChan, self).__init__() | ||
self.sampleNumber = ai_param.sampleNumber | ||
self.sampleRate = ai_param.sampleRate | ||
self.limit_inf = ai_param.limit_inf | ||
self.limit_sup = ai_param.limit_sup | ||
self.physicalChannel = ai_param.physicalChannel | ||
self.numberOfChannel = len(ai_param.physicalChannel) | ||
if isinstance(terminalConfig, str): | ||
terminalConfig = getattr(PyDAQmx, terminalConfig) | ||
self.terminalConfig = terminalConfig | ||
self.trigger = trigger | ||
self.configure() | ||
def configure(self): | ||
channel_string = ','.join(self.physicalChannel) | ||
self.CreateAIVoltageChan(channel_string,"",self.terminalConfig, | ||
self.limit_inf,self.limit_sup, | ||
PyDAQmx.DAQmx_Val_Volts,None) | ||
def start(self): | ||
n = self.sampleNumber | ||
sampleRate = self.sampleRate | ||
self.CfgSampClkTiming("",sampleRate,PyDAQmx.DAQmx_Val_Rising,PyDAQmx.DAQmx_Val_FiniteSamps,n) | ||
if self.trigger is not None: | ||
self.CfgDigEdgeRefTrig(self.trigger.terminal,self.trigger.direction,10) | ||
self.StartTask() | ||
def read(self): | ||
n = self.sampleNumber | ||
data = numpy.zeros((n,self.numberOfChannel), dtype=numpy.float64) | ||
read = int32() | ||
self.ReadAnalogF64(n,10.0,PyDAQmx.DAQmx_Val_GroupByScanNumber,data,n*self.numberOfChannel,byref(read),None) | ||
return data | ||
def stop(self): | ||
self.StopTask() | ||
def wait(self, timeout=10): | ||
self.WaitUntilTaskDone(timeout) | ||
|
||
|
||
if __name__=="__main__": | ||
ai = AIVoltageChan(ai_param=AIParameters(100000, 10000, ['/dev1/ai0', '/dev1/ai1']), | ||
terminalConfig="DAQmx_Val_PseudoDiff", | ||
trigger=RisingTrigger('/dev1/PFI0')) | ||
ai.start() | ||
ai.wait() | ||
ai.read() | ||
ai.stop() |
Oops, something went wrong.