1. OD600 (AU)
Current OD600
--AU
Specific growth rate μ
--h⁻¹
Gate decision
--
Sample
--lx
Reference
--lx
Sample:Ref ratio
--×
Bubble/outlier reject
--%
Last measured
--s
Blank not calibrated yet — OD600 is indicative only.
OD600 gating layer (bubbles / air column / level shift)
The estimator handles outliers within one measurement; this layer handles anomalies between measurements. The reported value is the median of the last few accepted readings. The raw estimate is never overwritten — every gate decision is kept in the CSV and raw data, so you can re-run with different thresholds via tools/replay_od.py.
Reported
--
AU
Raw estimate
--
AU
od_p90
--
AU
Pending
--
Rejected in a row
--
Accepted / rejected
--
Press this before a planned operation: the next valid reading is taken as the new level immediately, without waiting for the confirm count and without being flagged as suspicious.
Specific growth rate μ
μ is the least-squares slope of ln(OD600 reported) against time, using gate-accepted readings only. It restarts after a declared operation, a confirmed level shift, a new blank or a different estimator.
🔧 Engineering mode
OD600 measurement & calibration
Load clean media / a blank sample into the flow cuvette before pressing "Calibrate Blank" — it sets the current reading as OD600 = 0. Takes about 3 s to take effect.
LED alignment
Forces the LED continuously ON (instead of the measurement-only pulses) and shows live, unfiltered sample/reference readings so you can watch the ratio while adjusting the optics. OD600 measurement and logging are paused while active. If this page stops polling for 30 s the board exits engineering mode on its own.
Sample (live)
--
Reference (live)
--
Ratio (live)
--
MCU link status & tests
--
Automatic MCU reboot has been removed: on the UNO Q, after a software reset the MCU does not reconnect to the Bridge and only stopping the App or a power cycle recovers it. If the command channel stalls, the red banner appears; stop and restart the App in App Lab, and if that fails unplug the UNO Q for 10 s.
Test tools
Stress test: many parallel read calls; all must succeed. Python-side outage: every call fails for 30 s; the red banner should appear and clear afterwards.
3. pH
--Current pH
--
Temp (compensation)
--°C
Probe voltage
--V
Temperature (°C)
Current temp -- °C
--
DS18B20 status --
pH readings are Nernst-slope compensated with this temperature. Enter the current culture temperature; it is stored on the board and restored after an MCU reboot.
DS18B20 on D4 (DQ pulled up to 3.3 V with 4.7 kΩ). If the sensor cannot be read, the manual temperature above is used and plotted instead.
pH meter calibration & adjustment
--
Probe calibration
--Buffer temperature from the thermometer: put the thermometer and the pH probe in the buffer together and wait until both readings settle.
Steps: rinse the probe, put it in pH 7.00 buffer, wait until stable, press "Set as pH 7.00" → rinse, pH 4.01 buffer, "Set as pH 4.01" → put the probe back. Calibration is stored on the board and restored automatically after an MCU reboot.
pH is aggregated per sampling window into the CSV; readings outside 2–12 (probe error) are excluded and automatic dosing pauses.
Automatic pH control (base)
----
Advanced: steady-state & safety limits
When pH drops below target − deadband a cycle starts: feed valve to Base → the feed pump doses once at the dosing PWM → wait for mixing to settle (slope below the set value) → dose again while still below target; at target the feed valve returns to where it was. High pH only raises an alarm (no acid). Auto pH pauses while the feed pump runs manually. Several doses in a row with no pH rise (base empty, line blocked) latch a FAULT.
Manual dosing & base dosing settings
--
--
Manual dosing only works while the feed valve is set to Base (switch it under Pump › Feed valve & feed pump), and not while the feed pump runs.
Manual dosing no longer turns the feed valve: set the feed valve to Base first, then press Dose once. The dosing PWM and hourly limit apply to both auto pH and manual dosing; the MCU also refuses to dose unless the feed valve is at Base, the pressure trip is clear and the hourly limit is not exceeded.
2. Pressure & derived analysis
--
Feed
Retentate
Permeate
TMP
Valve pinched
Feed
--
bar
Retentate
--
bar
Permeate
--
bar
TMP
--
bar
--
Membrane filtration monitoring (derived)
● Not enough data yetDerived parameters
| Parameter | Value | Unit | Note / status |
|---|---|---|---|
| Key indicators | |||
| Permeability L_p (primary) | -- | LMH/bar | -- |
| TMP_in (max TMP) | -- | kPa | -- |
| TMP_out forward filtration | -- | kPa | -- |
| γ_ratio clogging warning | -- | × | -- |
| ΔP ratio (measured / baseline) | -- | × | -- |
| Shear rate γ (pressure) | -- | s⁻¹ | -- |
| Flux J | -- | LMH | -- |
| Level / vessel weight | -- | Needs level or load-cell sensor | |
| Secondary / diagnostic parameters | |||
| TMP_mean | -- | kPa | |
| TMP_in | -- | kPa | |
| TMP non-uniformity | -- | % | |
| R_t | -- | m⁻¹ | |
| P_s absolute | -- | kPa | |
| τ_w | -- | Pa | working range ≈ 1.4–4.2 Pa |
| τ_shell | -- | min | |
| Re | -- | laminar < 2300 | |
| ΔP_friction | -- | kPa | |
| ΔP reading (incl. gravity) | -- | kPa | |
| dTMP/dt | -- | kPa/min | |
| γ_flow | -- | s⁻¹ | |
| Actual dilution D | -- | h⁻¹ | |
τ_w is about 1.4–4.2 Pa in operation (γ 2,000–6,000 s⁻¹). Measured on this rig: B. subtilis still grew to OD600 3.5 at 6,000 s⁻¹ and kept secreting protein for 60+ hours. The γ upper limit of 11,000 s⁻¹ is the laminar-model limit (Re < 2000), not a cell-tolerance limit — above it, γ_flow = 8v/d and τ_w themselves stop being valid.
Operating inputs (Q_L, Q_perm, culture volume)
Q_perm from collected amount ÷ time
Q_L comes from the flow meter by default; switch to "Manual" if the meter is inaccurate or absent, and all derived values (γ, Re, ΔP ratio) use the manual value. Q_perm feeds J, L_p and D; culture volume feeds D (also editable under Specs). The ΔP–Q sweep always uses the flow meter.
Clogging indicators (γ_ratio, ΔP ratio; dashed 1.0 / 1.3)
γ_ratio
ΔP ratio
L_p trend (primary membrane indicator)
L_p needs Q_perm (collection-bottle scale); until then enter or compute it under "Operating inputs" above.
P_out instantaneous waveform (last 60 s)
P_out
P_out trough
P_s
If the red line (trough) touches the green line (P_s), pump pulsation is reaching backflow.
Gravity-offset self-test & settings
Start-up self-test: measure ρgh (also verifies the impulse lines)
Stop the pump first (PWM = 0). The system waits 10 s for flow to decay, then records 30 s; the reading must be a stable plateau, otherwise it keeps waiting (up to 3 min). Redo after every re-assembly of the tubing.
ΔP baseline = a·Q + b·Q² (quadratic ΔP–Q calibration through the origin). Before the scale is installed, Q_perm can be computed by weighing the collection bottle (g/min ≈ mL/min). The L_p initial value is captured automatically the first time L_p can be computed.
ΔP–Q sweep (multi-point calibration)
Zero the pressures and run the ρgh self-test first; use a clean membrane with the valve open. The pump steps through the PWM values below (high → low by default, so low PWMs are reached while already running instead of starting from rest); at each point the average ΔP_friction and flow are recorded after settling, then ΔP = a·Q + b·Q² is fitted. The original PWM is restored afterwards. Changing the PWM manually or emergency stop aborts the sweep.
| PWM | Q (mL/min) | ΔP_total (kPa) | ΔP_friction (kPa) | SD | Notes |
|---|
Pressure pulsation diagnostics
cycle_freq_hz is a rough zero-crossing estimate for comparison against an oscilloscope only, not a precise value.
Main pump (L298N)
● StoppedFlow (this window)
0.0mL/min
Pulse frequency
0.0Hz
📈 Click the flow values to open the live chart
Direction
Forward
The slider and the input box only preview a value; click "Apply" (or press Enter in the box) to send it. Reversing or emergency stop zeroes the PWM automatically.
Kick-start (low-PWM start)
A stopped pump has static friction, so a low PWM may not start it, yet it keeps running once moving. When enabled, starting from stop first runs at the kick PWM for a short time, then drops to your PWM.
Feed valve & feed pump
Feed valve--
--
Feed pump (L298N channel B)--
🔧 Wiring check
--
Measure the UNO Q header against GND with a meter: "IN3 (D12) high" for D12, "IN4 (D13) high" for D13, about 3.3 V each; then the IN3 / IN4 terminals on the L298N. The test switches off by itself when the time is up, and the main pump emergency stop also ends it.
What is pumped is chosen by the feed valve (Base / External feed). One direction only: driven by IN4 (D13) with IN3 (D12) held LOW (D12 cannot drive on the board); if the liquid flows the wrong way, swap the two motor wires on OUT3 / OUT4. Wiring: ENB = D11, IN3 = D12, IN4 = D13 (remove the ENB jumper on the L298N). The pump will not run while the feed valve is fully closed, the pressure trip is latched or after an emergency stop; auto pH pauses while it runs.
Pinch valve & shell sampling valve (STS3215)
--
Pinched for --
Pinch position not set: open "Valve setup" below, move the servo to where it just pinches the tube, and press "Save as pinched".
Shell sampling valve--
--
Valve setup (positions / safety limits)
Servo not found? Auto-scan
Unplug the driver board and connect UNO Q D0 directly to D1 with one jumper wire, then press. This tests only the UNO Q D0/D1 transmit/receive, independent of the driver board and servo.
No reply needed: sends a move command to the broadcast ID at all 8 baud rates. Servo moves → the transmit path (D1/TX) and power are fine; the problem is the reply path (D0/RX) or swapped TX/RX. Servo does not move → check the D1/TX wire, jumper, driver-board power and servo cable. Remove the tube from the clamp first.
Tries 8 baud rates (1M, 500k, 250k, 128k, 115200, 76800, 57600, 38400) with a broadcast ping each; the full scan also tries IDs 0–253. Press "Use" on a result to switch to that ID and baud (saved). The valve must be open while scanning.
Finding positions: turn torque off and rotate the clamp by hand until the tube is just flattened → "Save as pinched"; rotate back clear of the tube → "Save as open". Or approach with the number / ±20 buttons. The torque limit reduces clamp force and servo heating. TMP / Feed limits are checked by the MCU every 200 ms on instantaneous peaks; exceeding them releases and locks the valve even if Linux is down.
Recent valve events
| Pinched at | Duration | TMP mean/peak | Released by |
|---|
Sampling & feed valve setup (positions / servo ID)
Change servo ID (new servos ship as ID 1)
Only one "ID 1" may be on the bus at a time. Connect new servos one by one: with only the new servo connected (pinch valve unplugged), change ID 1 to 2 (shell valve) or 3 (feed valve), then connect the next one. The ID is stored in the servo EEPROM.
Default positions are from angles (0–360° → 0–4095): shell closed 315° = 3584, sensor 270° = 3072, open 0° = 0; feed closed 315° = 3584, base 270° = 3072, external feed 180° = 2048. If the mounting is off, turn by hand (torque off) or jog, then press "Save position".
Data Recording
Not recording
00:00
Recording runs entirely on the board: every sampling window is written straight to a CSV in the board's recordings/ folder as soon as it closes. Sleeping the computer, closing the browser, even restarting the App will not interrupt it — the browser is only the control surface. Each row holds OD600 (AU), flow (mL/min), pressure (bar), pump PWM and all derived parameters.
Sampling Settings
Pressure and flow are sampled continuously over this window; at the end of each window a single median/mean is taken and becomes the on-screen value, one chart point and one CSV row. The same duration is also the OD600 measurement interval, so all three signals stay aligned. Safety alerts on the instantaneous TMP peak/trough are unaffected and still update every 200 ms.
Algorithm selection
Since v5.0 every algorithm runs in Python: a change takes effect immediately and is saved; OD600 is recomputed at once from the last raw readings. All 8 OD600 algorithms are computed every time and written to the CSV (od_mad … od_p90); raw readings are kept in the recording's _raw folder and can be replayed with tools/replay_od.py. Each CSV row records the active combination in alg_profile. Changing steady-state or analysis source restarts the steady/trend accumulation.
Calibration values & specs
Calibration Values
Export saves the OD600 blank, pressure zero offsets, path-length factor, pH calibration, ρgh / ΔP–Q baseline, Q_perm, valve settings and specs currently in effect to one .json file. Import reads a previously exported file and writes the selected items back to the board.
Since v5.0 the OD600 blank, pressure zero offsets, path length factor and pH calibration live on the board's Linux side (calibration_state.json, ph_valve_state.json) and all conversions happen there, so an MCU reboot loses nothing; only the pressure zeros used by the valve safety interlock are pushed to the MCU automatically. You can also enter your own recorded values below; whenever the zeros in effect were not measured on the spot, a warning stays visible at the top of the page.
| Item | Saved value | Source | Time |
|---|
OD600 blank (manual entry)
The blank ratio alone is enough — it is the only value used in the calculation. You can also enter just the sample and reference lux and let the system compute the ratio. The two lux values only affect the display.
Pressure zero offsets (manual entry, bar)
Same values that "Zero calibrate" produces. Use "Read current values" above to fill these fields with what is in effect now, so you can note them down.
pH two-point calibration (manual entry)
Raw probe voltages (after the on-board amplifier) in the pH 7.00 and pH 4.01 buffers, and the buffer temperature at calibration. "Read current values" above fills these fields with the values in effect now; manually applied values are saved and pushed back after an MCU reboot.
Specifications
Module specs and thresholds used to compute the derived parameters. Changes take effect immediately and are saved (kept across App restarts); "Reset to defaults" returns to constants.json. Fields marked ● differ from the default.