10-13-2011 06:35 PM
Hello all,
I'm hoping the collective of creative minds here has some ideas to solve this.
Background:
I have a motor with a quadrature encoder.
There are 7 digital signals that occur at various angles as the motor rotates.
I need to capture the position of each of the 7 signals. Both rising AND falling edges.
I'm using a PCI-6602 counter/timer card.
I'm developing in Labwindows/CVI.
My approach so far:
Connect the A, B, Z signals from the encoder to each of the 7 counters.
Configure an angular encoder task to perform buffered position capture for each counter.
Connect a PFI input to each of the 7 digital signals and select as the sample clock.
As far as I can tell there is no way to capture on both the rising AND falling edge of the sample clock.
I can put some hardware on each of the signals to generate a short pulse for each rising and falling edge.
Now it will save a position sample for each of the edges on all 7 channels.
Here's the problem:
When I go into the arrays of position samples that were collected for each channel, how do I know if
it was a rising or falling edge??
Racking my brain,
Kirk
10-14-2011 01:08 PM
Hello kirkm,
Looking just at the problem section of your post, you would just need to know the initial state of the signal, and every pulse after that would be the opposite. If you start Low, next pulse is High, next is Low again....etc.
Have you looked into seeing if your card has change detection? I see that this is a pretty popular subject with other threads on the forums if you search for "rising falling edge"
Take a look here and see if setting up a change detection task will work for your case
10-14-2011 01:15 PM
I must have skipped over the part that you were using 6602. Change detection is not supported on that card.
10-14-2011 03:31 PM
Thanks for taking a look.
One thing I thought of that I haven't tried yet is to register a callback to occur on the sample clock.
Something like:
DAQmxRegisterSignalEvent (myEncoderCounterTask, DAQmx_Val_SampleClock, 0, myCallbackFunction, myCallbackData);
Then read the state of the sample clock pin in the callback and store it.
I'm not sure if the callback can keep up. Fortunately the signals that will drive the sample clock are fairly slow, about 100Hz on each channel.
What do you think?
Still working on this,
Kirk
10-17-2011 01:14 PM
100Hz doesn't sound like a lot at first glance but when you multiply this out over 7 channels that becomes a larger chunch of CPU resources. Best way is to try it and use something like windows task manager to keep track of your CPU and memory usages.
10-17-2011 01:33 PM
I tried using the following:
// register a callback to happen on each sample clock edge
DAQmxRegisterSignalEvent ( cthCounter4EncoderPosition, // TaskHandle Task,
DAQmx_Val_SampleCompleteEvent , // int32 Signal_ID,
0, // uInt32 Options,
SampleClockCallback, // DAQmxSignalEventCallbackPtr Callback_Function,
NULL // void *Callback_Data
);
And I get the following error --
It looks like in additon to not supporting change detection, the PCI-6602 doesn't support ANY of the signal events.
(unless you see something I'm doing wrong with my call to DAQmxRegisterSignalEvent) ??
Thanks,
Kirk
10-18-2011 04:44 PM
That's strange.
Right now you have 7 counter input tasks measuring edges, correct?
I don't see anything wrong with your code, but I will have to check with another engineer who can verify it.
Have you been able to implement the logic for figuring out if the sample was rising or falling that I suggested previously?
10-18-2011 05:10 PM
Right now I'm testing with just one counter to see if I can get it to work. I'll connect all 7 after I have it figured out.
I'm confused. If I undstand correctly the DAQmxRegisterSignalEvent(...) function is what you use to set up a change-detection callback. That is what I though you suggested. Then you later realized that the PCI-6602 doesn't support change detection.
I was hoping it would support one of the other signal events such as:
DAQmx_Val_SampleClock
or
DAQmx_Val_SampleCompleteEvent
But... according to the error I got in my previous post it looks like it doesn't support ANY of the signal events. (or maybe I'm doing something wrong in the code)
Kirk
10-31-2011 06:05 PM
I realize this is a late post.
I wanted to explain how I solved (mostly) this problem.
What I did was create some external hardware that generates a single pulse on the rising edges, and generates 2 pulses on the falling edges.
The pair of falling edge pulses are a function of the encoder A input so they are always 2 encoder cycles apart.
When I analyze the buffered encoder counts that are captured I can tell which are rising and falling edges.
Now I have another related question:
I'm running several encoder counters simultaneously from the same encoder A & B inputs.
Is it possible to connect the A & B inputs to Ctr0 and then internally route the signals to Ctr1, Ctr2 ....?
Or do I have to hardwire the connections. (which is not desireable because they'll have to drive 6 or 7 signals in parallel into a 2 meter long cable to get up to the PCI-6602)??
I tried the following:
// get Ctr1 inputs from Ctr0
DAQmxSetChanAttribute ( cthCounter1EncoderPosition, // TaskHandle Task_Handle,
NULL, // char Channel[],
DAQmx_CI_Encoder_AInputTerm, // int32 Attribute,
"/Dev1/PFI39", // ...
0 //
);
DAQmxSetChanAttribute ( cthCounter1EncoderPosition, // TaskHandle Task_Handle,
NULL, // char Channel[],
DAQmx_CI_Encoder_BInputTerm, // int32 Attribute,
"/Dev1/PFI37", // ...
0 //
);
I get this error message:
Any ideas???
Thanks,
Kirk
11-01-2011 11:22 AM
Hi Kirk,
Our PCI-6602 card does not support internal routing for counter signals. You will have to wire your encoder output to each of the counter inputs if you want to use multiple counters to read the same encoder.
Good luck with the rest of your project.