Code Monkey home page Code Monkey logo

Comments (9)

GoogleCodeExporter avatar GoogleCodeExporter commented on September 15, 2024
I wound up writing my own ctypes-based class for accessing the digital I/O 
ports on
my NI-DAQ 6008.  I based it on the examples given in
http://www.scipy.org/Cookbook/Data_Acquisition_with_NIDAQmx and the C code 
provided
with the NIDAQmx 9.0.2 driver.  As seen in the example python code at 
scipy.org, it
uses nicaiu.dll to access the hardware.  The code was tested and it seems to 
work for
what I'm trying to do:

"""
This is an interpretation of the example program
C:\Documents and Settings\All Users\Documents\National
Instruments\NI-DAQ\Examples\DAQmx ANSI C\Digital\Generate Values\Write Dig
Chan\WriteDigChan.c
This routine allows you to access and set the digital output ports.
This module depends on:
numpy
Adapted by Martin Bures [ mbures { @ } zoll { . } com ]
Re-adapted by Matthew Last [ mlast { @ } trexenterprises { . } com]
"""
# import system libraries
import ctypes
import numpy as np

# load DLL
nidaq = ctypes.windll.nicaiu # load the DLL
##############################
# Setup some typedefs and constants
# to correspond with values in
# C:\Program Files\National Instruments\NI-DAQ\DAQmx ANSI C 
Dev\include\NIDAQmx.h
# the typedefs

uint8 = ctypes.c_uint8
uInt32 = ctypes.c_ulong
uInt64 = ctypes.c_ulonglong
float64 = ctypes.c_double
TaskHandle = uInt32
# the constants
DAQmx_Val_ChanForAllLines = 1
DAQmx_Val_GroupByChannel = 0

class Ports( threading.Thread ):
    """
    This class performs the necessary initialization of the DAQ hardware and
    initializes the digital lines to low (digital 0)
    """
    def __init__( self ):
        self.port0 = [0,0,0,0,0,0,0,0]
        self.port1 = [0,0,0,0]

        self.taskHandle0 = TaskHandle( 0 )
        self.taskHandle1 = TaskHandle( 0 )

        # setup the DAQ hardware for port0 and port1
        self.CHK(nidaq.DAQmxCreateTask("",
                          ctypes.byref( self.taskHandle0 )))
        self.CHK(nidaq.DAQmxCreateTask("",
                          ctypes.byref( self.taskHandle1 )))

        self.CHK(nidaq.DAQmxCreateDOChan( self.taskHandle0,
                                   "Dev1/port0/line0:7",
                                   "",
                                   DAQmx_Val_ChanForAllLines))
        self.CHK(nidaq.DAQmxCreateDOChan( self.taskHandle1,
                                   "Dev1/port1/line0:3",
                                   "",
                                   DAQmx_Val_ChanForAllLines))

        self.run(self.taskHandle0)
        self.run(self.taskHandle1)

        # Initialize digital ports
        self.update( port0 = self.port0, port1 = self.port1)

    def CHK( self, err ):
        """a simple error checking routine"""
        if err < 0:
            buf_size = 100
            buf = ctypes.create_string_buffer('\000' * buf_size)
            nidaq.DAQmxGetErrorString(err,ctypes.byref(buf),buf_size)
            raise RuntimeError('nidaq call failed with error %d:
%s'%(err,repr(buf.value)))
        if err > 0:
            buf_size = 100
            buf = ctypes.create_string_buffer('\000' * buf_size)
            nidaq.DAQmxGetErrorString(err,ctypes.byref(buf),buf_size)
            raise RuntimeError('nidaq generated warning %d: %s'%(err,repr(buf.value)))

    def run( self, taskHandle ):
        self.CHK(nidaq.DAQmxStartTask( taskHandle ))

    def stop( self ):
        nidaq.DAQmxStopTask( self.taskHandle0 )
        nidaq.DAQmxClearTask( self.taskHandle0 )

    def update(self, port0 = [0,0,0,0,0,0,0,0], port1 = [0,0,0,0]):
        if len(port0) != 8:
            raise ValueError('port0 argument must have 8 values')
        if len(port1) != 4:
            raise ValueError('port1 argument must have 4 values')

        for i in range(len(port0)):
            self.port0data[i] = port0[i]
        for i in range(len(port1)):
            self.port1data[i] = port1[i]
        self.CHK(nidaq.DAQmxWriteDigitalLines( self.taskHandle0,
                              1, 1, float64(10.0),
                              DAQmx_Val_GroupByChannel,
                              self.port0data.ctypes.data,
                              None,
                              None))
        self.CHK(nidaq.DAQmxWriteDigitalLines( self.taskHandle1,
                              1, 1, float64(10.0),
                              DAQmx_Val_GroupByChannel,
                              self.port1data.ctypes.data,
                              None,
                              None))

Original comment by [email protected] on 3 Dec 2009 at 1:04

from pylibnidaqmx.

GoogleCodeExporter avatar GoogleCodeExporter commented on September 15, 2024
I lie!  It doesn't work.  I removed some critical pieces during my code cleanup 
just
before I posted.  Here's the really truly tested and working code:

"""
This is an interpretation of the example program
C:\Documents and Settings\All Users\Documents\National
Instruments\NI-DAQ\Examples\DAQmx ANSI C\Digital\Generate Values\Write Dig
Chan\WriteDigChan.c
This routine allows you to access and set the digital output ports.
This module depends on:
numpy
Adapted by Martin Bures [ mbures { @ } zoll { . } com ]
Re-adapted by Matthew Last [ mlast { @ } trexenterprises { . } com]
"""
# import system libraries
import ctypes
import numpy as np

# load DLL
nidaq = ctypes.windll.nicaiu # load the DLL
##############################
# Setup some typedefs and constants
# to correspond with values in
# C:\Program Files\National Instruments\NI-DAQ\DAQmx ANSI C 
Dev\include\NIDAQmx.h
# the typedefs

uint8 = ctypes.c_uint8
uInt32 = ctypes.c_ulong
uInt64 = ctypes.c_ulonglong
float64 = ctypes.c_double
TaskHandle = uInt32
# the constants
DAQmx_Val_ChanForAllLines = 1
DAQmx_Val_GroupByChannel = 0

class Ports( object ):
    """
    This class performs the necessary initialization of the DAQ hardware and
    initializes the digital lines to low (digital 0)
    """
    def __init__( self ):
        self.port0 = [0,0,0,0,0,0,0,0]
        self.port1 = [0,0,0,0]
        self.port0data = np.zeros((8,), np.uint8 )
        self.port1data = np.zeros((4,), np.uint8 )

        self.taskHandle0 = TaskHandle( 0 )
        self.taskHandle1 = TaskHandle( 0 )

        # setup the DAQ hardware for port0 and port1
        self.CHK(nidaq.DAQmxCreateTask("",
                          ctypes.byref( self.taskHandle0 )))
        self.CHK(nidaq.DAQmxCreateTask("",
                          ctypes.byref( self.taskHandle1 )))

        self.CHK(nidaq.DAQmxCreateDOChan( self.taskHandle0,
                                   "Dev1/port0/line0:7",
                                   "",
                                   DAQmx_Val_ChanForAllLines))
        self.CHK(nidaq.DAQmxCreateDOChan( self.taskHandle1,
                                   "Dev1/port1/line0:3",
                                   "",
                                   DAQmx_Val_ChanForAllLines))

        self.run(self.taskHandle0)
        self.run(self.taskHandle1)

        # Initialize digital ports
        self.update( port0 = self.port0, port1 = self.port1)

    def CHK( self, err ):
        """a simple error checking routine"""
        if err < 0:
            buf_size = 100
            buf = ctypes.create_string_buffer('\000' * buf_size)
            nidaq.DAQmxGetErrorString(err,ctypes.byref(buf),buf_size)
            raise RuntimeError('nidaq call failed with error %d:
%s'%(err,repr(buf.value)))
        if err > 0:
            buf_size = 100
            buf = ctypes.create_string_buffer('\000' * buf_size)
            nidaq.DAQmxGetErrorString(err,ctypes.byref(buf),buf_size)
            raise RuntimeError('nidaq generated warning %d: %s'%(err,repr(buf.value)))

    def run( self, taskHandle ):
        self.CHK(nidaq.DAQmxStartTask( taskHandle ))

    def stop( self ):
        nidaq.DAQmxStopTask( self.taskHandle0 )
        nidaq.DAQmxClearTask( self.taskHandle0 )

    def update(self, port0 = [0,0,0,0,0,0,0,0], port1 = [0,0,0,0]):
        if len(port0) != 8:
            raise ValueError('port0 argument must have 8 values')
        if len(port1) != 4:
            raise ValueError('port1 argument must have 4 values')

        for i in range(len(port0)):
            self.port0data[i] = port0[i]
        for i in range(len(port1)):
            self.port1data[i] = port1[i]
        self.CHK(nidaq.DAQmxWriteDigitalLines( self.taskHandle0,
                              1, 1, float64(10.0),
                              DAQmx_Val_GroupByChannel,
                              self.port0data.ctypes.data,
                              None,
                              None))
        self.CHK(nidaq.DAQmxWriteDigitalLines( self.taskHandle1,
                              1, 1, float64(10.0),
                              DAQmx_Val_GroupByChannel,
                              self.port1data.ctypes.data,
                              None,
                              None))

Original comment by [email protected] on 3 Dec 2009 at 1:19

from pylibnidaqmx.

GoogleCodeExporter avatar GoogleCodeExporter commented on September 15, 2024
[deleted comment]

from pylibnidaqmx.

GoogleCodeExporter avatar GoogleCodeExporter commented on September 15, 2024
I'm also trying to get this to work on windows as well as linux. Here's a first 
patch 
for windows work: test for platform and load windows dll if on win32.  

Should probably specify NIDAQmx.h in setup.cfg, but here just change it to 
where it 
is on my system.
105,113c105
< if sys.platform == 'win32':
<     try:
<         libnidaqmx = ctypes.windll.nicaiu # load the DLL
<     except WindowsError as err:
<         print "Trying to load the national instruments DAQmx dll library on 
windows 
but can't find the nicaiu.dll.  Is it on the PATH? Is NI-DAQmx installed?"
<         raise
< else: 
<     # default: assume we are on linux
<     lib = ctypes.util.find_library('nidaqmx')
---
> lib = ctypes.util.find_library('nidaqmx')
115,116c107,108
<     if lib is None:
<         raise ImportError('Failed to find NI-DAQmx library. Make sure that 
libnidaqmx is installed and its location is listed in PATH|LD_LIBRARY_PATH|..')
---
> if lib is None:
>     raise ImportError('Failed to find NI-DAQmx library. Make sure that 
libnidaqmx 
is installed and its location is listed in PATH|LD_LIBRARY_PATH|..')
118c110
<     libnidaqmx = ctypes.cdll.LoadLibrary(lib)
---
> libnidaqmx = ctypes.cdll.LoadLibrary(lib)
151,152c143
<     #include_nidaqmx_h = '/usr/local/include/NIDAQmx.h'
<     include_nidaqmx_h = r'c:/Programs/NationaInstruments/NI-DAQ/DAQmx ANSI C 
Dev/include/NIDAQmx.h'
---
>     include_nidaqmx_h = '/usr/local/include/NIDAQmx.h'


Original comment by [email protected] on 23 Dec 2009 at 8:25

Attachments:

from pylibnidaqmx.

GoogleCodeExporter avatar GoogleCodeExporter commented on September 15, 2024
Sorry for long delay in responding (I must create issues ml..).

I have commited a patch that adds Windows support to pylibnidaqmx.
The patch is derived from comment #4 but is not tested (users may need
to update include_nidaqmx_h string).
Please report any issues.

Original comment by pearu.peterson on 8 Jan 2010 at 8:43

from pylibnidaqmx.

GoogleCodeExporter avatar GoogleCodeExporter commented on September 15, 2024
Thank you Pearu.
I've now done some tests with r27 with windows xp and NI-DAQmx 8.8 and 9.0. I 
believe 
the only change that needs to be done is to point to where my include file is 
kept.
I also need to becareful that I don't try to start a task if auto_start=True is 
specified during a write() as this raises an error.

The on demand DigitalOutTask task works
The buffered write with internal clock timing works with the AnalogOutTask
and I can trigger the AnalogOutTask using an analog trigger. 


The test acquisition script doesn't work on my system, but I haven't looked yet 
into 
why. 

Original comment by [email protected] on 11 Feb 2010 at 1:19

from pylibnidaqmx.

GoogleCodeExporter avatar GoogleCodeExporter commented on September 15, 2024
On above comment I meant to say that it applied to revision 26 not r27

Original comment by [email protected] on 11 Feb 2010 at 1:21

from pylibnidaqmx.

GoogleCodeExporter avatar GoogleCodeExporter commented on September 15, 2024
It seems that your include file

  c:/Programs/NationaInstruments/NI-DAQ/DAQmx ANSI C 
Dev/include/NIDAQmx.h

is in a non-standard place and, in general, its location cannot be
determined automatically. The path

  C:\Program Files\National Instruments\NI-DAQ\DAQmx ANSI C Dev\include\NIDAQmx.h

seems more reasonable as a standard path.
Anyway, now the trunk has all NI-DAQ defines for 9.0.x version in a .py and the
include file is not used anymore.

I am closing this issue as fixed. If you find other problems, please report 
them as
separate issues.

Original comment by pearu.peterson on 12 Feb 2010 at 7:39

  • Changed state: Fixed

from pylibnidaqmx.

GoogleCodeExporter avatar GoogleCodeExporter commented on September 15, 2024
I agree about the include file.  Perhaps I can come up a with a patch to allow 
the 
setting of the include file location in setup.cfg.

Original comment by [email protected] on 12 Feb 2010 at 6:46

from pylibnidaqmx.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.