Open-source Python driver for DLAB dPette and dPette+ electronic pipettes. Full serial volume control, speed control, and three operating modes (pipetting, splitting, dilution) — no hardware modifications needed.
Uses the Silicon Labs CP2102 USB-UART bridge (VID 0x10C4, PID 0xEA60)
at 9600 baud 8N1.
dPette 8-channel with USB-UART bridge attached
Verified on the 8-channel dPette — same CP2102 bridge, same 6-byte protocol.
There is no open-source, disposable-tip, API-controlled pipette at this price point.
| System | Price tier | Tips | Control |
|---|---|---|---|
| dPette + this driver | ~$80–130 (Aliexpress / DLAB direct) | Disposable | Full serial |
| ac-rad Digital Pipette | DIY (BOM not published) | Syringe (no tips) | Arduino + Python host |
| Science Jubilee + OT-2 pipette | DIY (system cost not published) | Disposable | Python (science_jubilee) |
| Opentrons OT-2 | From $15,950 | Disposable | Python (Protocol API) |
| Tecan Fluent | Quote only | Disposable | FluentControl (proprietary); PyLabRobot wraps |
| Hamilton Microlab STAR | Quote only | Disposable (CO-RE II) | VENUS / PyHamilton |
| Heidolph Hei-FLOW | Quote only | Continuous flow (tubing, not pipette-class) | Proprietary (analog/RS-232 depending on model) |
Prices verified 2026-05-26 against vendor/project pages linked above. Hei-FLOW is listed for reference — peristaltic pumps move continuous flow, not discrete pipette volumes, so they solve a different problem.
- Volume-controlled aspirate/dispense — set any volume via serial (B2), confirmed in EXP-050
- Three operating modes — PI (pipetting), ST (splitting), DI (dilution)
- Speed control — 3 speed levels for aspirate and dispense
- Mixing — aspirate/dispense cycling with caller-controlled tip position
- EEPROM read/write — firmware version, calibration coefficients
- Single- and multichannel — verified on the 8-channel dPette
- 121 tests passing, 55 experiments documented
git clone https://github.com/Lambda-Biolab/dpette-usb-driver.git
cd dpette-usb-driver
uv pip install -e .from dpette import DPetteDriver, SerialConfig
drv = DPetteDriver(SerialConfig(port="/dev/cu.usbserial-0001"))
drv.connect() # A0 handshake + enter PI mode
drv.aspirate(200.0) # sets volume to 200 µL, aspirates
drv.dispense() # dispenses
drv.aspirate(50.0) # change volume on the fly
drv.dispense()
drv.disconnect()# Tip must be raised above liquid before dispense
# (blow includes piston return that creates suction)
for _ in range(5):
# lower tip into liquid
drv.mix_aspirate(100.0, speed=3)
# raise tip above liquid
drv.mix_dispense()from dpette.protocol import WorkingMode
drv.split_setup(100.0, count=3) # enters ST mode, sets 100 µL × 3
# tip in liquid
drv.split_aspirate() # aspirates total (300 µL)
# raise tip, move to destination wells
drv.split_dispense() # aliquot 1
drv.split_dispense() # aliquot 2
drv.split_dispense() # aliquot 3drv.dilute_setup(200.0, 100.0) # enters DI mode
# tip in diluent
drv.dilute_aspirate() # aspirates 200 µL
# tip in sample
drv.dilute_aspirate() # aspirates 100 µL on top
# raise tip — switch to PI mode to dispense (DI blow
# doesn't trigger motor on basic dPette)
drv.enter_mode(WorkingMode.PI) # homes motor, expels liquidfrom dpette.protocol import KeyAction
drv.set_speed(KeyAction.SUCK, 3) # fast aspirate
drv.set_speed(KeyAction.BLOW, 1) # slow dispensepytest # 121 tests
ruff check src/ tests/ # lint
mypy src/ # type checkAll communication uses 6-byte packets:
[0xFE] [CMD] [B2] [B3] [B4] [CHECKSUM] host → device
[0xFD] [CMD] [B2] [B3] [B4] [CHECKSUM] device → host
Checksum = sum(bytes[1:5]) & 0xFF.
Commands cover handshake (A0), EEPROM read/write (A3/A4), mode and
volume control (B0/B2), and aspirate/dispense (B3). See
docs/PROTOCOL_NOTES.md for the full command
reference.
- Err4 on startup: Caused by
A5 b2=1(calibration mode entry via serial). Persists across reboots. Cannot be cleared via serial — the error has never been resolved, including via PetteCali (Windows). Dismiss by holding the button. All serial operations work normally after dismissal. - DI mode dispense: B3 blow doesn't trigger motor on basic dPette.
Workaround:
enter_mode(WorkingMode.PI)homes the motor and expels liquid. - Piston return suction: B3 blow includes a piston return to home. If the tip is submerged, this draws extra liquid. Always dispense with tip above liquid.
WARNING: This software is provided as-is for research and educational purposes. Using it may void your pipette's warranty.
Do NOT send
FE A5 01(enter calibration mode) — causes persistent Err4. The driver never sends this command.
- Protocol Notes — full command reference
- Experiment Log — 55 experiments with results
- Hardware Notes — CP2102, device connection
- Safety Model — risks and software guardrails
- PyLabRobot — hardware-agnostic Python SDK for floor-standing liquid handlers (Hamilton STAR/Vantage, Tecan EVO, Opentrons OT-2). Different tier; same Python-first goal.
- xg590/Learn_dPettePlus —
earlier independent reverse-engineering of the same dPette+ protocol;
source of the official
Communication_Protocol_CN.doc. - qte77/i3mega-pipettebot — downstream: drives a converted consumer 3D printer using this driver as a low-cost dispensing robot.
Xiaokang Guo (NYU) had already reverse-engineered
the dPette+ in xg590/Learn_dPettePlus
and republished the DLAB Communication_Protocol_CN.doc there. We came across
the spec while cross-checking our own findings; it confirms several of our
results — most usefully the A1 INFO response layout (channel count, volume
range) and the B3 KEY completion-code semantics.
The remote-control protocol itself (A0/B0/B2/B3) was discovered earlier in
this project by Ghidra-decompiling PetteCali.exe and confirmed in live
experiments EXP-049 and EXP-050.
MIT — see LICENSE.
