Recently I have bought a vacuum pump from [∞] Robotshop to experiment controlled withdrawal/injection devices following [»] the method I presented last year. In the previous post, the idea was to tune the pressure inside a tank (positive or vacuum) to get a steady flow rate. When the pressure inside the tank gets above the atmospheric pressure, fluid is drawn from the reactor to the outside (injection) and when the pressure inside the tank gets below the atmospheric pressure, fluid is drawn inside the tank (withdrawn/aspiration). When the pressure inside the tank is constant, the flow rate is approximately constant too. The object of this post is to develop a method to actively control the pressure inside the tank through feedback from a pressure sensor.
In the previous post, I have focused on the usage of aquarium pumps and by-pass valves to create a positive pressure inside the tank. Here I will focus on vacuum, but the technology is easily adapted to the case of positive pressure as well. The tank used is shown on Figure 1. It is built from PVC elements sealed with glue. Two holes were drilled into the cap to attach PG7 glands. Because the glands tend to crush the silicon tubing, I have used aluminium tubes as connectors. All of these elements can be bought in most DIY/hardware shops but be sure to buy IP68 glands as the lower insulation will not stand the pressure/vacuum. On the picture, you may notice that I have two caps: one with two small aluminium tubes and a second one with much longer ones. This is a result from the theory detailed in the previous post, where I have shown that it is a better idea to use the longer tubes (down to the bottom of the tank) for fluid injection. As we are interested in vacuum here, I have mounted the cap with the shorter tubes. By the way, always check the chemical compatibility charts. Here, most solvents, acid and bases are forbidden because of the PVC and aluminium. You can build alternatives using polyethylene or polypropylene elements but they are harder to seal together. In the past, I have successfully pumped concentrated hydrochloric acid with this technology.
The goal here is to control the pressure inside the tank and so we will need a pressure sensor such as the PCCFA6G which works up to ±1 bar. Check [»] this post to learn how to build your pressure sensor. One of the ports of the tank should be connected to the pressure sensor and the second one to the air pump. Do not forget to insert a bypass valve between the pump and the tank, such as explained in the previous post. When working with fluid, we will have to drill a third hole into the cap such as shown on Figure 2. I prefer avoiding connecting the pressure sensor directly onto the pump port because it tends to generate noisy data; so be sure to use a port exclusively for the pressure sensor.
There are two ways to control the pressure inside the tank: either run the pump in continuous motion and tune the by-pass valve to allow more or less exchange with atmospheric pressure (see [»] here for details on this), or, do not change the by-pass valve but tune the pump speed. When changing the pump speed, more or less molecule is exchanged between the pump and the tank. When the pump removes air faster from the tank than the by-pass valve allows air from the outside to come into the tank, the overall pressure will decrease. Inversely, when the by-pass valve let air come into the tank faster than the pump removes it, the overall pressure will increase. In this post, I have chosen to control the pressure by tuning the pump speed.
The pump used here is an AIRPO D2028 membrane pump which ranges from -700 mbar to +2500 mbar and works under 12 Volts (max 0.7 Amps). These pumps are cheap (less than $30US) but they do not last very long (between 200 and 500 hours as quoted by the manufacturer). The datasheet finally mentions a withdrawal capacity of 10-15 litres per minute at atmospheric pressure.
In the very first tests, I have tried an ON/OFF control of the pump. The pressure was monitored every 10 ms by a PIC microcontroller and the pump turned off when the pressure was above the desired valued. During the off state, some air was allowed to come into the tank by the by-pass valve until the pressure dropped below the target value where the pump was turned back on. The results are shown on Figure 3 and are clearly not that good. I had already experimented the same problem in the past with a piston compressor driven the same way and so the issue does not come from the pump but rather from the lousy control structure used.
More reactive control with finer tuning of the pump speeds are then required. The idea is that there exists some operation speed such that the pump perfectly compensates the amount of air exchanged by the by-pass valve. Because it is too difficult to derive such values from theory as it may change from experiment to experiment (or even within an experiment!), we need to use the feedback from a sensor to adapt the speed of the pump in real-time until a good value is found. There are various reactive structures that can be used but a popular one is the Proportional-Integral-Derivative (PID) controller. If p(t) is the pressure feedback from the sensor, e(t) the target value (usually constant but may also be changed during operations) and s(t) the speed of the motor to apply, the controller has the following structure:
with the good values for kP, kI and kD, s(t) will settle such that p(t)=e(t).
The controller was implemented on a PIC and the PWM output updated every 10 ms using the following code (read [»] this post for more information on PWM control):
#include <pic.h>
bit g_bUpdate = 0;
unsigned char g_ucPWMClock = 0;
unsigned char g_ucPWM = 0;
void init(void)
{
CMCON0 = 0b00000111;
TRISA0 = 1;
TRISA1 = 1;
TRISA2 = 1;
TRISC0 = 1;
TRISC1 = 1;
TRISC2 = 1;
ANSEL = 0b01110111;
ADCON1 = 0b00100000;
TRISC3 = 0;
TRISC4 = 0;
T0CS = 0;
PSA = 1;
PS0 = 0;
PS1 = 0;
PS2 = 0;
T0IE = 1;
TMR1IE = 1;
T1OSCEN = 0;
TMR1CS = 0;
T1CKPS0 = 0;
T1CKPS1 = 0;
TMR1ON = 1;
TMR1L = 0;
TMR1H = 0;
PEIE = 1;
}
void interrupt ctrl(void)
{
if(T0IF)
{
TMR0 = 128;
RC3 = (g_ucPWM > g_ucPWMClock) ? 1 : 0;
if(g_ucPWMClock < 100)
g_ucPWMClock ++;
else
g_ucPWMClock = 0;
T0IF = 0;
}
if(TMR1IF)
{
TMR1IF = 0;
g_bUpdate = 1;
}
}
unsigned char getCommand(unsigned long *pCommand, unsigned long *pPressure, unsigned long *pSamples, float *pIntegrator, float *pLastStep)
{
const float fProportional = 0.01;
const float fIntegral = 0.001;
const float fDerivate = 1.0;
unsigned short usCommand = (unsigned short)(*pCommand / *pSamples);
if(usCommand <= 10)
return 0;
unsigned short usPressure = (unsigned short)(*pPressure / *pSamples);
float fStep = ((float)usCommand - (float)usPressure) * 1000.0 / 1024.0;
float fResult = fStep * fProportional;
*pIntegrator += fIntegral * fResult;
fResult += *pIntegrator;
fResult += fDerivate * fProportional * (fStep - *pLastStep);
*pLastStep = fStep;
if(fResult < 0.0)
return 0;
else if(fResult > 1.0)
return 100;
return (unsigned char)(100.0 * fResult);
}
unsigned short analog(unsigned char ucChannel)
{
ADCON0 = 0b10000001 | ((ucChannel & 7) << 2);
ADIF = 0;
for(unsigned char c=0;c<50;c++);
ADCON0 |= 0b10000011;
while(ADCON0 & 2);
return (((unsigned short)ADRESH) << 8) | (unsigned short)ADRESL;
}
void main(void)
{
init();
GIE = 1;
unsigned long ulCommand = 0;
unsigned long ulPressure = 0;
unsigned long ulSamples = 0;
float fIntegrator = 0;
float fLastStep = 0;
while(1)
{
ulCommand += analog(0);
ulPressure += analog(2);
ulSamples ++;
while(!g_bUpdate);
g_ucPWM = getCommand(&ulCommand, &ulPressure, &ulSamples, &fIntegrator, &fLastStep);
ulCommand = 0;
ulPressure = 0;
ulSamples = 0;
g_bUpdate = 0;
}
}
Tuning of the controller values can be quite hard and fall way beyond the scope of this article but I recommend experimenting with them to detect experimentally what are good values. Figure 4 shows the effect of some of the parameters. In our case, the derivative effect seems to go unnoticed but the integral effect is strong, even at very low kI. Usually, the integrator ensures that the pressure finally matches the target which is not guaranteed with the proportional controller only (kI=kD=0). In the case of Figure 4, I suspect that my target was not -200 mbar as I thought but more probably about -220 mbar because it would be odd that the integral controller misses the target completely…
You should however take care when tuning kI because it may have tremendous effect on the command such as presented on Figure 5. Here, the value of kI was set too high and produced an overshoot that took about 1 minute to compensate. Integrators also tend to react slowly and are then usually compensated by derivative controllers which are much faster to react to changes in the signal. I have however failed to see any difference with and without the derivative controller here, as can be seen on Figure 4.
Now that our controller is working properly we can connect the third port to some fluid inlet. One of the port will be connected to the pump and the by-pass valve, the second one will be connected to the pressure sensor and the third one will be connected to the fluid inlet tube. I have used a 1-3 mm silicon tube (1 mm inner diameter, 3 mm outer diameter), long of 1.5 metre dipped into a graduated cylinder with 100 ml of liquid to measure the average flow-rate by recording the time required to empty the cylinder. That way, we can settle a precise vacuum inside the tank and check the flow-rate corresponding to that pressure. The experimental data was obtained by first reducing the pressure from about 400 mbar to 150 mbar and then increasing it back to 400 mbar to check for reproducibility.
The results are presented on Figure 6. All the point fits nicely on a line of equation Q [ml/h] = 4.68 * P [mbar], with a r2 of 0.9915. This result was expected because the silicon tubing used was sufficiently thin to ensure laminar flows and so the Poiseuille equation for cylinders applies.
The math from Poiseuille flows predicts a pressure drop of
with ∆P the pressure drop, Q the flow-rate, µ the dynamic viscosity of the fluid (10-3 Pa.s for water), L the tube length (1.5 m) and d the tube inner diameter (10-3 m).
From this we obtain a theoretical Q=5.89*∆P (Q in [ml/h] and ∆P in [mbar]) which is to be compared to the value obtained experimentally (Q=4.68*∆P). The order of magnitude is clearly confirmed and the small error (26%) can probably be explained by some localized pressure drops at the tube mouths.
By adapting the command, it is then possible to select a relatively precise flow rate. However, the pressure drop being a function of the tubing circuit, it may change depending on the operating conditions. To have a reliable and constant measurement of flow rate, I have built a flow sensor by measuring the pressure drop across a small length (less than 10 cm) of the silicon tubing with a 0.5 psi differential pressure sensor. The small silicon tubing will produce a linear output with a slope that can easily be calibrated for a given fluid. Using this flow sensor in place of the pressure sensor for the PID controller yielded the results of Figure 7.
Although the flow rate control is less clean than pressure control, it gives satisfactory results with a relatively fast response. The flow rate shows some burst but they are quickly compensated by the PID controller and so the averaged flow rate over a few seconds is stable enough.
Finally, I would like to mention that experimentation has shown that the volume of the tank vs. the pumping capacity of the air pump (in litres/s) plays an important role in data smoothness at given target values. When acquiring the data from Figure 7, the pump started and stopped every few seconds because the target flow rate was too low for the PWM to adapt nicely. Targeting for higher flow rates, where the air pump can run in a smoother way should then yield smoother data. As a conclusion, we may say that the dynamic range of the controller is not that good even if it does its job in the end. This is not really an issue if you are interested in an averaged flow rate on, say, 30 seconds or more, but it can be troublesome if you need very smooth flows. In the latter case, other technologies may perform better.
Still, I am quite happy with the results considering the cost of the pump built here and its reliability. I would definitively recommend it to you as you will have lot of fun playing with it and it demonstrates quite well the usefulness of PID controllers.
[⇈] Top of PageYou may also like:
[»] Steady Streams in the Lab #1
[»] Counting Bubbles with Laplace Pressure