Do I just use a standard PID algorithm and tune to minimize overshoot?
I think no. If you set PWM you set (control) flow rate, not level. So a PID is not the right algorithm.
To reach a position (liquid level), normally two cascaded PIDs are used: one controls the position (liquid level), the other controls the speed (flow rate). Two cascaded PIDs work well to keep the level constant: even if the level drops because someone consumes the liquid, they would work together to gently refill.
If I understand well, you reduce PWM down to a value PWMmin, as the vessel gets full. Your problem is that you risk to set a PWM too low which, for some type of pump, it is not sufficient and the pump stops.
A PID algorithm would be correct to control the PWM given a flow rate. As you approach the target value (quantity of liquid) you reduce the flow rate, and the PID regulates the PWM consequently.
If you can read the flow rate, you have all you need. Perhaps you have not... but you could estimate the flow rate reading the liquid level at intervals (seconds? minutes?). May be your reading is fast and accurate enough, or maybe not, all depends on time, precision, and whether it is allowed that a pump stops for a while (because the PWM is too low to make it move), until the software notices that the liquid level stopped raising and raise PWM consequently.
So, I think there are two possible strategies:
- Decrease PWM as you are doing now but, if a stop of the pump is detected, raise it again
-- or --
- When decreasing PWM, monitor the flow rate in an effort to understand the correct value to decrease PWM in the next step. I suppose that, before reaching the critical PWMmin, you notice that the flow rate is decreasing too much in respect to decrease of PWM.
If none of the two methods are viable, then there is no other choice to read reliably the flow rate, and in this case the PID should not be too difficult to set up.
When you can reliably (more or less) control the flow rate, you can concentrate on the first problem (reach a liquid level).
What you are doing now is actually a sort of PID - no, better than a PID, because what you are doing now is an algorithm tailored to the problem. PID is a good and general algorithm, but its bigger defect is that it doesn't know anything about the system it is driving. All you can do is set three coefficients, while in many cases more "intelligence" can do better. To stay on this case: a PID can try to generate a correct PWM for the pump, but it does not natively know that there is a minimum value to respect: that is a thing that must be managed outside the PID (or the PID must be modified). But now, we are back to the first problem: if this minimum PWM is not a fixed value, the PID can well stop the pump for a while, until it recognize that there is no flow, and then the PID will increase PWM again.