An Open-Source Platform Enabling Continuous, Low-Flow Control for Long-Term Operation in Biotechnology Systems
A GUI software and hardware platform for imposing flow rates and behaviors in a DIY pump mechanism. Supports multiple pump connections, four flow behavior modes, scheduled command sequences, and experiment file generation.
- Requirements
- Project Structure
- Setup
- Running the Application
- GUI Overview
- Connecting Pumps
- Pump Controls
- Flow Behaviors
- Pause / Resume / Restart
- Text File Scheduling
- Create Experiment Dialog
- Text File Format
- Arduino Command Protocol
- Troubleshooting
- Python 3.8+
- PyQt5
- pyserial
- Arduino board with the DSCPM firmware loaded (
pump_JS_07222025.ino)
Install Python dependencies:
pip install PyQt5 pyserialDSCPM_v2/
├── Arduino_code/
│ └── pump_JS_07222025.ino # Arduino firmware for pump control
├── Python code/
│ ├── GUI.py # Entry point - launches the application
│ ├── pump_app.py # Main window, all GUI logic and widgets
│ ├── arduino_cmds.py # Serial communication wrapper
│ ├── autoport.py # USB port auto-detection and connection
│ └── pump_render.png # Pump image displayed in the GUI
└── README.md
-
Flash the Arduino: Open
Arduino_code/pump_JS_07222025.inoin the Arduino IDE and upload it to your board. The firmware uses pins 9 and 11 for servos and pins 5, 6, 10 for solenoid valves. Baud rate is 9600. -
Connect hardware: Plug the Arduino into your computer via USB. Note the serial number or device path if you plan to use manual connection.
-
Install dependencies: Run
pip install PyQt5 pyserialin your Python environment.
cd "Python code"
python GUI.pyThe Pump GUI window will open.
The interface is organized into rows from top to bottom:
| Row | Section | Purpose |
|---|---|---|
| 0 | Pump Image | Visual reference of the pump hardware |
| 1 | Multi Pump Connect | Connect multiple pumps by entering serial numbers |
| 2 | Connect / Serial | Auto-connect or manually enter a serial number / device path |
| 3 | Flowrate Quick Adjust | Type a number (0–40) to change flow rate on the fly |
| 4 | On/Off + Direction | Turn the pump on/off and toggle flow direction |
| 5 | Flow Behavior | Select a flow mode, enter parameters, and apply |
| 6 | Pause / Resume / Restart | Control scheduled command execution |
| 7 | File Buttons | Create experiment, upload/change/run/exit text files |
| 8 | File Labels | Shows the currently selected file name |
| 9 | File Contents Display | Human-readable preview of the loaded command file |
Click Auto Connect. The software scans USB ports and connects to the first likely Arduino device. The button turns green on success.
Type a USB serial number (e.g. 054433A493735191B7D8) or a device path (e.g. /dev/cu.usbmodem1101) into the serial input field and press Enter.
- Enter the number of pumps (1–10) in the "Connect multiple pumps" field and press Enter.
- A popup window appears - enter the serial number for each pump.
- Click Collect Serial #s. The software connects to each Arduino and adds them to the pump dropdown.
- Use the dropdown to switch between connected pumps.
- Click Pump: OFF to turn the pump on. Sends
123to the Arduino. - Click Pump: ON to turn it off. Sends
0to the Arduino. - The button changes color: green = on, red = off.
- Click the Direction button to toggle between forward (
-->) and backward (<--). Sends321to the Arduino. - Direction only toggles when the pump is on.
Type an integer (0–40) in the flowrate field and press Enter. This sends the number directly to the Arduino, which recalculates the servo delay for that flow rate in uL/min.
The Flow Behavior section provides four modes. Select a mode from the dropdown, fill in the visible parameters, then click Apply Flow to send the command.
Steady flow in one direction.
| Parameter | Description |
|---|---|
| Flow Rate (uL/min) | 0–40 |
Command sent: FLOWA,{rate}
Intermittent on/off bursts.
| Parameter | Description |
|---|---|
| Flow Rate (uL/min) | 0–40 |
| Duty Cycle (0–1) | Fraction of each cycle the pump is active |
| Pulse Freq (Hz) | How many cycles per second |
Command sent: FLOWB,{rate},{duty},{freq}
Back-and-forth flow.
| Parameter | Description |
|---|---|
| Flow Rate (uL/min) | 0–40 |
| Osc Freq (Hz) | Oscillation frequency |
| Osc Amplitude | Amplitude of the oscillation |
Command sent: FLOWC,{rate},{freq},{amplitude}
Pulsed bursts of oscillatory flow - combines both behaviors.
| Parameter | Description |
|---|---|
| Flow Rate (uL/min) | 0–40 |
| Pulse Freq (Hz) | Frequency of the pulse envelope |
| Duty Cycle (0–1) | Fraction of each pulse cycle that is active |
| Osc Amplitude | Amplitude of the oscillation within each pulse |
| Osc Freq (Hz) | Frequency of the oscillation within each pulse |
Command sent: FLOWD,{rate},{pulse_freq},{duty},{osc_amplitude},{osc_freq}
Note: The Arduino firmware must be updated to parse and execute these
FLOWcommands. The current firmware only handles constant flow via numeric flow rate values.
These buttons control scheduled command execution (from text files or generated experiments):
| Button | Action |
|---|---|
| Pause | Sends 0 to stop the pump. Freezes the command scheduler. All remaining command times are shifted forward so relative timing is preserved on resume. |
| Resume | Sends 123 to restart the pump. Unfreezes the scheduler and continues from where it left off. |
| Restart Cycle | Stops the current execution entirely, recalculates all command times from the original delays, and starts the full sequence over from the beginning. |
You can run pre-written command sequences from .txt files.
Click Upload .txt file, browse to your file, and select it. The file name appears in the label and its contents are displayed in the preview area.
Click Run .txt file. The software parses the file, matches serial numbers to connected boards, and begins executing commands on a background thread at the scheduled times.
- If a worker is already running, new commands are merged into the existing schedule.
- If a serial number in the file doesn't match any connected board but only one board is connected, it falls back to that board.
Click Change current file to cycle through previously uploaded files.
Click Exit current file to kill the running scheduler, stop the pump, and clear all scheduled commands.
Click the purple Create Experiment button to open a dialog for building command sequences visually.
- Select a pump from the dropdown (uses connected pump names).
- Enter the time in seconds from the start of the experiment.
- Choose a behavior: Turn On, Turn Off, Change Direction, Constant, Pulse, Oscillation, or Pulse of Oscillation.
- Fill in the parameters that appear for the selected behavior.
- Click Add Step. The step appears in the table below.
- Repeat for all steps in your experiment.
- Select a row in the table and click Remove Selected to delete it.
- Steps are sorted by time when the file is generated.
Click Generate & Save File. A save dialog appears - choose a location and filename. The software:
- Writes the
.txtfile to disk in the standard command format. - Loads it as the current file in the main GUI.
- Displays the parsed commands in the file contents preview.
You can then click Run .txt file to execute the experiment immediately.
Command files use this format, with entries separated by %%%%%%%%%:
SERIAL*********COMMAND#########DELAY%%%%%%%%%SERIAL*********COMMAND#########DELAY
| Field | Description |
|---|---|
SERIAL |
The Arduino's USB serial number (e.g. 054433A493735191B7D8) |
COMMAND |
Any valid command string (see table below) |
DELAY |
Time in seconds from the start of execution |
054433A493735191B7D8*********123#########0%%%%%%%%%054433A493735191B7D8*********FLOWA,10.0#########2%%%%%%%%%054433A493735191B7D8*********FLOWB,15.0,0.5,2.0#########30%%%%%%%%%054433A493735191B7D8*********0#########60
This sequence:
- At 0s - Turn pump on
- At 2s - Constant flow at 10 uL/min
- At 30s - Switch to pulse mode (15 uL/min, 50% duty, 2 Hz)
- At 60s - Turn pump off
Communication runs at 9600 baud. The Arduino sends READY on startup; Python waits for this before proceeding.
| Command | Action |
|---|---|
0 |
Turn pump off. Saves position to EEPROM. |
123 |
Turn pump on. |
321 |
Toggle flow direction. |
456 |
Request status log (position, direction, valve state). |
Any float (e.g. 10.5) |
Set flow rate in uL/min. Recalculates servo delay. |
FLOWA,{rate} |
Constant flow mode (firmware update required). |
FLOWB,{rate},{duty},{freq} |
Pulse mode (firmware update required). |
FLOWC,{rate},{freq},{amp} |
Oscillation mode (firmware update required). |
FLOWD,{rate},{pfreq},{duty},{oamp},{ofreq} |
Pulse of oscillation mode (firmware update required). |
| Response | When |
|---|---|
READY |
On startup, signals handshake complete |
System OFF. Position saved. |
After command 0 |
Pumps ON |
After command 123 |
Direction switched. |
After command 321 |
LOG: Position: X, FWD: Y... |
After command 456 |
Flow rate changed to X uL/min |
After a numeric flow rate command |
App won't start / ModuleNotFoundError
- Make sure you've installed dependencies:
pip install PyQt5 pyserial - Run from inside the
Python code/directory so relative imports work.
"No device found" on connect
- Check that the Arduino is plugged in via USB.
- On macOS, verify the device appears under
/dev/cu.*(runls /dev/cu.*in terminal). - Try entering the device path manually (e.g.
/dev/cu.usbmodem1101).
Connect button turns red
- The auto-detection couldn't find a matching device. Try manual serial entry or check USB connection.
Pump doesn't respond to FLOW commands
- The Arduino firmware (
pump_JS_07222025.ino) does not yet handleFLOWA/FLOWB/FLOWC/FLOWDcommands. Numeric flow rate changes and on/off/direction work. The firmware needs to be updated to parse the new comma-separated flow commands.
Pause/Resume not working
- These buttons only work when a text file schedule is running. For manual control, use the On/Off button directly.
File displays "no valid commands found"
- Check that the file uses the correct format:
SERIAL*********COMMAND#########DELAYwith%%%%%%%%%separators.
Multiple pumps - wrong pump receives commands
- Use the pump dropdown to select which pump you're controlling manually.
- In text files, make sure each command line uses the correct serial number for the target pump.

