Quote:
Originally Posted by Alan Anderson
We did that for the shooter wheel last year, but with a twist. Recognizing that the buffer is essentially a filter that slows down the measurement response, we added the newest value from the buffer multiple times. The resolution stays high, but the sum more quickly represents a change in velocity.
I also came up with an interesting result when I figured how long it took to maintain the ring buffer. With as many as ten entries, it turned out to be faster to move all of the values every time than to index through an array. Array operations are convenient and make for easier coding in many cases, but they can be remarkably slow.
|
I agree that a weighted average approach can help. In this case, to get the resolution we needed, a sample window of about 4*26 (100ms) worked out about right, but only performing the PID calculations at that rate, made the loop somewhat hard to optimize and user response more sluggish.
I don't doubt that individual moves would be faster as it avoids one or more multiply operations to compute the array index.
Although the interrupt routines use an arrayed variable to store the tach counts, the use of an absolute index allows the compiler and linker to resolve this to a fixed memory location at build time.
The overall simplification of Kevin's code by reworking the logic to remove direction sensing as well as the overhead of function calls helps reduce the CPU loading where the impact is the greatest.
My primary point in sharing the idea was to provide a simpler example of how a velocity only interrupt could work, and to introduce the idea of using a sliding window for data values to improve resolution.
I chose to use arrayed variables in the 26ms loop for the tach code as well as all of the remaining PID code just to help with readability and to make it easy to change the size of the ring buffer, or add/delete motors.
Certainly if the CPU didn't have any idle time left, the arrays are one of the first things I'd go after.