问题
I'm having a hard time getting both PID feedback and positioning to run at the same time.
My thought to calculate the RPM is to:
- start a timer and count encoder pulses using an interrupt.
- use some simple math to convert to RPM.
- reset variables used and start over.
I can calculate RPM but then I can only call my PID controller after the calculation (however long I want to wait to get good resolution.) This results in very messy code. Is there a simpler method or something I'm missing?
Info about my application: I am programming to an Atmel ATmega328P with a DC motor/dual magnetic encoder with ~600 pulses per revolution (after gearhead). I want to call GoToTarget(#) and have the motor go to the position while updating the PID parameters. In addition,it must go both ways.
回答1:
Your speed calculation timer and your PID loop timer should be the same thing - not separate.
Do not waste time and resolution converting pulse count to speed in RPM; if the timer is accurately periodic - and it needs to be for a stable PID - then the pulse count is directly proportional to speed, and the PID does not care about the units - that can be adjusted for by the value of the coefficients. If you want your set-point speed to be in real-world units, convert that to the equivalent number of pulses-per-PID-period instead of the other way around.
Your loop should look like this ;
for(;;)
{
WaitTimer() ;
pulses = pulse_count - previous_pulse_count ;
previous_pulse_count = pulse_count ;
control = pid( pulses ) ;
motor( control ) ;
}
You then need only an interrupt to count pulses - it need not perform any calculation, just increment a counter - and perhaps an interrupt for the timer, depending on the implementation of WaitTimer() and whether this is multi-threaded.
Note also that if the shared variable pulse_count is not atomic, you will need to disable interrupts while it is read (best wrapped in a function), and it will need to be declared volatile
.
来源:https://stackoverflow.com/questions/17237173/pid-feedback-position-controller-with-dc-motor-encoder