YouTube Video: https://www.youtube.com/watch?v=1OjPXJKbuPw
This project involves two liquid-filled reservoirs, labeled A and B. Reservoir A serves as a supply tank, and its liquid level is not critical. Reservoir B, however, requires a stable liquid level, which is the primary control objective. An ultrasonic distance sensor is mounted vertically above Reservoir B to measure the liquid depth, providing distance readings denoted as x₁. A peristaltic liquid pump connects the two reservoirs. The pump's role is to transfer excess liquid from Reservoir B to Reservoir A or to draw liquid from Reservoir A to replenish Reservoir B, depending on the measured liquid level.
To maintain the desired liquid level in Reservoir B, a PID (Proportional-Integral-Derivative) control algorithm is implemented. The controller minimizes the error between the setpoint and the measured value by adjusting the pump's operation. The PID control law is defined as:
u(t) = Kp * e(t) + Ki * ∫e(t)dt + Kd * de(t)/dt
Where:
e(t)
is the error between the measured and target level (e.g., e(t) = x₁ - target)Kp
is the proportional gainKi
is the integral gainKd
is the derivative gainu(t)
is the output used to determine the pump’s direction and speed (via PWM)
This PID controller ensures that the liquid level in Reservoir B remains stable despite disturbances or changes in system dynamics.
- GNU Octave (Tested on version 10 (2025-03-25))
- Arduino IDE (Tested on version 1.8.19 (Store 1.8.57.0))
- USB connection to Arduino board (Uno, Nano, etc.)
instrument-control
package for Octave
- Arduino Uno
- HC-SR04: Ultrasonic Sound Sensor
- L298N: H BRIDGE
- 12V 3x5 PUM: Peristaltic Water Pump
- 12V ADAPTER: Power Supply for the Pump
- 9V BATTERY: Power Supply for Arduino
Here is the connection map of the system:
COMPONENT | DESCRIPTION | COMPONENT PIN | CARD PIN | CARD |
---|---|---|---|---|
HC-SR04 | Ultrasonic Sound Sensor | TRIG | D6 | UNO |
HC-SR04 | Ultrasonic Sound Sensor | ECHO | D7 | UNO |
L298N | H BRIDGE | IN1 | D8 | UNO |
L298N | H BRIDGE | IN2 | D9 | UNO |
L298N | H BRIDGE | ENA | D10 (PWM) | UNO |
12V ADAPTER | POWER SUPPLY | + / - | L298N | |
12V 3x5 PUMP | Peristaltic Water Pump | + | OUT1 | L298N |
12V 3x5 PUMP | Peristaltic Water Pump | - | OUT2 | L298N |
Follow the steps below to set up the environment for PID-controlled liquid transfer.
-
Install the
instrument-control
package:pkg install -forge instrument-control pkg load instrument-control
-
Clone this repository or download the source code:
git clone https://github.com/DevBD1/PID_Controlled_Liquid_Transfer.git cd PID_Controlled_Liquid_Transfer
-
(Optional) If you have
.env
or calibration constants, place them in the root folder. -
Make sure your Arduino is connected via
COM3
or change the port in the script:s = serialport("COM3", 9600);
- Open
arduino/transfer_serial.ino
in Arduino IDE. - Select your correct board and COM port.
- Upload the sketch.
To test the system and determine the standard deviation of sensor inputs:
- Run
matlab/standard_deviation/log_realistic.m
script - Input the direction of the pump for test
- Input the repeat count
- Check the generated .csv file
- Run
matlab/standard_deviation/analyse.m
script - Read the output, the script will generate a variable at the end
- Check the generated
pid_tolerance.mat
file
To start full PID control:
- Run
matlab/pid_control_serialport_mapped.m
script
pid_control_serialport_mapped.m
You can modify the PID constants and port settings at the top of the .m
files:
Kp = 40;
Ki = 0.5;
Kd = 20;
s = serialport("COM3", 9600); % Change if needed
Use log_static.m when the reservoir B is empty. The result is your max. height.
Fill or Empty
-> dir: .../matlab/fill_or_empty.mStop
-> dir: .../matlab/stop.m