Issue with Dispense Command on OT-2

Hi,

I am a relatively new user of PLR and I am not sure if I ran into an issue regarding my own knowledge of PLR or if this is a genuine bug in PLRs dispense routine w.r.t. OT-2.

The gist of what is going on is support for the dispense command appears to be driving the plunger on the OT-2 in the wrong direction, essentially aspirating a bunch of air on the dispense call. I replicated the same script using Opentrons native API and the behavior was fine i.e., calling dispense seems to drive the plunger in the correct direction triggering a dispense action. This may be setup specific as we are currently using a P300 Gen 1 single pipette on a left mount or like I mentioned incorrect use of PLR on my part. I will note, the discard tips command does dispense liquid into trash correctly before discarding the tips. I’ll include snippets of both the functioning Opentrons script as well as the PLR variant.

PLR Routine Snippet

...
async def main():
    set_tip_tracking(True)
    set_volume_tracking(True)
    backend = OpentronsOT2Backend(host=OT2_IP)
    deck = OTDeck()
    lh = LiquidHandler(backend=backend, deck=deck)
    await lh.setup()

    source_plate = BioRad_96_wellplate_500uL_Vb(name="Source_Aspirate_Plate")
    deck.assign_child_at_slot(source_plate, slot=4)

    dispense_plate = BioRad_96_underside_flat(name="Target_Dispense_Plate")
    deck.assign_child_at_slot(dispense_plate, slot=1)

    tip_rack_300 = opentrons_96_tiprack_300ul(name="TipRack_300")
    deck.assign_child_at_slot(tip_rack_300, slot=7)

    rows = ["A", "B", "C", "D", "E", "F", "G", "H"]
    for row in rows:
        source_plate.get_well(f"{row}1").tracker.set_volume(500)
        source_plate.get_well(f"{row}12").tracker.set_volume(500)

    volumes = [30, 40, 50, 60, 80, 100, 120, 150]
    for i, vol in enumerate(volumes):
        row = rows[i]
        source_well = f"{row}12"
        target_well = f"{row}12"
        tip_well = f"{row}1"
        await lh.pick_up_tips(tip_rack_300[tip_well])
        await lh.aspirate(
            source_plate[source_well],
            vols=[vol],
        )
        await lh.dispense(
            dispense_plate[target_well],
            vols=[vol],
        )
        await lh.discard_tips()
    await lh.stop()

Opentrons Routine Snippet

...
def run(protocol: protocol_api.ProtocolContext):
    source_plate = protocol.load_labware("biorad_96_wellplate_200ul_pcr", "4")

    dispense_plate = protocol.load_labware("biorad_96_wellplate_200ul_pcr", "1")

    tip_rack_300 = protocol.load_labware("opentrons_96_tiprack_300ul", "7")

    left_pipette = protocol.load_instrument("p300_single", "left")

    rows = ["A", "B", "C", "D", "E", "F", "G", "H"]
    volumes = [30, 40, 50, 60, 80, 100, 120, 150]

    for i, vol in enumerate(volumes):
        row = rows[i]
        source_well = source_plate[f"{row}12"]
        target_well = dispense_plate[f"{row}12"]
        tip_well = tip_rack_300[f"{row}1"]
        left_pipette.pick_up_tip(tip_well)
        left_pipette.aspirate(vol, source_well)
        left_pipette.dispense(vol, target_well)
        left_pipette.drop_tip()

These are just one instance of a test I was running testing various drop sizes with the pipette included with this OT-2.

2 Likes

this was fixed with opentrons-http-api-client==0.2.1

but PLR currently still used version 0.2.0. fixed in opentrons: bump opentrons-http-api-client pin to 0.2.1 · PyLabRobot/pylabrobot@fb0f701 · GitHub and it will be part of the next PLR release

1 Like

Gotcha, thanks for the clarification!

to make the above more explicit, you can update this right now using pip install opentrons-http-api-client==0.2.1 in the next version of PLR that will be installed by default, but you can already install the upgraded dependency right now.

let me know if it works!

1 Like