Curiox Laminar Wash HT2000#

The Curiox Laminar Wash HT2000 is a benchtop station that runs Curiox’s Laminar Wash process on DropArray plates. It has a serial interface and runs wash and prime routines under host control. (This is a legacy system, succeeded by the HT2100.)

Property

Value

Communication

Serial, binary-framed ASCII payloads

Serial settings

115200 baud, 8 data bits, no parity, 1 stop bit, no handshake

Frame

FF FF FF FF FF 01 + length + payload + 16-bit checksum + FF

Wash repeats

1–19

Initial volume

0–99 (device units)

Flow rate

2–20 (device units)

Channel

0–5 or 11–15

Warning

This driver has NOT been tested against hardware in PyLabRobot. The protocol, frame format, and reply layouts are reconstructed from the vendor software. If you verify it on an HT2000, please open a PR to remove the not-tested warning.

How it talks#

Each command is a short ASCII payload (for example 210 for a standard wash) wrapped in a fixed binary frame: a six-byte preamble, the payload length, the payload, a 16-bit checksum, and a trailer byte. Replies are fixed length and carry a single status digit – 0 ready, 1 busy, 2 error, 3 stopped. Every action other than the status poll and the report returns an 11-byte acknowledgement.

You do not build frames yourself; the driver methods below do it for you.

Physical setup#

Connect the HT2000’s serial port to your computer, typically through a USB-to-serial adapter. Make sure the port parameters match the driver defaults (115200 baud, 8 data bits, no parity, 1 stop bit, no handshake).

Connect#

setup() opens the serial port and polls the instrument once. If the HT2000 reports an error state it raises a CurioxHT2000Error. It also logs the not-tested warning.

from pylabrobot.curiox import CurioxHT2000

washer = CurioxHT2000(port="/dev/ttyUSB0")  # replace with your port
await washer.setup()

Check status#

ping() returns (status, mode, error) for a quick health check. enquire_report() returns a fuller StatusReport including tray position and whether a plate is loaded.

status, mode, error = await washer.ping()
print(status, mode, error)

report = await washer.enquire_report()
print(report)

Load a plate#

Loading a plate is two steps with a physical action in between: move the tray out, place the plate, then move it back in. Both moves are idempotent, so they are safe to call without tracking the tray’s state.

First, move the tray out:

await washer.move_tray_out()

Place the DropArray plate on the tray, then move it back in:

await washer.move_tray_in()

Prime the fluidics#

Before washing, prime the fluid path. prime() runs a routine and waits for it to settle. Choose the routine by name: "standard", "head", "pump", or "short".

await washer.prime("standard")

Run a wash#

wash() uploads the wash parameters and runs a cycle. It switches the instrument to operation mode if needed, applies the parameters, starts the wash, and then polls until the cycle completes (the instrument finishes washing and returns to ready). It raises if the plate is missing, the instrument stops, or the cycle does not complete within max_operation_duration.

await washer.wash(
    wash_number=3,      # number of wash repeats (1..19)
    initial_volume=50,  # device units (0..99)
    flow_rate=5,        # device units (2..20)
    channel=0,          # 0..5 or 11..15
)

Drain#

Drain the aspirator and the spill tray between runs.

await washer.drain_aspirator()
await washer.drain_spill_tray()

Home#

Recover the home position if the instrument needs re-seating.

await washer.home()

Disconnect#

stop() closes the serial connection.

await washer.stop()