I've been studying and trying to implement a PI feedback controller for a BLDC.
Right now, just to unit test the code for the PI controller, I'm driving two phases with a PWM signal on a MOSFET inverter and trying to get a prescribed current out by watching the voltage that develops on a sense resistor.
Here is the what I have the architecture:
1) A PWM has a register value and starts outputting pulses
2) The windings ramp up with current flow
3) A voltage is developed across a 0.015R sense resistor
4) That voltage is gained up by 5x through an OpAmp
5) That voltage is fed to and ADC that samples at the exact center of each pulse.
6) The ADC readings are collected and averaged as fast as the pulses occur for a period of 20ms
7) The PID controller that I've included then takes action and that's where I'm stuck.
Ultimately, what I really want, is a value to stick in the PWM on-time register...I want a 16bit value. But, what I'm getting in are 12 bit ADC values.
So, I said to myself, "no problem...I'm not getting current readings in, but I know what those values really are, so I'll just convert them to current!"
So, I did this:
$$ I_m = \dfrac{ADC}{R_{sense} * 5 * \dfrac{4096}{3.3}}$$
So, that's OK. Then I go through the PI control, where we do:
$$ I_{err} = I_{set point} - I_m $$
Then, do what you do in a PI controller...Add integral gains to their past values, scale proportional gains by a scalar, and then add them up:
$$ I_{feedback} = P * I_{err} + I * \int{I_{err}}{dt} $$
This is the part where me and my buddy looked at each other and didn't know what to say...Here we're holding current feedback in our hands, measured in Amps (and a rather large value, I might add, thanks to the high gains that I've read PI controllers like to see)....But, what I need to do is put this into a PWM counter-compare register...That's a 16bit counter, not a...current register, whatever that would be!
Consider this case...I ask for 100mA and I observe 200mA...I calculate my error of -100mA, so I need to cool this thing off...I intuitively know that the answer here is to reduce the PWM duty cycle from whatever it is now, to a lesser value.
If I go through the whole algorithm, because of the negative error, that minus-sign is going to propogate all the way to my $$I_{feedback}$$....So, I leave the feedback with a negative value. What can I do with this? How should I apply that to a PWM register, which is the real control output?