I am currently trying to figure out how to timestamp each rising edge of a TTL signal. I have a magnetic rotary encoder with 1024pulses per revolution, outputting 2 TTL signals and a reference pulse once every revolution. My measurement setup consists of PXI with a NI6608 card. I have wired the TTL signals to the CTR0 Gate and CTR1 Gate (PFI38 and PFI34).
My main task is to measure the rotational speed with the best possible accuracy, and hence I would like to "timestamp" each rising edge based on the 80Mhz Clock, although I still have no idea how to do this. I currently imagine the solution being:
-create a counter based on the 80Mhz clock
-write counter to buffer for each rising edge
-output & clear buffer each 10ms
The maximum frequency of my TTL signal will be ~110kHz. Looking forward to your help!
With best regards,
Solved! Go to Solution.
You can do this with a counter task configured for either period or frequency measurement. Here's an example that depends on wiring to the default PFI pins. Key point: DAQmx is configured for "Implicit" timing rather than "Sample Clock" timing.
Here's some info about how to configure to use non-default pins of your choosing. You'll be able to select a PFI pin as the signal source for CI.Period.Term
Thank you Kevin,
I already tried the solution using period or frequency measurement, although this is not what I want (or I do not understand it properly). My end-goal is to have a buffer with the last 2048 rising edge timestamps so that I can use them to calculate the exact speed of my setup by comparing the rising edge timestamp T0 to T1024, T1 to T1025 and so on.
A cumulative sum of the periods from index 1 to N-1 (inclusive) will give you the timestamp for edge #N.
On your 6608 device, index 0 is a partial period from the instant your task started until the 1st edge. It's not meaningful here and should be ignored. (On newer devices, this partial interval is not returned and index 0 represents the interval from the 1st edge to the 2nd. This change in behavior is often helpful, but I'm nevertheless not entirely a fan.)
As to your plan to compare T0 to T1024, T1 to T1025, etc., perhaps you should describe the bigger picture for your test setup and app. Why do you want to do that? What will it tell you? It's possible there's a different approach that would fit your circumstances better.
The main approach is that I use a magnetic encoder with 1024 pulses per revolution. As each pulse has a magnetic accuracy of around 7", the resulting jitter in calculated speed will be out of tolerance. I, therefore, would like to compare each TTL pulse with the exact same TTL pulse 1 revolution later, and do this for every TTL pulse. Furthermore, I need this to run continuously for longer durations (several minutes).
I already tried summing up the periods, but I have not figured out a way to achieve maximum accuracy as i always miss a few pulses between each data-acquisition loop.
I hope I could clarify my problem. Thank you for your help!
With best regards, Ben
You shouldn't *need* to miss any pulses, can you post your data acq code? Maybe I can suggest a fix.
Also, can you describe more completely the way or ways you want to analyze the resulting data? It sounds to me like you're aiming to get an average speed over 1 complete revolution to limit the influence of physical encoder tolerances. But it also sounds like you want to do this 1-rev average speed starting from each of the 1024 possible starting positions. Do I have that right?
It may turn out to be easier to work with an edge counting task instead of period measurement. The idea would be to count edges of the internal timebase (80 MHz) while using the encoder signal as the sample clock. Then every pair of count values 1024 samples apart would already give you a cumulative "timestamp" difference for the same physical encoder edge on consecutive revolutions. However, you'll need to be aware that the 32-bit counter will rollover in (2^32 / 80e6) ~= 53.7 sec. There are straightforward ways to work around rollover though if needed, it's just important to be aware of it upfront.
Summary: with period measurement, there will be no hardware rollover of the 32-bit count register but in software you'll need to do a lot of cumulative summing. I'd recommend doing the cumulative sums as 64-bit integers before converting to double-precision seconds.
With edge counting, there *may* be rollover of the 32-bit count register but otherwise you wouldn't need to do any cumulative summing. Either can work, but I think edge counting is more straightforward and therefore less likely to have bugs in the post-processing code.
Ok Kevin I think I finally understand what you are proposing.
I already had the cumulative summing method working, and then timestamped each data-bundle (I requested 1000 samples each time). I then added all the periods in the bundle to the timestamp and compared this to the next arriving bundle and found a difference in time (which for me suggested that I miss pulses between the acquisitions). I am currently not so sure that this method works to make sure that i get all the pulses, but I cannot think of a better method right now?
Below is my DAQ code, but it should be completely straight-forward. My end-goal is to have the highest possible accuracy on my speed measurement using the magnetic encoder, with a measurement rate of at least 100hz.
1. While reading 1000 samples at a time isn't *inherently* wrong, it seems to me your post-processing might be more straightforward if you read 1024 at a time for exactly 1 full rev.
2. I don't really understand your description for summing and other post-processing. Code would be better. Be sure to put all the period data in an array or graph, right-click and choose "Data Operations-->Make Current Value Default". Then save back to LV 2016 or earlier and post.
3. Meanwhile, work separately on your processing algorithm. This is a good habit to develop. Create yourself some code that can generate a reasonable simulation of your expected actual data. Now you have data whose characteristics you can know ahead of time and use it to develop and evaluate your post-processing algorithms.
4. What is the reason for needing a 100 Hz measurement rate? Satisfying that while also comparing T0 with T1024, T1 with T1025, etc. is going to make your post-processing quite a bit more complicated. Doable, but be prepared to spend some extra time making it robust.
P.S. Attached is a head start for generating simulated period data. It superimposes nominal periods with a "misalignment" term (once-per-rev sinusoid), a "gear mesh" term (integer-times-per-rev triangle), and a "random" term (gaussian std dev). I recommend you keep all these contributors available even if they don't match your specific situation. Having extra knobs to control will help you to troubleshoot and perfect your post-processing code.
Thank you for all your help. The reason why my code is so limited is that I am only at the beginning of the development, and acquiring the TTL signals was the first task I wanted to get rid off. The post-processing of the data and all the rest should be straight forward.
Yesterday I realized that my sanity-check if I miss any pulses was wrong. Using the "High Resolution Relative Seconds" to timestamp my data and then calculate backwards and forwards to the next data-set cannot yield a perfect matching result. I then went on and using a signal generator with known FM modulation, and thus I could verify that I do not miss any pulses. I will now continue using the cumulative sum to calculate my speeds.
The 100Hz update frequency was just a baseline, the challenge is that I want to measure rotational speeds from 0 to 6000rpm with the best possible accuracy.
Thanks again for your help!