I've been working on a project for an RC flight controller. I've been using interrupts to determine the PWM input signal but I have noticed that interrupt latency is about 30us - should it be this large? To make matters worse, it is not consistent, sometimes it can be as large as 60us.
The code below shows how I have tested this and attached is a scope output showing the delays. The output should only be high for as long as the ISR takes to fire added to the digitalWrite() time.
In the context of my project this means I cannot accurately determine the length of a pulse.
On top of this the Servo.write() seems to be causing jitter. I think this may be related to the interrupt latency (servo library times the pulses with interrupts). Code below shows a minimal sketch example. When the servo is powered from a bench supply and signal connected to pin 6 the servo jitters about once a second. When signal is connected to an RC receiver, there is no jitter so I don't think the problem lies in the servo but more probably in the code.
Thanks for this, brilliant stuff for the PwmOut - gets rid of all jitter for me.
The mbed interrupt way of doing things seems to be a major improvement as well, latency of 10us (typically), but very ocaasionally takes 35us. Is there a background ISR that could be blocking the one I've set up? (first time with arduino - tell me if I'm being daft...)
As an aside, is 10us the performance you'd expect from this? (unless I've done the maths wrong that's 640 clock cycles...)
EDIT: After reading some of the mbed forums the 10us does seem to be normal, however the occasional 35us does not.
Code I used to test it is below, with pin 2 and 6 connected.
dannickalls:
EDIT: After reading some of the mbed forums the 10us does seem to be normal, however the occasional 35us does not.
ARM-Cortex-M processors have Nested Vector Interrupt Controllers. This means that interrupts with a higher priority can interrupt ISRs of lower priority interrupts. There could be two cases
there is an interrupt with a higher priority configured
there is an interrupt with the same priority running sometimes when your interrupt fires preventing your ISR from running
FYI: The nRF52840 has 48 interrupts with 3 bits priority = 8 Levels
There are some functions defined like NVIC_SetPriority() in the CMSIS core, but I/you need to some experimenting to figure out how the priorities are currently set and whether it is safe to change them.
Thanks for testing it out! What Klaus said makes perfect sense to me.
Also, try using wait_us() instead of delayMicroseconds(), as wait_us() is native mbed function. I have noticed that it complains heavily about Arduino waits during compile time...
Edit: I've just checked Arduino-mbed wrapper, and delayMicroseconds() is implemented as a simple call of wait_us(). So disregard this post.
Thanks Klaus, your much more knowledgeable view confirms what I suspected...
I'm afraid I don't think I have the knowledge to do a thorough investigation into this, but if I find some spare time I'll certainly have a look... (even if just out of curiosity)
If I filter my results sensibly then the variability in interrupt latency in the mbed ISRs is ok(ish) for my application.