11-22-2007 08:55 AM
11-26-2007 04:18 PM
Hello Lou_III,
First off, welcome to the NI forum. From your description, it appears
that the problem is with the fact you lose your position information when you
try and stop the counter task. You need to stop the counter task so that
you can switch from single point reading to a buffered counter synchronized
with an analog input (and back).
Assuming I understand the issue correctly, then I have a couple ideas you can
try. First off, you could use two counters (both wired to the encoder)
and have one do single point while the other does buffered. You could
then choose which data is displayed/used/etc depending on what your need is.
Since they are both running from the beginning, you would not lose your
position when switching.
If that is not an option, then you could just use the buffered acquisition.
When you want the single point, you could read all of the data on the FIFO
buffer and only use the last point. This would be very close to the
single point read, but you would just have to parse the data yourself (get the
last value in the array). I tried this in LabVIEW (which I am more fluent
in) and it worked very well. I used a case structure (equivalent to
"if, then, else" statements in C) and a Boolean to choose whether to
take the last point of the array I read or output the whole array. I did not
specify a samples to read so that the function would read all of the
samples in the buffer and give me the most recent point.
The trick with this second method is that you must always have an external
clock running to latch values into the buffer of the counter. One way to
do this is to have your analog input running continuously (even if you do not
need the data). This would provide your sample clock. You could then
manually control the buffer with the RelativeTo function and the OverWrite Mode
Property so you do not get a buffer overwrite error.
I am a little confused as to how the analog input goes with all of this.
Do you want to use the encoder as the sample clock of the analog input? Or are
you possibly trying to take encoder values at the same time as your analog
input?
If you want to use the encoder signal as your AI sample clock and synchronize
with the counter, you could input the encoder signal on a PFI line and use it
as the sample clock for both the AI and the counter (you would be counting the
edges and latching values of the counter with the same signal). I tried this
with my M series card, and it worked.
If you are trying to just use the same sample clock, you can set up the AI
sample clock and use it (e.g. Dev1/ai/SampleClock) for both the AI and the
counter.
I realize this is a long, wordy post, so please post back with the questions I
am sure you will have and I will do my best to clarify.
11-27-2007 10:24 AM - edited 11-27-2007 10:24 AM
Hello Neal, thanks for your help on this. I really appreciate it.
As you guessed, I must support two seperate encoders so using both NI counters for one encoder is not an option.
The software that is being interfaced to is quite flexible so I need to support both "types" of data collection cases.
Case 1. Analog & Encoder & Digital buffered data collected against the NI internal timer (I have this working correctly using the "Dev1/ai/SampleClock" as the second parameter to the DAQmxCfgSampClkTiming function.)
Case 2. Analog & Encoder & Digital buffered data collected against either an Encoder or an Analog value. (ie, collect data every 10 quadrature pulse or collect data every 1 mv )
I like your idea of always leaving a daq task running but can I change the Rate of the collection without stopping the task? ie. If I just want single point data can I collect at 10 Hz but then when the user has requested high speed data acquisition I need to get data at 20 000 Hz. I haven't tried this yet but I think I have to stop the task to change the rate of the internally clocked DAQ.
When it comes to Case 2...I don't understand how to get route the Encoder output to be the sample clock and use a different PFI line or how to get it to collect every say 10th quadrature pulse. Is there a Divide by N function call somewhere? If you could steer me to how this type of data collection is setup that would be great.
11-27-2007 03:26 PM
12-05-2007 01:12 PM
Hi Neal....I have a follow up question related to digital I/O.
If I have a buffered data collection going on to read the digital inputs I have setup on Port0...can I also simultaneously control digital ouputs that I have created on another task using the DAQmxWriteDigitalScalarU32 function? If not do I have to create my digital inputs & outputs on the same task, could I then do what I want? Right now the Analog Inputs are on one task, Digital Inputs are on one task, each Encoder has one task, and my Digital Outputs are on another task. Also, I understand the readback string for the ananlog Outputs is ao0_vs_aognd and ao1_vs_aognd but can I read these back while the AI task is running...do they share the same mux or what are the rules here.
12-06-2007 07:08 PM - edited 12-06-2007 07:09 PM
Hello Lou,
I am going to answer your questions in two "sections" so I can keep
things straight. The first section I will focus on your question about
doing synchronous digital input and output. Then I will go into how the
Analog Inputs are read.
DIO:
Since you are trying to do two separate functions (digital input and digital
output), you need two separate tasks. This is due to how the tasks
operate; using different buffers and operations (read v write). The
DAQmxWriteDigitalScalarU32 function is a write function, so it will not work
with a digital input. The way to synchronize these is exactly like how
you synchronized the analog and encoder; you must use the same sample clock so
that the two tasks read and write out of their respective buffers at the same
time. The catch is that you must provide an external clock signal to do
this.
Analog Input:
I am slightly confused about what you mean by "readback string" and
reading it back. It appears to me that you want to read the ao0 and ao1
channels (internally routed to aognd) back with your AI task while it is
running. If this is the case, then you would need to include these
channels (_ao0_vs_aognd and _ao1_vs_aognd) in the channel list when configuring
the task. Due to the fact the channel information is used extensively
while configuring the task, there is no way to add channels while the task is
running. You would then have to read the data like the rest of the
channels.
The only properties of a task you can change while the task is running are
listed in the LabVIEW help (see image below). I am unsure if you have
access to this help file, but if you do, you can search for them by searching
(with quotes) "Properties Settable at Task Run Time."
12-13-2007 03:24 PM
I have physically have one encoder and feed in Phase A & B to ct0 and reverse Phase A & B into ctr1 so that effectively I have two quadrature encoders that always read the same value but one is the negative of the other. If one reads -27.25 the other reads +27.25 When one counts up the other counts down and vice-versa. Everything works great when I compile the debug version of my program in MSVC.
However, when I compile the release version the encoders do NOT work correctly. I have removed the optimizations on the cpp files that contain references to DAQMX C function calls but it still does not work. The symptom is that ct0 and ctr1 do not count in different directions. If one moves in the positive direction the other one also moves in the positive diretion but at a different rate (say ctr0 counts faster than ctr1)...when I spin the encoder the opposite way, (instead of counting backwards) both ctr's continue to count up but now ctr1 counts up at a faster rate than ctr0. Wierd indeed. Any ides on what is happening here ?
12-17-2007 02:42 PM