06-04-2021 11:08 AM
Hi,
I am using a optical rotary encoder to measure the angle and the RPM of the shaft. I have a USB 6341 DAQ system which I am using for acquiring the encoder signals. I am using the counters to count the edge of channel A. When I acquire the data and look at the data, it looked like counts were being skipped in between. It happens more drastically for the case of higher speeds whereas for low speeds, it happens sometimes. I looked at some online resources but could not find any suitable resource to help with this problem.
I have attached the code as well for reference. Can someone please help me with this issue?
Regards,
Abbishek
06-04-2021 12:45 PM - edited 06-04-2021 01:03 PM
We don't have your hardware, so can you attach a typical output file, then tell us how you expect it to look instead. Maybe you have some misconceptions. What are typical rates for fast and slow?
Also:
06-04-2021 12:50 PM
What does your data look like?
Are you saying the encoder is missing counts as in it missed edges?
Or are you saying that when you look at your log file, you sometimes see a count of 0, 1, 2, 3, 4 but other times 100, 101, 105, 107, 109, 110 , something like that?
I'm going to guess the latter. That is perfectly normal and you aren't missing any thing. The DAQ Hardware is doing the counting. You are periodically using software to ask the DAQ device, "what is my count now?" If you are asking fast enough, or the pulses from the encoder are going slow enough, you'll be able to see it tick up, 1, 2, 3, 4, ..... But at faster speeds, you are getting multiple encoder pulses since the software can only run at however fast the CPU allows it, you might have two pulses go by in the time it takes for the acquisition loop to come back around and ask again.
Complicating this is that the acquisition loop is building up data in arrays, and the loop is running as fast as it cans. That means you are quickly accumulating data, and once the array gets too big, the CPU has to take time to find a bigger chunk of contiguous memory, move all the acquired data to that, before it can start appending new data to the end of the array. (Also, you are acquiring data on an extra tunnel you never use.)
You'd be better off with a producer consumer architecture so that the data is passed in a queue and written off to a file in a separate loop.
06-04-2021 01:34 PM
Hi,
Thank you for the response. You are right that it is the latter case that in the log file counts are missing.
You suggested using a producer consumer architecture. I am not well versed in this concept. So it would be helpful if you can suggest how to use this architecture with the program I uploaded before.
Thank you
Abbishek
06-04-2021 02:10 PM
Hi,
I made this VI with a producer consumer architecture like you suggested read from online resources. The counts still seem to be missing. However, I am not sure if this is how the architecture is supposed to perform or not. Can you please guide me with this program and the architecture.
Thanks
Abbishek
06-04-2021 03:29 PM - edited 06-04-2021 04:07 PM
@Abbishek94 wrote:
The counts still seem to be missing.
You did not answer or address any of my points, and the code is still an inefficient mess.
Counts cannot be "missing", each reading just allows you to tell how many counts occurred since the last reading by comparing with the previous reading. The only way to "miss counts" is if the counter has an insufficient number of bits and rolls over twice between readings.
06-04-2021 03:31 PM
Get rid of the auto-indexing tunnel in the upper, producer loop. Since you aren't using it anywhere, the compiler might just discard it. But there is definitely no reason to create a wire branch that you never use.
The producer/consumer should certainly help memory issues. But you still haven't handled your problem with how fast the acquisition loop runs nor answered Altenbach's question about it.
Let me put it into words.
If the loop runs once per millisecond, and your encoder generates a pulse once per millisecond, then you'll basically see each and every increment of that counter as it detects the pulse.
Now imagine your encoder is running twice as fast. It will generate two pulses, incrementing the counter by a count of 2 in a millisecond, before your acquisition loop as a chance to get around to read the current count. There is no way you can resolved that without having a much faster acquisition.
What exactly are you trying to achieve here? Do you really need a log entry for each and every encoder pulse? If so, Why?
What is your fastest pulse rate for that encoder?
If you have a high pulse rate, and if you need to document each and every increment of that counter, then you probably will not be able to do it with a Windows based system. You would need to look at an FPGA based system to do the pulse acquisition.
06-04-2021 04:11 PM
I understand the point regarding the acquisition. If we want a more precise timing, should we use a sample clock and set the sample rate there? The problem is if the samples fall in between the two edges, then the encoder will not increment the count and the rpm calculated will be wrong. So, is there any other way to increase the fastness of acquisition.
The encoder is mounted to a shaft which is coupled with the rotation motor and I need the angles (counts) to calculate the rpm.
Can you elaborate on the pulse rate of the encoder? If I am not misunderstanding, the resolution of the encoder is 5000 pulses per revolution.
Abbishek
06-04-2021 06:20 PM
If you want a precise measurement of RPM from an encoder you're going to need hardware-driven sample timing.
One way is to configure an angular encoder task and provide it with a constant rate clock from another task (or create one with another counter). Each sample gives you an angular position, and you can do a derivative to figure out RPM. Note that this approach will give you really good Pos vs Time info. However, because numerical derivatives tend to amplify noise and disturbances, you may not like what you see in your RPM vs Time.
Another way is to configure a frequency measurement task where you specify Implicit timing and characterize every time interval. This is likely to lead you to much better RPM info. The sample #'s will correspond to relative angle (1 sample per cycle of the encoder signal). The time at each sample can be figured by summing the reciprocal of all the frequencies (i.e., summing the periods). Samples will be inherently equally spaced in angle but variably spaced in time.
-Kevin P
06-04-2021 06:48 PM - edited 06-04-2021 06:51 PM
@Abbishek94 wrote:
Can you elaborate on the pulse rate of the encoder? If I am not misunderstanding, the resolution of the encoder is 5000 pulses per revolution.
That's part of the equation. The other part is how fast is the encoder turning?
If it is spinning once per second, then your pulse rate is 5000 pulses/sec.
If it is spinning 100 times per second, then your rate is 500,000 pulses/sec.
Either of these speeds would be difficult to detect each and every pulse with a software timed loop.
However the hardware is more than capable of counting all the pulses.
You haven't really said what you are trying to do, but you are hinting at measuring RPM. Try to measure RPM based on each and every encoder pulse is a very backwards way to do it and over complicated. Kevin has given you advice on a better way to measure RPM.