Excess air bubbles when pipetting multiple times

I’m doing cell seeding into 384 wellplates with my FLEX and I have a persistent issue with air bubbles when mixing my cell solution, especially after several plates.

video here

Does anyone have any solutions that they like to use for this? I’ve tried blowing out in several places within the protocol and it doesn’t seem to help. It’s a rather bubbly solution of cell media. It’s annoying because sometimes the filter tips clog from too many bubbles

2 Likes

Hey- can you send me your protocol so we can look at what you’re currently doing to troubleshoot this?

1 Like

Hey there Meghan!

Summary
    def remove_liquid_loc_list(waste_name,plate_name, volume, pip = channel_96, aspirate_rate = 0.2):
        # Get pipetting well destinations
        list_pipetting_wells_actual = get_pipetting_wells_A1B1A2B2(plate_name)
        
        protocol.comment(f"Consolidating from plate {plate_name}")
        # Remove from each plate (+10 volume to get everything)
        for well_name in list_pipetting_wells_actual:
            pip.aspirate(volume+10, well_name.bottom(1.2), rate = aspirate_rate)
        # Dispense into waste reservoir
        waste_loc = waste_name.wells_by_name()["A1"]
        pip.dispense(volume*len(list_pipetting_wells_actual),waste_loc.bottom(4),rate=1)
        # dip to remove bubbles
        pip.blow_out(waste_loc.bottom(10))
        pip.move_to(waste_loc.bottom(3))
        # blow out to remove liquid gathered from dip 
        pip.blow_out(waste_loc.bottom(10))
        # retract slowly
        pip.move_to(waste_loc.top(3),speed=50)
    def distribute_cell_volume(source_name,plate_name, volume,mix_rounds=5, mix_volume = 140 , pip = channel_96,dispense_rate = 0.25, aspirate_rate = 0.25):
        list_pipetting_wells_actual = get_pipetting_wells_A1B1A2B2(plate_name)

        source_loc = source_name.wells_by_name()["A1"]
        
        # if single distribute then mix every time and distirubte one at time, better for more accurate volumes
        for well_name in list_pipetting_wells_actual:
            if well_name == list_pipetting_wells_actual[0]:
                # Mix more for first transfer
                mix_intensity = 2
                current_mix_rounds = mix_rounds * mix_intensity

            else:
                # Mix less for second transfer
                current_mix_rounds = mix_rounds

            # Complex mix, aspirate at bottom, move up, dispense, repeat
            #TODO try force-direct later, pipette seems to not move smoothly but move back to the top after each action 
            for iteration in range(current_mix_rounds):
                pip.aspirate(mix_volume, source_loc.bottom(2),rate=1)

                pip.dispense(mix_volume,source_loc.bottom(10),rate=1)
                pip.blow_out(source_loc.top())
                if iteration == current_mix_rounds:
                    pip.blow_out(source_loc.top())
            pip.mix(3,100,source_loc.bottom(2))
            pip.blow_out(source_loc.top(-8))
            # Aspirate cell volume
            channel_96.aspirate(volume, source_loc.bottom(2),rate=aspirate_rate)
            # Move slowly to reduce drippage
            channel_96.move_to(source_loc.top(1),speed=50)
            # Dispense into wellplate 
            channel_96.dispense(volume,well_name,rate=dispense_rate)
if remove_liquid:
           remove_liquid_loc_list(waste_name=waste_trough,plate_name=current_plate, volume=removal_volume)
if cell_addition:
          distribute_cell_volume(source_name=liquid_source,plate_name=current_plate, volume=addition_volume)

I can definitely share the above code snippets. I use remove_liquid_loc_list before using the function distribute_cell_volume.

Any suggestions are appreciated, cheers!

Thanks- I should have some recommendations for you soon!

There is some commentary in the protocol of what we would recommend trying (a couple options to test out)!

def distribute_cell_volume(source_name,plate_name, volume,mix_rounds=5, mix_volume = 140 , pip = channel_96,dispense_rate = 0.25, aspirate_rate = 0.25):
list_pipetting_wells_actual = get_pipetting_wells_A1B1A2B2(plate_name)
source_loc = source_name.wells_by_name()[“A1”]
# if single distribute then mix every time and distirubte one at time, better for more accurate volumes
for well_name in list_pipetting_wells_actual:
if well_name == list_pipetting_wells_actual[0]:
# Mix more for first transfer
mix_intensity = 2
current_mix_rounds = mix_rounds * mix_intensity
else:
# Mix less for second transfer
current_mix_rounds = mix_rounds
# Complex mix, aspirate at bottom, move up, dispense, repeat
#TODO try force-direct later, pipette seems to not move smoothly but move back to the top after each action
for iteration in range(current_mix_rounds):
pip.aspirate(mix_volume, source_loc.bottom(2),rate=1)
pip.dispense(mix_volume,source_loc.bottom(10),rate=1)
pip.blow_out(source_loc.top())
if iteration == current_mix_rounds:
pip.blow_out(source_loc.top())
####I usually stray away from the mix commmand, As I can see it introduce air bubbles due to the way it moves####
######Could TRY THIS OR THE BELOW#######
for x in range(3):
pip.aspirate(100,source_loc.bottom(2),rate=1)
pip.dispense(100,source_loc.bottom(2),rate=1)
####If you want to continue using the mix command, I would suggest using the following####
pip.aspirate(100,source_loc.bottom(2),rate=1)
pip.dispense(90,source_loc.bottom(2),rate=1)
pip.mix(3,95,source_loc.bottom(2))
pip.dispense(10,source_loc.bottom(2),rate=1)
#pip.blow_out(source_loc.top(-8))
# Aspirate cell volume
channel_96.aspirate(volume, source_loc.bottom(2),rate=aspirate_rate)
# Move slowly to reduce drippage
channel_96.move_to(source_loc.top(1),speed=50)
# Dispense into wellplate
channel_96.dispense(volume,well_name,rate=dispense_rate)
if remove_liquid:
remove_liquid_loc_list(waste_name=waste_trough,plate_name=current_plate, volume=removal_volume)
if cell_addition:
distribute_cell_volume(source_name=liquid_source,plate_name=current_plate, volume=addition_volume)

Thank you very much for the prompt response Meghan! I’ll do some testing and let you know how it goes

1 Like

We had similar problems on our OT-2 with air bubbles and dripping.

Here’s some pseudo code from a custom transfer function with manual blow outs and air gaps (after both aspirating and dispensing). It provides more options than the built in transfer function. You might have luck doing a similar manual aspiration on your system.

# Reset the pipette including any previous air gaps
pipette.move_to(source_top)
pipette.dispense()

# Get air for manual blowout
if dispense_blow_out_volume is not None:
    pipette.aspirate(dispense_blow_out_volume)

# Aspirate
pipette.move_to(source)
pipette.aspirate(volume)
protocol.delay(aspirate_delay)

# Air gap after aspiration
pipette.move_to(source_top, speed=aspirate_exit_speed)
if aspirate_air_gap_volume is not None:
    pipette.air_gap(aspirate_air_gap_volume, height=0)

# Dispense, including blow out
pipette.move_to(destination)
pipette.dispense()
protocol.delay(dispense_delay)

# Air gap after dispensing
pipette.move_to(destination_top, speed=dispense_exit_speed)
if dispense_air_gap_volume is not None:
    pipette.air_gap(dispense_air_gap_volume, height=0)
1 Like

Thanks for your reply!

I’ve tried these suggestions and honestly it seems like just using a mix() command without any of the individual aspirate/ dispense commands works the best, because the flex seems incapable of performing multiple aspirate / dispenses without an automatic airgap / blowout between them

Currently just using the standard mix command, retracting the pipette head slowly out of the reservoir, and then dispensing the media directly into the .top(), rate = 1.5 of a 384 wellplate seems to work the best