Do people use multichannel pippette as a single channel by using only the outer channel?

I was listening to this opentrons webinar:
and the author claimed that he uses the outer channel of an 8-channel pipette for concentration normalisation (while 7 other channels simply dont pick up a tip). I wanted to ask if this a well-known trick in the community. If so is there even a point in buying an 8 channel. And finally has this been formalised in the opentrons API somehow?

Yes this is definitely a well known trick, I even have used an 8 channel to just pick up 2, 3, or 4 tips as well. It all depends on your requirements. The trick isn’t formalized in the API though. Opentrons does have a help article on it here however

As for your question, I assume you meant

“is there even a point in buying a single channel p300”.

Well, yes there is. For one if you try this trick and try to pipette a 24 wellplate in slot 1, you’ll have a bad time because the multichannel will be out of bounds, and that error doesn’t always show up in simulation, but when you run it (as you’re likely picking up tips with channel A). Granted I find a lot less usage out of p300 singles rather than p1000s or p20s, so I’d say the p300 single is the least useful of the bunch (in my experience).


Im following the help article you attached and getting this error:

AttributeError [line 33]: ‘NoneType’ object has no attribute ‘update_config_item’

I’m confused – here’s the line that’s causing the error, which I’m lifting pretty much straight from the example:

protocol._hw_manager.hardware._attached_instruments[types.Mount.RIGHT].update_config_item('pick_up_current', pick_up_current)

Any idea what could be the issue here?

1 Like

This part of our API is being updated, and the hardware manager used in this code has changed. I can make it a point to try to update this article, but if this method is mission-critical for you, you might want to consider downgrading.

OK, understood. Any advice on which version to downgrade to?

6.3.1 should be the software version that works with that sample protocol. Instructions for downgrade.

You may find this function works, which is one we use

def pick_up_1_tip(self, pip, tiprack):
# using multi-pipette as single:
# initialize starting tiprack setup, for reference later when you try returning tips
starting_setup = self.update_tip_tracker(tiprack)

    pip_channel = "A"

    if tiprack.load_name != "opentrons_96_tiprack_300ul":
            "othelp.pick_up_1_tip() ERROR >> This only work with opentrons_96_tiprack_300ul. Your tiprack is {}".format(

    next_tip = tiprack.next_tip()
    next_tip_name = next_tip.well_name
    next_tip_letter = next_tip_name[0]
    # print(next_tip_name)
    skipped = []
    tip_selected = False

    # confirm dictionary per row letter
    confirm_dict = {
        "A": {
            "B": False,
            "C": False,
            "D": False,
            "E": False,
            "F": False,
            "G": False,
            "H": False,
        "B": {
            "C": False,
            "D": False,
            "E": False,
            "F": False,
            "G": False,
            "H": False,
        "C": {"D": False, "E": False, "F": False, "G": False, "H": False},
        "D": {"E": False, "F": False, "G": False, "H": False},
        "E": {"F": False, "G": False, "H": False},
        "F": {"G": False, "H": False},
        "G": {"H": False},
        "H": {},

    while tip_selected is False:  # skips anything not in accepted tip list
        # print("checking tip {}".format(next_tip_name))
        column_number = next_tip_name[1:]
        tips_to_confirm = confirm_dict[next_tip_letter]  # check against confirmation list (from above)

        checklist = {}
        for c_tip in tips_to_confirm.keys():
            checklist[c_tip] = tiprack.well(c_tip + column_number).has_tip
        # print(checklist)

        # if tip setup matches tips to confirm, take next_tip
        if checklist == tips_to_confirm:
            tip_selected = True
            next_tip = tiprack.next_tip()
            # print(next_tip)

            next_tip_name = next_tip.well_name
            next_tip_letter = next_tip_name[0]



    # return tips that were not actually picked up
    column_number = next_tip_name[1:]

    for name in skipped:
        if starting_setup[name] is True:  # only return if it wasnt there at the start of this function

It’s a bit different from the help article so you may get around the version error you’re encountering

As far as I can tell this doesn’t adjust the pick up current? Which I think works OK for the p300 but not for the p20. That’s the bit that isn’t working in the example code.

Thank you!

Oh sorry, I haven’t used it for a p20, my bad. I must’ve missed that in your post.

Have you considered just hardcoding the movements? Telling the pipette to move to a specific spot with specific force? Bit of a pain but sometimes you gotta do what you gotta do. You can change the pipette’s movement speed by:

pip.default_speed = 50

and change it back to default by calling

pip.default_speed = None