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:
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.
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
.