Generally you find the PID gain values by structured experimentation, something like this:
- Start with only a P gain (I and D = 0), and make it as high as possible with little or no overshoot.
- Add a little I gain. Make it as high as possible without producing more than just a little ringing.
- Up the P gain a little. This will usually add a little stability now that the I term is there.
- Iterate with the P and I terms to get the fastest settling time with whatever overshoot you can tolerate.
- You can either stop here, or try to add a little D term. The polarity of the D term depends on how exactly you implemented the equations. A little D can add some stability, which allows you to make the P and I terms a bit more aggressive. The point of the D term is basically to say if I'm already heading in the right direction, decrease the drive. However, D is susceptible to noise. Making it too high will cause the output to sortof "vibrate", which is basically amplifying the sensor noise onto the output. A little D can be useful if you need the last bit of performance, but a lot of implementations leave it out.
I notice you plan on doing this all in analog electronics. This makes no sense, especially for something slow like a motor. For efficiency, you will want to drive the motor with PWM. The natural way to do this is the motor speed sensor feeds into a microcontroller A/D. The micro does the PID calculations and uses that to adjust the PWM duty cycle. It can also do the direction changing with the H bridge, guarantee break before make, etc. There are many small and cheap micros with A/D and PWM hardware built in. Some even have H bridge drive PWM outputs. This is such a common problem that there are whole subfamilies of micros optimized for this.
The compute power you need is modest. Back in the late 1990s I used a PIC 16F877 to run two layered PID control loops that drove a DC motor. The inner loop controlled the position of the motor and output PWM to the H bridge. The outer loop controlled the speed of a gasoline engine and output a position value to the inner loop. The PID computations were done in 24 bit floating point. We used 8 ms per iteration, which left a little time to do all the other low priority tasks. That micro was running at its maximum speed of 5 MIPS. That is quite slow by today's standards. Lots of micros are quite capable of doing what you need.
Doing this in analog will take more board space, take more components, be much harder to tweak, and does not provide a convenient interface to the motor driver power stage. It just doesn't make sense.
I don't see any code that resets K0
, K1
, and K2
, until the load state is used.
This means that on start-up, these registers have X
value.
Therefore the outputs of u_mult1
, u_mult2
, and u_mult3
have X
value.
Therefore the outpus of u_adder1
, u_adder2
, and u_adder3
get X
value.
Therefore on the next clock edge, sum_out_old
gets X
value. Probably at the same time, the K variables get loaded with their values from the module inputs. But it's too late. Since sum_out
is calculated from sum_out_old
, it then becomes X
, and sum_out_old
is trapped in the X
state.
The easy way to solve this is to have K0
, K1
, and K2
reset to 0 when rst_n
is asserted (low), but you should consider if this is correct for your situation.
Best Answer
You only need to adjust the RC product to tune a PID controller, so there should be no problem if you have fixed (or discretely switched) capacitor values and adjustable resistors. You might need to switch capacitors of you have no idea of the plant characteristics and have to accommodate a huge range of possible parameters.
But more and more this kind of thing is done entirely in the digital domain. In particular, slower loops are excellent candidates,