Controller for slow changing system

Hello together,

I built an air humidifier (for a small test chamber which should hold constant humidity) that is basically an impinger filled with water. To increase the humidity inside the chamber I pipe air through the impinger and to lower the humidity, I supply it directly from the pump into the chamber.

Due to constructive restrictions, the distance between the impinger and the chamber has to be quite big and therefore it takes quite a while until humid air is pushed into the chamber after switching the valve.

Right now, I use a PID controller (Brett Beauregard's PID library), but I am not quite sure, if a PID controller fits my problem. In case I experience a slight overshoot (let's say, the desired humidity is 60 % and we measure 62 %), the output value falls to 0. Then the measured humidity starts falling and after passing the 60 % line, the output is set to > 0. As mentioned earlier, since it takes quite a wile until the humid air reaches the chamber, the measured humidity falls way below 60 % and starts increasing.
To sum up - if the humidifier just starts working after falling below the desired value, I get an inevitable oscillation (period time is roughly 5 min). Do you know a type of controller, which might fit my needs any better? I thought about setting a constant minimum value so that, the humidity might not fall that fast. But since the environment humidity (and temperature) are not constant, this would lead to other problems...

Thanks in advance,
Josef

Confirm you only have on and off, or I think the air does or does not pass over/through the impinger.

PID has its place. I am only familiar with it in the context of systems that can vary a control, in this case feeding a greater or lesser amount of air through the impinger.

So I wonder aloud if you can control the fan volume or direct a controllable percentage of the air through the impinger.

a7

Your problem sounds like an analogue of controlling hot water central heating, which has a similar problem due to the lag between starting to heat the water and the hot water in the radiators heating the room, and, the reverse, turning off the source of heat but the now hot radiators continuing to heat the room long after the source of heat has been turned off.

The solution is to use slow PWM to control the heat source. In the case of my heating controller I use PWM with a 720 second cycle time and usually achieve control of room temperature to within 0.1 degree Celsius, although sometimes it only achieves 0.2 degrees.

The way I did it was to have the heating on full if the room temperature is lower than 1 degree less than the set temperature. Once the temperature comes within 1 degree then PWM takes over, with the on to off time ratio reducing towards zero as the temperature approaches the set temperature. I also use a crude version of the integration part of PID to add an offset to the set temperature to compensate for the need to keep some heat going into the room at the set temperature to compensate for heat lost

I suggest you should be able to adapt this idea to what you are doing.

Thanks four your response! Yes, I only have on/off. Therefore, I vary the valves duty factor (frequency 1 Hz) - I should have mentioned this...

Thank you too for your reply!

Yes, this sounds like being basically the same problem. How do you determine this "offset to the set temperature"? May you share a snipped of your code (no documentation needed - decrypting code usually aids understanding it :wink: ).

Trial and error! I think it adds 0.05 degree to the set temperature for each minute the actual temperature is in the PWM range but below the set temperature.

I am on holiday at the moment with no access to my code. Send me a PM on Saturday to remind me and I will share some code.

OK, thank you very much! Enjoy your holiday!

PID is an elegant solution to a generalized control problem, but as with Perry's heating system, you can often do better by using a control algorithm that uses what it knows about your particular system.

I'd open the humidifying valve all the way to start and gradually close it down as you approach the desired humidity, preferably never actually closing it all the way. That by itself might let you get around the lag because it will always be flowing a little bit. If it gets too humid because of that, you can fix it with the other supply of dry air.

Depends how tightly the humidity must be held around the target value. If you can stand a little slop, then there's nothing simpler, more stable, or more reliable then a bang-bang controller with a little bit of hysteresis around the setpoint.

Hey, if it’s good enough for Charles Stark Draper and NASA, it’s good enough for me:

The deflection error is then supplied to the servo amplifier, 
a bang-bang amplifier with deadzone and hysteresis. 

:wink:

a7

Thank you all for your replies!

If just implemented an easy bang-bang controller with hysteresis and will start testing it this afternoon.

Greetings,
Josef

If the problem is the long distance between the source of air and the chamber, could you measure the humidity much closer to the source?

This is unfortunately not possible in the current setting.

The oscillation I measured by using the bang-bang controller was quite sensitive to the ambient humidity and in many cases far worse than the PID controller I used previously.

After a few tests with manually setting the duty cycle und just waiting for the value to settle, I found out that depending on the environment temperature and humidity, a duty cycle of around 60 ... 80 % is needed to obtain the required humidity. My (freely speaking quite hacky "solution") for now, is to use my original PID controller and set the lower bound to 50 % duty cycle. Hence, the oscillation dampened and for now only around half the amplitude I obtained with a 0 % duty cycle lower bound.

Hello together,

since the environment temperature und humidity changed quite a bit within the last two weeks, my "solution" using a 50% duty cycle as lower bound was not anymore as effective as before. Since both increased quite a bit, I got a very pronounced overshoot reaction and the mean humidity stayed too high for most of the time (within this environment, the 50% lower bound were simply too high...). So I searched for an other solution, which I would like to share with you.

The basic idea is to use the suggested bang-bang controller, but I modiefied it a bit. Below the lower bound the humdidifier is now completely turned on and above the higher bound, it is turned off. In between the two bounds, if the humidity increased within the last 10 s (cycle time 1 s), it is turned of - if it decreases, the humidifier is turned on. This "solution" improved the over- and undershooting reactions by approximately a factor of 2 compared to the bang bang controller.

#define VALVEPIN 4

#define CC_H_WINDOWSIZE 1000

#define CC_H_PREV_N_VALS 10
double cc_h_prev[10] = {0.};

double cc_h;
double cc_h_high = 60.2;
double cc_low = 58.8;

unsigned long cc_h_windowStart = 0;

void loop()
{
	unsigned long now = millis();
	if (now - cc_h_windowStart >= CC_H_WINDOWSIZE)
	{
		cc_h_windowStart = now;
		
		if (cc_h > cc_h_high)
		{
			digitalWrite(VALVEPIN, LOW);
		} 
		else if (cc_h < cc_low)
		{
			digitalWrite(VALVEPIN, HIGH);
		}
		else
		{
			if ((cc_h_prev[0] - cc_h) > 0)
			{
				// Negative gradient --> Turn on
				digitalWrite(VALVEPIN, HIGH);
			}
			else
			{
				digitalWrite(VALVEPIN, LOW);
			}

		}
		
		// Shift values
		memcpy(cc_h_prev, &cc_h_prev[1], sizeof(cc_h_prev) - sizeof(double));
		cc_h_prev[CC_H_PREV_N_VALS - 1] = cc_h;
	}
}

Maybe, there is someone who will profit thereof, like if profited from your generous input :slight_smile:

Best greetings,
Josef

Nice.

Let’s call it BBD, bang bang derivative.

a7