How do you run multiple SignalCapture.Read() calls at once?
I’m using it to count rotations of a motor, and we now need to add several more rotational counters to the microcontroller.
This method appears to block the CPU, and blocking a 400MHz CPU to count one interrupt port seems like a waste of clock cycles, especially over the 100ms+ interval that we need. I feel like I’m missing something here.
Using .NET MF on a G400-D.
Use IO ports with interrupts?
Signal Capture provides microseconds between edges. The pulse frequency is up to 2KHz. We need to have at least 3 channels of such.
IO ports with interrupts didn’t seem to provide reliable timing output when tried at those speeds.
Signal Capture was an additional feature to get timing critical functions. I’m suspecting that what you are finding is that this comes at a cost, the ability to multitask… so in this particular case you may be forced to look at co-processing to manage those multiple streams of input and leave your G400 to do the aggregation and control
How are you doing the timing?
Catching the interrupt event and then using DateTime.Now to track the time between events (using Ticks / Timespan as measurement). Do you know of a better way to do it?
There is a much better way to do it!
Just got back to USA from Europe… Have not slept in 24 hours…
If no one else talks about interrupt queueing and the timestamp on each interrupt I will explain tomorrow.
**** Awake now,
First MF uses a queued mechanism for interrupts. When a hardware interrupts, MF creates an interrupt event and puts it on a queue. The interrupt events are then processed by an internal interrupt processing thread, which calls your interrupt handler.
Depending upon what is going on, there can be a variable delay between the time when the hardware interrupt occurred and when your handler sees it. This explains why using DateTime.Now to time interrupts can cause significant jitter.
When you use an InterruptPort object, the event handler gets a relative timestamp for the interrupt as one of its parameters. This is the timestamp you should use for timing purpose.
Reading an IO Port’s value in an interrupt handler, expecting it to be the value that was present at the time of the interrupt is also a no-no for I hope obvious reasons.
The link below explains this further:
Let us know if this works in your application.
Very interesting! I didn’t know how that worked. So basically .NET will cycle through the interrupts in the queue and call your handlers once per interrupt, so that your code execution is decoupled from the hardware interrupts.
The link you provided used the class GPIOInterruptEventHandler to handle interrupts. However, I couldn’t find the class in my .NET MF namespace (perhaps I have the wrong version or something).
All I have available is the NativeEventHandler class, which takes a method of the form IntButton_OnInterrupt(uint port, uint state, DateTime time), and provides a DateTime object rather than a TimeSpan object.
I presume that the DateTime.TimeSpan is the same timestamp as the plain TimeSpan coming out of the GPIOInterruptEventHandler. Do you think this just does the same thing?
BTW, I hope you enjoyed your trip to Europe! Jet lag can be a drag
Yes. Been a while since I have used MF.
I believe subtracting a DateTime Object from a DateTime object returns a TimeSpan object.
DateTime start = DateTime.Now;
… busy busy …
TimeSpan elapsed = DateTime.Now - start;