'''
It is possible to control the DAQ card without nidaqmx. To do so
the ANSI C DAQmx library can be loaded directly using ctypes. Note that
this method adds a lot of data typing headaches.
This is a port to Python of the ANSI C DAQmx example Cont Acq-Int Clk.c
'''
import ctypes
import numpy
import pylab as pl
import time
import fltk
#Cross platform getch
# See: http://code.activestate.com/recipes/134892/
try :
import msvcrt
getch = msvcrt.getch
except ImportError:
import sys, tty, termios
def getch() :
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
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
int32 = ctypes.c_long
uInt32 = ctypes.c_ulong
uInt64 = ctypes.c_ulonglong
float64 = ctypes.c_double
TaskHandle = uInt32
# the constants
DAQmx_Val_Cfg_Default = int32(-1)
DAQmx_Val_Volts = 10348
DAQmx_Val_Rising = 10280
DAQmx_Val_GroupByChannel = 0
DAQmx_Val_FiniteSamps = 10178 # Finite Samples
DAQmx_Val_ContSamps = 10123 # Continuous Samples
DAQmx_Val_HWTimedSinglePoint= 12522 # Hardware Timed Single Point
#*** Values for the everyNsamplesEventType parameter of DAQmxRegisterEveryNSamplesEvent ***
DAQmx_Val_Acquired_Into_Buffer = 1 # Acquired Into Buffer
DAQmx_Val_Transferred_From_Buffer = 2 # Transferred From Buffer
#*** Values for the Fill Mode parameter of DAQmxReadAnalogF64, DAQmxReadBinaryI16, DAQmxReadBinaryU16, DAQmxReadBinaryI32, DAQmxReadBinaryU32,
# DAQmxReadDigitalU8, DAQmxReadDigitalU32, DAQmxReadDigitalLines ***
#*** Values for the Data Layout parameter of DAQmxWriteAnalogF64, DAQmxWriteBinaryI16, DAQmxWriteDigitalU8, DAQmxWriteDigitalU32, DAQmxWriteDigitalLines ***
DAQmx_Val_GroupByChannel = 0 # Group by Channel
DAQmx_Val_GroupByScanNumber = 1 # Group by Scan Number
##############################
def CHK(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)))
#*********************************************/
# Callback Functions
# See: http://docs.python.org/library/ctypes.html#callback-functions
#*********************************************/
myCnt = 0
# return type, and then arg types
EVERYNFUNC = ctypes.CFUNCTYPE(int32, TaskHandle, int32, uInt32, ctypes.c_void_p)
def EveryNCallback(taskHandle, everyNsamplesEventType, nSamples, callbackData) :
data = numpy.zeros((1000,),dtype=numpy.float64)
read = int32()
CHK(nidaq.DAQmxReadAnalogF64(taskHandle,1000,
float64(10.0),DAQmx_Val_GroupByScanNumber,data.ctypes.data,
1000,ctypes.byref(read),None));
if read > 0 :
global myCnt
myCnt += 1
print "%d: Acquired %d samples." % (myCnt,read.value)
return 0
#and the callback function
# This can not be inlined into the function call!
EveryNCallback_func = EVERYNFUNC(EveryNCallback)
DONEFUNC = ctypes.CFUNCTYPE(int32, TaskHandle, int32, ctypes.c_void_p)
def DoneCallback(taskHandle, status, callbackData) :
CHK( status )
return 0;
#and the callback function
DoneCallback_func = DONEFUNC(DoneCallback)
#*********************************************/
# DAQmx Configure Code
#*********************************************/
taskHandle = TaskHandle(0)
CHK(nidaq.DAQmxCreateTask("",ctypes.byref(taskHandle)))
CHK(nidaq.DAQmxCreateAIVoltageChan(taskHandle,"Dev1/ai0","",
DAQmx_Val_Cfg_Default,
float64(-10.0),float64(10.0),
DAQmx_Val_Volts, None));
CHK(nidaq.DAQmxCfgSampClkTiming(taskHandle,"",float64(10000.0),
DAQmx_Val_Rising,DAQmx_Val_ContSamps,
uInt64(1000)))
CHK(nidaq.DAQmxRegisterEveryNSamplesEvent(taskHandle,
DAQmx_Val_Acquired_Into_Buffer,1000,0,
EveryNCallback_func,0))
CHK(nidaq.DAQmxRegisterDoneEvent(taskHandle,0,DoneCallback_func,None));
#*********************************************/
# DAQmx Start Code
#*********************************************/
CHK(nidaq.DAQmxStartTask(taskHandle));
print "Acquiring samples continuously. Press Enter to interrupt";
while True :
x = getch()
if x :
break
else :
time.sleep(0.1)