LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Need help writing script for Digital DAQ

Hello,

 

I am trying to write an aquisition program for digital input coming from a hall sensor.  I will be passing a magnet over a hall sensor on a motor and want to record the number of rotations.  I have pasted together a script based on various websites, but it isn't functioning the way I want.  I would like to be able to collect data points indefinately, or fixed, and then print out the resulting count.  I have attepted to use the ctypes wrapper in Python.  The NI functions remain unchanged though, so if you don't know Python it shouldn't be a problem to read.  I am using a NI PCI-6503. 

NI PCI-6503

NI PCI-6503

NI PCI-6503

 

The code:

 

# C:\Program Files\National Instruments\NI-DAQ\Examples\DAQmx ANSI C\Analog In\Measure Voltage\Acq-Int Clk\Acq-IntClk.c
import ctypes
import numpy
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_ChanForAllLines = int32(0)

 

##############################

def CHK(err):
"""a simple error checking routine"""
     if err < 0:
          buf_size = 200
          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)))

 

# initialize variables

taskHandle = TaskHandle(0)
max_num_samples = 1000

 

# array to gather points
data = numpy.zeros((max_num_samples,),dtype=numpy.float64)


# now, on with the program
CHK(nidaq.DAQmxCreateTask("",ctypes.byref(taskHandle)))

CHK(nidaq.DAQmxCreateDIChan(taskHandle,'Dev1/port1/line1',"", DAQmx_Val_ChanForAllLines))

CHK(nidaq.DAQmxStartTask(taskHandle))
read = int32()
CHK(nidaq.DAQmxReadDigitalU32(taskHandle,int32(-1),float64(1),DAQmx_Val_GroupByChannel,data.ctypes.data,max_num_samples,ctypes.byref(read),None))

 

print "Acquired %d points"%(read.value)

 

if taskHandle.value != 0:
     nidaq.DAQmxStopTask(taskHandle)
     nidaq.DAQmxClearTask(taskHandle)

 

print "End of program, press Enter key to quit"
raw_input()

 

 

This script returns "Acquired 1 points" immediately, regardless of how many times the hall sensor has been switched.  

I apologize for the sloppy code, but I understand very little of the underlying principles of these DAQ functions, despite reading their documentation.  Seeing as how the code does not return an error, I am hoping there is just a minor tweak or two that will be farily obvious to someone with more experience.  

 

Thanks

0 Kudos
Message 1 of 7
(3,398 Views)

Hello

 

I don't understand much of Python, but the error might be on how you are updating your read array with values. What does the line read = int32()do? Are you assigning it the value of a function, or is it a declaration?

 

Notice that on the DAQmx example ReadDigChan.c (Start » Programs » National Instruments » NI-DAQ » Text-Based Code Support Digital » Read Values) we acquire 100 values and write them to "data", our read array. In the example, we read the samples using the function

 

printf("Data acquired, channel %d: 0x%X\n",i,data[i]);

 

You are missing printing out the data that holds the actual read values, in the example’s case, data[i]. I hope this helps.

Regards,
Daniel REDS
RF Systems Engineer

Help us grow.
If a post solves your question, mark it as The Solution.
If a post helps, give Kudos to it.
0 Kudos
Message 2 of 7
(3,377 Views)

Hello and thanks for the reply.  

 

So the read variable, from what I can tell, hold hows many points were returned by the function.  That is why read.value always is returning 1.  I think this is what is happening.  Also, yes, printing data[0], displayed the value returned by the read function.  Subsequent calls to the functions did not accumulate new points into the array though.  For example, after three calls to the read function, the array 'data', looks like this: [1,,,,,,], instead of this [1,1,1,,,,].

My hardware doesn't do timing, so time functions are not accepted, and that is why I figured if I just ran the read function in a loop, the values would accumulate in the 'data' array, which they didn't.  Do you know why this might be?

 

Thanks again,

Paul

0 Kudos
Message 3 of 7
(3,359 Views)
Hello, Looking at the example, on the DAQmxRead function, I see that the read parameter, which is ultimately the variable that prints out the data, is called as a pointer &read.


/*********************************************/
// DAQmx Read Code
/*********************************************/
DAQmxErrChk (DAQmxReadDigitalLines(taskHandle,1,10.0,DAQmx_Val_GroupByChannel,data,100,&read,&bytesPerSamp,NULL));
// assuming 8 channels acquired
for(Samp2Read=0;Samp2Read<2;Samp2Read++){
for(i=0;i<8;++i)
printf("Data acquired, channel %d: 0x%X\n",i,data[i]);
printf("read= %d",read);
Sleep(1000);
}


On your code I see

CHK(nidaq.DAQmxReadDigitalU32(taskHandle,int32(-1),float64(1),DAQmx_Val_GroupByChannel,data.ctypes.data,max_num_samples,ctypes.byref(read),None))


Are you setting the parameter as a pointer?

Regards,
Daniel REDS
RF Systems Engineer

Help us grow.
If a post solves your question, mark it as The Solution.
If a post helps, give Kudos to it.
0 Kudos
Message 4 of 7
(3,331 Views)

Thank you for the reply.  I decided just to run the function in a Python loop and collect the each value in a list.  I worked out well.  Thank you for your help though.

 

Paul

0 Kudos
Message 5 of 7
(3,315 Views)

Hi Paul,

 

I'm glad it's working. In case anyone else has this problem in the future, could you post your working Python code here? Thanks for making our community grow.

Regards,
Daniel REDS
RF Systems Engineer

Help us grow.
If a post solves your question, mark it as The Solution.
If a post helps, give Kudos to it.
0 Kudos
Message 6 of 7
(3,284 Views)

Hey Daniel,

 

Most of this script is from http://www.scipy.org/Cookbook/Data_Acquisition_with_NIDAQmx. 

I needed to run the ReadDigitalU32 function in Python loop because my DAQ device did not support timed aquistion and I don't have LabView.  

 

 

import numpy
import time
import ctypes

 

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_FiniteSamps = 10178
DAQmx_Val_GroupByChannel = 0
DAQmx_Val_ChanForAllLines = int32(0)

# initialize variables
taskHandle = TaskHandle(0)
max_num_samples = 10000
data = numpy.zeros((max_num_samples,),dtype=numpy.float64)
read = uInt32()
bufferSize = uInt32(10000)

 

def CHK(err):
"""a simple error checking routine"""
     if err < 0:
          buf_size = 200
          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)))

 

# Start up DAQ
CHK(nidaq.DAQmxCreateTask("",ctypes.byref(taskHandle)))
CHK(nidaq.DAQmxCreateDIChan(taskHandle,"Dev?/port?/line?","", DAQmx_Val_ChanForAllLines))
CHK(nidaq.DAQmxStartTask(taskHandle))

 

#initialize lists and time 1 

t1 = time.time()
times = []
points = []

 

while True:
     try:
          CHK(nidaq.DAQmxReadDigitalU32(taskHandle,int32(-1),float64(1),
          DAQmx_Val_GroupByChannel,data.ctypes.data,uInt32(2*bufferSize.value)
         ,ctypes.byref(read), None))

 

          t2 = time.time()
         #data[0] is the position in the numpy array 'data' that holds the value aquired
         #from your device
         points.append(data[0])
         times.append(t2 - t1) 
         t1 = time.time()
         #Choose time interval between data aquisition
         time.sleep(.02)


     except KeyboardInterrupt:
          break

 

 

#process the lists of points and time intervals as you so choose

 

 

 

Thanks for the help!

Paul

0 Kudos
Message 7 of 7
(3,269 Views)