OpenHumidistat: Humidity-controlled experiments for everyone

Humidity control is a crucial element for a wide variety of experiments. Yet, often naive methods are used that do not yield stable regulation of the humidity, are slow, or are inflexible. PID-based electropneumatic humidistats solve these problems, but commercial devices are not widespread, typically proprietary and/or prohibitively expensive. Here we describe OpenHumidistat: a free and open-source humidistat for laboratory-scale humidity control that is affordable (<500 EUR) and easy to build. The design is based around mixing a humid and dry air flow in varying proportions, using proportional solenoid valves and flow sensors to control flow rates. The mixed flow is led into a measurement chamber, which contains a humidity sensor to provide feedback to the controller, to achieve closed-loop humidity control.


Hardware in context
Humidity control is essential for a plethora of biological, chemical, and physical experiments [1], some of which simply require a stable, constant humidity, while in others the humidity might be an experimental variable which is varied. In either case, careful humidity control is necessary. A device that accomplishes this is called a humidity controller or humidistat (analogous to a thermostat for temperature).
Systems designed to adjust the humidity in experiments are often based on equilibria of water vapour with salt solutions [2,3], local heating of a water bath in a reservoir chamber [4,5], or using an air stream composed of a mixture of approximately dry and water-saturated air [6,7,8,9] that is manually mixed in varying ratios. The first method provides stable control, but is very inflexible: for every value of humidity, a specific salt is required. This moreover means that when an experiment calls for sweeping a range of humidities, the salt solution has to be manually swapped out for another one when moving to the next humidity point, interrupting the experiment [10]. Depending on the size of the chamber, equilibration also can take quite long. For this reason, this method is mainly suited for experiments which only require long-term stabilisation of the humidity on a single value in a air-tight chamber. The other methods are more suited to experiments requiring changing humidities, but typically yield poor control due to the lack of (automatic) feedback. This, combined with the typically long response times makes them arduous to regulate manually and prone to external disturbances. Therefore, humidistats based on electropneumatic devices have been developed. In these devices, electronically-driven valves are used to mix a humid and dry air stream in varying proportions. A humidity sensor in a chamber is used to provide feedback to the controller actuating the valves. The advantages of such humidistats are fast settling times, good disturbance rejection, broad attainable humidity range, flexibility and portability, and easy, intuitive operation. Electropneumatic humidistats are commercially available, but are often unsuitable to many labs because they are typically prohibitively expensive, proprietary, and/or tailored to a specific experimental setup.
An open-source design of an electropneumatic humidistat using solenoid valves driven by an Arduino was published by Boulogne [11]. This was followed by the HumidOSH [12], which is a self-contained environmental chamber utilising a similar principle. In this design, ordinary (non-proportional) solenoid valves are opened/closed for varying time periods to control the ratio of humid and dry air led into a chamber. This control method, called time-proportional control, can be regarded as PWM (Pulse-Width Modulation), except on longer timescales. This method then relies on the inherent (diffusion-driven) time averaging properties of the comparatively long residence time of the chamber to attain a stable humidity. For this reason, the minimum settling times are inherently limited: Boulogne reports settling times on the order of 1/2 h, and the HumidOSH takes several days. Reducing the residence time of the chamber is not an option since in that case, the resulting chamber humidity will fluctuate significantly over time. Hence, when quicker dynamics or small chambers 1 are desired, a more delicate control technique is required.
In our previous publication [13], we presented an affordable open-source humidistat for lab-scale applications based on an Arduino microcontroller, a set of proportional solenoid valves, a gas washing bottle, and a humidity sensor. Using closed-loop feedback, humidity control is achieved in a small measurement chamber by regulating the ratio of dry and humid air flows. Because this design utilises proportional solenoid valves which allow for analog control of the flow rate through the valve, stable humidity control can be achieved even in small chambers. It achieved fast regulation of humidity over a wide range (10-95%) with settling times within 30 s.
Here, we improve upon that design, primarily by moving to cascade control, in which the individual flow rates are closed-loop controlled as well for improved robustness and dynamic performance. This is comparable to the approach taken by Gaponenko et al. [10], but avoiding the use of (expensive) off-the-shelf mass flow controllers. Furthermore, many small improvements to both the hardware and firmware are made, most notably an upgraded humidity sensor, a much larger graphical display, and a more powerful microcontroller. Meanwhile, the firmware is (re)written to include the cascade PID control loop with feed-forward and a new graphical user interface to match the new display, while care is taken to keep the code modular and fully configurable, such that it is compatible with (any combination of) both 'original' and upgraded components. Finally, by including comprehensive build instructions, printed circuit board (PCB) designs for the electronic circuits, and 3D printable models for the enclosure, this paper also facilitates reproducibility of the device.

Principle
The working principle behind the humidistat is the mixing of a humid and dry airflow in varying proportions. In order to adjust the flow rates of humid and dry air, proportional solenoid valves are utilised, which provide analog electronical control over the flow rates. A PID controller running on a Teensy LC microcontroller board [14] actuates the valves in order to attain the desired humidity in a chamber, which contains a humidity sensor to provide feedback to the controller ( Figure 1).

PID control
PID control is a closed-loop control scheme, which means that feedback is employed to control some process variable (PV from here on). The letters P, I, and D stand for proportional, integral, and derivative respectively, and refer to the three actions included in the control scheme. The PID controller seeks to close the error between the PV and the user-desired value called the setpoint (SP) by actuating some final control element (FCE) whose state is represented by a control variable (CV). Often, the FCE is a valve, or sometimes a electric device such as a heater. [15,16,17] The CV is the sum of the three principal components of the PID controller: the proportional term, which is given by the instantaneous error between the PV and SP; the integral term, which is given by the integral of the error over time; and the derivative term, which is given by the rate of change of the error with respect to time. Each term is multiplied by its respective gain (K p , K i , and K d ), as expressed by the following equation: Here, u(t) is the control variable and e(t) = r(t) − y(t) is the error given by the difference between the SP (r(t)) and PV (y(t)). x is a bound variable within the integral. In practice, in digital PID controllers, this continuous PID equation is discretised and the integral and derivative are approximated by finite difference methods. [17] The PID controller can be augmented by a feed-forward action, which does not incorporate feedback, but tries to (partially) control the plant by using some preknown model of it. An example of this is simply including the setpoint multiplied by a feed-forward gain K ff :

Controller design
In the first version of the humidistat [13], a single control loop exists: the humidity controller. It directly regulates the humidity in the chamber by actuating the two valves as FCEs ( Figure 2). While this works reasonably well after careful tuning of the PID gains, it suffers from lack of robustness. Most notably, it is sensitive to the feed pressure, and finding an universal 'sweet spot' for the PID gains is difficult [13].
The main reason for the challenges in tuning the controller stems from imperfect actuators. The proportional solenoid valve response is non-linear and also exhibits rather severe hysteresis (from plunger stiction). This adversely affects the controller performance in several ways: first of all, the non-linearity results  in a operating point-dependent process gain. Hence, the optimal PID gains for moderate humidity values are different from those for extreme humidity values. For example, because of the S-shaped flow rate-CV curve, a tuning parameter set that provides good performance for extreme humidity values might cause unstable/underdamped behaviour around moderate values. Moreover, the total flow rate is only constant if the valve response is linear. Non-linearities in the valve response cause variations in the total flow rate with CV, which in turn alter the process dynamics since the plant's response time and dead time depend on the total flow rate. Finally, hysteresis in the valve response can induce oscillation of the controller [18].
An elegant way to improve the dynamic performance and stability of a PID controller is to employ cascade control ( Figure 3). In that case, there is one outer control loop which controls humidity, and two inner loops that control flow: one for each valve. The outer controller does not directly actuate the valves, but its output is fed into the (flow rate) setpoints of the two inner control loops [15,17]. As such, the inner control loops essentially constitute custom flow controllers. Naturally, such a setup requires flow sensors besides just a humidity sensor.
A cascade controller can improve dynamic performance by exploiting a separation of characteristic timescales in the plant: the inner loops, controlling flow, have much faster dynamics than the outer loop because the inner PVs (flow rates) respond much quicker to changes than the outer PV (chamber humidity) [15,17]. Moreover, a cascade controller is better able to deal with hysteresis in the plant [19].
Another advantage of using a cascade controller is that the actuator non-linearities are much less of a concern since they are dealt with in the inner loop [17]; the flow rates are closed-loop controlled. As a result, the total flow rate can be kept constant despite non-linear valve response [15]. This is difficult to achieve without closedloop flow rate control: one could try to compensate for the non-linear valve response, but that requires carefully characterising the flow rate-CV curve, which is complicated by hysteresis and dependence on external factors such as the feed pressure. Closed-loop control also removes the need for carefully calibrating the zero-flow solenoid duty cycle.

Microcontroller board
As a microcontroller board, a Teensy LC [14] is used, which is similar in terms of price to the more popular Arduino Uno which was used in the previous version, but features much improved specifications: it is faster, has more flash and RAM and more I/O pins. This allows for a more complex UI. A comparison between the specifications of the Teensy LC and Arduino Uno is given in Table 1.
OpenHumidistat can be used fully standalone, but it is possible to connect it to a PC to monitor and/or log the controller parameters using a Python utility.

UI
The 16x2 character display from the previous version has been upgraded to a larger, graphical 128x64 LCD.
Meanwhile, similarly to the previous version, a 5button keypad with 4 directional and a 'select' button is used. This keypad is implemented as a resistance ladder, such that it only occupies a single analog input pin on the microcontroller.
If desired, this keypad could relatively simply be interchanged for an alternative input method, such as a joystick or rotary encoder.

Sensors
The humidity sensor was upgraded from the DHT22/ AM2302 to the more reliable and accurate Sensirion SHT-85 [20]. This sensor, although more expensive, is also significantly smaller, which makes it easier to fit to measurement chambers.
In order to provide flow rate feedback for closed-loop flow control, MEMS flow sensors from Omron (model D6F-P0010A1) were used. These sensors output the flow rate as an analog voltage signal, and have a maximum measurable flow rate of 1 L min −1 .

Valves
In order to achieve analog control over the flow rates, proportional solenoid valves were used. Unchanged from the previous version, PVQ30-series miniature proportional solenoid valves from SMC were used.
These valves are driven by a (smoothed) PWM current that is generated by a custom solenoid valve driver (see 3.2).

Humidifier
One of the two air streams is humidified by bubbling it through water in two gas washing bottles. Two bottles are connected in series to ensure sufficient water vapour saturation at high flow rates.
This method is simple and does not require any electronics. Moreover, unlike ultrasonic humidifiers, it strictly produces vapour, and no aerosols.

Summary
In summary, OpenHumidistat features: • Standalone control of humidity in a chamber

Electronic circuits
Electronic circuit schematics and PCB designs are provided for two boards: a mainboard and a solenoid driver board. Schematics of the circuits are shown in Figure 4 and 5 respectively.
The microcontroller board (a Teensy LC) can be plugged onto the mainboard, which provides headers to connect to all peripherals (solenoid driver board, sensors, keypad, display). Besides headers, it contains a number of pull-up/down resistors and a Schottky diode between the USB V BUS and the device's +5V net, to avoid potentially backpowering the USB host in case the device is powered by its own power supply and USB simultaneously.  Grand total 489.10 The solenoid driver board receives low-power PWM control signals from the microcontroller, and uses that to drive the (two) solenoid valves. More specifically, it comprises a 2-channel VCCS (Voltage-Controlled Current Sink), to drive the solenoid valves in a constantcurrent manner. This is necessary because the solenoids heat up considerably during normal operation, and this consequently alters their resistance. Without a constant-current driver, the solenoid current, which is the parameter that controls the flow rate, would drift with temperature. Design details about the VCCS are available in the supplementary material of the previous publication [13].
The solenoids require 12 V. This is provided by an external power supply, which is connected to header J4 on the solenoid driver board. To allow the microcontroller and peripherals also to be powered through this power supply, the solenoid driver board includes a linear voltage regulator which creates a +5V line from the +12V supply.
An archive containing Gerber and drill files of the PCB designs, as well as source files of the circuit schematics and PCB designs which can be opened in the free EDA KiCad [21] are made available under the CERN-OHL-S.

Firmware
The firmware running on the microcontroller is written in C++ with the Arduino Core framework and the PlatformIO [22] build system. It is written using the object-oriented programming paradigm, and as such consists of a number of modular classes.
The source is available under the GNU GPL v3.

Enclosure
CAD models for the enclosure are provided: source files (SolidWorks) and STL files for 3D printing.

Bill of materials
The full bill of materials is available at https://dx. doi.org/10.17605/OSF.IO/F5U6E.
We note that electronic components are listed with their prices per unit, but are commonly purchased in larger quantities (usually at least 10). This means that the actual cost might be inflated somewhat if one does not already have access to these (rather common) electronic components. Still, since these components are relatively cheap, even having to purchase 10 times the required amount does not increase the total price of the device by much.
Electronic and pneumatic components can be sourced from retailers such as RS Components, Mouser, Farnell, and Digikey. The gas washing bottles can be sourced   from laboratory glassware distributors such as VWR and Fisher Scientific.
A summarised version of the BoM can be found in Table 3. It can be seen that the custom parts of the device are very cheap to build, and the majority of the total cost of the device comes from off-the-shelf components such as the humidity sensor, the flow sensors, gas washing bottles, and most notably the proportional solenoid valves. The total cost of the materials needed to build OpenHumidistat is less than €500.

Materials and tools
Refer to the BoM (section 4) for a comprehensive list of materials to order. Detailed instructions can be found in the README.md file included with the firmware (see section 3.3).

Electronics
After obtaining the electronic components and the PCBs, the boards can be assembled. When populating the PCBs with the components, use the reference designators printed in silkscreen on the PCB and the BoM (or circuit schematic) to look up which component goes where. Figure 6 can also be used as a visual reference.

Solenoid driver board
1. The MOSFETs and the linear regulator used on the solenoid driver board (Q1, Q2, and U2) dissipate power as heat and should have heatsinks attached for cooling. Screw these on before soldering them onto the board.

Populate the board with the components.
(a) Assembled mainboard with Teensy installed.

Figure 7
• It is recommended to start with the small components (resistors, diodes, disc capacitors), and solder the largest components (trimpots and TO-220 packages with heatsinks) last.
• For the DIP-8 IC (the LM358 opamp, U1), it is recommended to use a socket in order to prevent overheating the IC during soldering and to facilitate replacement if necessary.
When done, the board should look like in Figure 7b.

Mainboard
The solenoid driver board is all THT (Through-Hole Technology) for easy hand-soldering, but the mainboard contains a few SMD (Surface Mount Device) components because of space constraints. However, it should still be doable to hand-solder these as long as it is done carefully and small-gauge solder wire is used.
1. Start by disconnecting the Teensy's +5V and V BUS nets by cutting the trace between the two respective pads using a knife or sharp flat screwdriver, as described in the Teensy documentation [23] (Option #1). The V BUS and +5V nets are connected through a Schottky diode on the mainboard.
2. If the Teensy came without headers pre-installed, solder (male) headers to the microcontroller board.
3. Solder the SMD components (7 resistors and a Schottky diode) onto the board. It will be a lot easier to do so before the THT components are in place.
• If the thermistors are not used, the resistors R4, R5, R6, and R7 may be omitted.

Solder the rest of the components (headers and sockets) onto the board.
When done, the board should look like in Figure 7a.
Cut off the component leads after they are secured in place with solder joints. Make sure all joints are sound and that there are no unintended solder bridges that could inadvertently short pads. Also make sure that all polarised components (diodes, transistors, ICs, connectors) are installed the right way around.

Cables and connectors
The several boards and peripherals are interconnected through (DuPont) jumper cables. Since these connectors are not keyed, it is good practise to plug the female DuPont connectors to their headers with their contacts facing out in order to not confuse the polarity of the connectors.

Humidity sensor(s)
1. Create the humidity sensor cable: solder one end of a length (1-2 m recommended, depending on the desired distance between the OpenHumidistat and the measurement chamber) of 4-wire data cable to the SHT-85 sensor and crimp a 6P4C plug on the other end. Mind the pin order: it should match that of the header marked I2C SHT85 on the mainboard.
2. Make a cable to connect the female modular jack (which will be mounted in the front panel) to the mainboard: crimp a 4-pin female DuPont connector on one end, and solder the wires on the other end to the pins of the female modular jack. Again, mind the order of the pins: the cable should preserve it along the entire path from the header on the mainboard, to the actual SHT-85 sensor. Use a multimeter to verify the continuity of the connections, if required.
For backwards compatibility, the mainboard also includes a header for connecting a DHT22/AM2302 humidity sensor. If desired, the above procedure can be repeated for this sensor type.

Power
Make a cable to connect the the barrel jack (which will be mounted in the front panel) to the +12V header (J4) on the solenoid driver board. For this, wire thicker than that used for the signal cables should be used: at least 0.5 mm 2 (AWG 20).  Usually, it is 'center positive', but verify this: reverse polarity will damage the electronics.
2. Use heat-shrink tubing to insulate the end of the barrel jack.

Solenoid valves
1. Crimp female 2-pin JST-XH connectors to the solenoid valve wires. Mind the polarity: the red wire should correspond to the positive bottom pin on headers J1/J2 (marked +12V).

Thermistors
Optionally, 4 thermistors can be installed for temperature monitoring of the solenoids and MOSFETs. For this, 1. Crimp female 2-pin DuPont connectors to the thermistor cables.
2. Glue or otherwise attach the thermistors to the solenoid valves and MOSFET heatsinks.

Other peripherals
The other peripherals (display, keypad, flow sensors) are connected using (female-female) DuPont cables, which can be simply used as-is.
Refer to Table 4 for connecting the display module to the mainboard.

Testing and calibration
1. Partially assemble the device: install the Teensy onto the mainboard and connect the solenoid driver board, display, keypad, and flow sensors to the mainboard.
2. When connecting the device over USB (connected to the Teensy), the device should power up. Check that the firmware is running, that the interface is shown on the display, and that you can interact with it using the keypad.
3. Calibrate the solenoid driver by adjusting the trimpots. To do this: (a) Make sure there is a 3.3 V signal applied to the pins S1/S2 of the solenoid driver board. This is most straightforwardly done by having it connected to the mainboard, and having the microcontroller output a 100% duty cycle signal on both of the channels. This should happen automatically, as the flow controllers' CVs will saturate with no actual flow through the sensors.
(b) After verifying on the display that the microcontroller is outputting a 100% duty cycle signal on both channels, use a multimeter to measure the voltage between each of the test points TP1 and TP2, and ground. Adjust each trimpot (RV1 and RV2) until the voltage at the respective test point reads exactly 0.330 V.

Enclosure
1. Print the enclosure using the included STL files (two parts: the enclosure, and the frontpanel) 2. Make a base plate onto which to affix the compon- (c) Affix the DC barrel jack.
6. Install components into the frontpanel: (a) Glue the modular jacks into place.
(b) Affix the pneumatic bulkhead union couplings.
7. You can then slide the baseplate including components into the enclosure, and screw the frontpanel on (after connecting cables and tubing, of course). See 5.8 for details on the pneumatic connections.

Measurement chamber
A wide variety of measurement chambers can be used, depending on the envisioned application of the humidistat. The only requirements are that it must fit the humidity sensor, and that it should be reasonably closed; if there is too much exchange with ambient air, it might be difficult to reach extreme humidity values.
The device is tested with chambers with volumes of several cL, but smaller or larger chambers can be used if desired. Note that larger chambers will have larger residence times, which will in turn limit the speed of the controller.
If for a particular experimental setup it is undesirable or impossible to fit the humidity sensor in the measurement chamber, it also possible to construct a 'pre-chamber' containing just the humidity sensor, which is then connected between the humidistat and the measurement chamber. This pre-chamber should be completely air-tight in this case. The advantage of this configuration is the versatility: the humidistat can be used with practically every experimental setup featuring a flow cell this way without any modification. A potential disadvantage arises when the actual measurement chamber is too open, in which case exchange with the ambient air occurs and the actual humidity will deviate from the measured humidity in the pre-chamber.

Assembling the device
Once all the individual assemblies are completed, the full device can be assembled.
2. Make the pneumatic connections using PU tubing. See Figure 9 for reference.

Operation instructions
To turn on the device, connect the external 12 V power supply to the DC jack. The microcontroller (and peripherals) can also be powered from the USB port, but for operation of the valves, a 12 V supply is required.
Instruction for the usage of the UI can be found in the README.md included with the firmware.

Humidifier
1. Fill the gas washing bottles with (DI) water.
2. Connect the two gas washing bottles in series.
3. Connect the gas washing bottles to the designated ports on the device. Make sure the direction is correct: if it is wrong, it will flush water into the system.

Chamber
1. Using PU tubing, connect the outlet port of the device to the measurement chamber.
2. Also connect the humidity sensor installed in this measurement chamber to the device.

Feed
As supply gas, either dry air or nitrogen can be used.
Although not strictly required, the solenoid valves perform better when it is pressure-regulated (at 1-2 bar).
1. Connect the nitrogen/air supply to the inlet port of the device.
2. Increase the feed pressure until the OpenHumidistat's flow controllers achieve sufficient flow (recognisable by the stopping of blinking of the flow controller labels on the display). Note that you need at least about 1 bar for the solenoid valves to open.

Testing and tuning
The system contains two solenoid valves and two flow sensors: one set for humid flow, and one for dry flow. Hence, there are 4 ways to connect these, but they must be connected in the right configuration for the controllers to work properly. To test this: 1. Turn on the device.
2. With the humidity controller in manual mode and feed pressure applied to the device's inlet: • If the flow controllers manage to successfully regulate the flow rates, the flow sensors correctly correspond to the solenoid valves.
• If both flow controllers saturate (one CV goes to 0%, while the other goes to 100%), the flow controllers are erroneously trying to control each other's flow. In this case, swap either: the pneumatic connections between the flow sensors and the solenoid valves, the connectors of either the flow sensors (on the mainboard) or the solenoid valves (on the solenoid driver board), or the pin numbers of either the flow sensors or the solenoid driver channels in the firmware's config file.
3. Turn the humidity controller into automatic mode.
• If the humidity controller manages to regulate the humidity by converging on the SP (even if doing so slowly, or with overshoot), the device is configured correctly.
• If the humidity controller saturates (the CV goes to either 0% or 100% and stays there), the humid and dry flows are swapped. In this case, swap either: the pin numbers of both the flow sensors and solenoid driver channels in the firmware's config file, the electrical connectors of both the flow sensors and the solenoid valves or the pneumatic connections of the dry and wet flows (disconnect the tubing from the flow sensor going to the humidifier and connect it directly to the union tee, and disconnect the tubing going directly going to the union tee and connect it to bulkhead union going to the humidifier).
4. Tune the two PID controllers (outer humidity controller and inner flow controllers) appropriately for the total flow rate and measurement chamber used by adjusting the controller parameters. Defaults for these can be set in config.h, but they can also be overridden using the UI itself in a standalone manner. Section 7.1 illustrates the tuning procedure.

Hazards
Because the outlet of the gas washing bottles is subject to back pressure from the dry flow, there exists a risk of backflow through the gas washing bottles when the inlet of the gas washing bottles is left unconnected, or when the humid solenoid valve is closed (open) and the tubing and/or connections from there to the gas washing bottles are not completely air-tight. This is problematic because it will siphon liquid water out the gas washing bottles into the system.
Users should be alert of this potential issue, which can be spotted by the water level rising in the tubes of the gas washing bottles. If this problem occurs, it is strongly recommended to install a check valve (e.g. SMC AKH, Festo H-QS) in line with the gas washing bottles, which should prevent any backflow.

Tuning
A manual tuning procedure is outlined below. This was performed with a 'universal pre-chamber' with a volume of 25 mL, which with the used total flow rate of 2 L min −1 gives a residence time of 0.75 s.

Flow controllers
The inner control loops, constituting flow controllers, are tuned as PI-only controllers with a high K i , so that   they essentially are integral controllers. This works very well because the plant, that is, the flow though the solenoid valve, is a fully self-regulating process that, although non-linear and exhibiting hysteresis, fortunately almost does not have any dead or response time: it responds virtually instantly to changes that the controller makes by actuating the valves. Hence, overshoot is barely of concern and this controller is very stable. Because the signal from the flow sensors is rather noisy and because it is not necessary in this case, derivative action is not used (K d = 0). [15] As mentioned in the first section, a major improvement over the single-loop controller is that it is no longer critical to meticulously calibrate the minimum value of the CV (solenoid duty cycle). Whereas this was crucial in the previous design to make sure the resulting total combined flow rate is reasonably constant and no deadband exists at the lower range of the solenoid response, with closed-loop flow control the this zero-flow duty cycle is automatically 'found' by the flow controller. In the cascade control scheme this parameter still exists, but solely for the proper functioning of the anti integral windup mechanism.

Humidity controller
For the (outer) humidity controller, is helpful to start off by considering a purely feed-forward (ff) controller.
In that case, the controller solely acts on the SP, and there is no feedback. In other words, the CV is purely a function of the SP.
Feed-forward-only controllers like these are rarely ever sufficient because they cannot deal with external disturbances (after all, if they were, the entire PID control-ler would be unnecessary), but including a significant feed-forward action in our outer humidity controller turns out to be a useful starting point. We set K ff to 0.01, since that creates a CV of 1 (the maximum) for a SP of 100 (%) 2 . The implicit model behind this feed-forward action is that the resulting humidity of the mixed-together dry and humid air is proportional to the ratio of those two flow rates. This is a reasonable initial guess that nevertheless fails when the 'dry' air is slightly moist, the humid air is not fully saturated, or when the plant is confronted with other external disturbances, but that does not matter, since the feedback action (PID) exists to correct for those. The main benefit of partly relying on feed-forward action, is that this can supplant most of the integral action in providing the 'offset', yet without the potential for destabilising the controller.
The dynamic response of the feed-forward-only controller is shown in Figure 10a. Although it is physically impossible for this controller to oscillate or overshoot, the PV values it settles on deviate significantly from the SP (for most values) and the settling times are far from optimal.
As an example, a small amount of integral action is then added to help with static deviations from the aforementioned ideal model. The resulting response is shown in Figure 10b. The controller now eventually homes in on the SP, but only rather slowly, and after considerably overshooting it. This is an inherent effect of high integral action on a plant with some time delay [15,16].
Next, we add proportional action. This makes the controller act briefly on the error between the PV and SP, and has the effect of reducing the accumulation time of the integral action, so the settling times improve (Figure 11a).

Figure 11
Derivative action is also added to accelerate the dynamic response by reducing overshoot, and finally the response is reasonably satisfactory, with good setpoint tracking, and settling times on the order of 10 s (Figure 11b).

Robustness
Due to closed-loop flow control, the system is a lot more robust to various feed pressures. Whereas with the single-loop humidistat variations in feed pressure and/or chamber pressure drop led to varying flow rates, which in turn affects the solenoid valve response and chamber response time, the flow controllers in the cascade humidity controller always keep the total flow rate constant despite varying feed pressures. This makes the controller more portable, especially in situations where the feed pressure is not controlled.

Conclusion and outlook
We presented the design of a free and open-source humidistat. Due to the usage of cascade PID control, in which the dry and humid flow rates are also closed-loop controlled, the dynamic performance and robustness was significantly improved over our previous design in which a single control loop was used: Settling times are improved from~30 s to~10 s.
The versatility of the device makes it broadly applicable, bringing humidity control to a wide variety of experimental and analytical setups.
As a final note, we want to mention the possibility of generalising the OpenHumidistat beyond water vapour. By swapping the water in the gas washing bottles for a different substance, this design could readily function as a vapour pressure controller for arbitrary vapours, provided that an appropriate vapour sensor for it exists.

Declaration of competing interest
The authors declare no competing interests.