Automate Biological Laboratory Workflows Using a Liquid Handling Robot

Eddymsantos
3 min readMar 24, 2023

Humans learn from mistakes, but it can be taxing on time and resources. Automation is the way of the future, but its origin lies in the past by centuries.

The first documented instance of a liquid handling system was developed in 1875 by Thaddeus M. Stevens. There are other systems documented through the 18' and 1900s, but the technology wasn’t developing and most system were local and specific; not allowing for widespread breakthroughs.

Biomek NXp Automted Liquid Handler — Beckman Coulter

Modern day automation greatly increases efficiency in laboratories by ensuring speed and accuracy. Accuracy is ensured by many mediums such as weight differences and wavelength measurements.

Efficiency is ensured simply by the automation of liquid volumes and mixtures. We can use codes for specific movements, but the highest level of efficiency comes from algorithms which, in short, can automate the automation.

While effiency is amazing it doesn’t mean much without accuracy. Accuracy, especially with potentially hundreds of mixtures that may only have a 1 mL, is extremely important. Weight difference is a posibility, but it’s not the most reliable method. Some liquids have quick evaporative properties, so the weight could change by the time the tube is in position. That’s why most, if not all, automation systems have an option of enclosing the system to solve this issue. Though this isn’t full proof either, as temperature and humidity are factors. Wavelength measurements are considered one of the most accurate measurements for accuracy.

Accuracy is also dependent on the labware used. With larger instruments, it’s important to know the minimum liquid requirements. If the minimum liquid requirement is not met the labware cannot ensure the best accuracy possible.

SETUP

Opentrons Designer Example

There are programs that simplify the program of automation systems, such as the Opentrons protocol designer pictured above. Some automation systems may still have protocol designers in development and not ready to use, so scientist must be able to know how to code the experiments by hand. This includes simple coding and algorithms depending on the experiments requires and scientist’s preference.

Below is part of the code I used to develop the experiment in the photo above.

from opentrons import protocol_api import sys sys.tracebacklimit = 0
#metadata
metadata = {
‘protocolName’:’Final_Assignment’,
‘author’:’Eddy Santos’,
‘description’:’Final_Assignment’,
‘apiLevel’:’2.13'
}

#protocol run function
def run (protcol): protocol_api.ProtocolContext):
#load labware

#load 15 mL tubes in location 1
fithteen_mL = protocol.load_labware (‘nest_12_reservoir_15ml’, location = ‘1’)
#load 1.5 mL tubes in location 2
one_and_a_half_tubes =
protocol.
load_labware (‘opentrons_24_tuberack_eppendorf_1.5ml_safelock_snapcap’,
location = ‘2’)
#load opentrons 96 filter tip rack 20 uL in loation 3
twenty_mL_filter_tips =
protocol.load_labware (‘opentrons_96_filtertiprack_20_ul’, location = ‘3’)
#load opentrons 24 tube rack 2mL safe-lock in location “4”
eppendorf_24 =
protocol.
load_labware (‘opentrons_24_tuberack_eppendorf_1.5ml_safelock_snapcap’,
location = ‘4’)
#load opentrons 6 tube rack with falcon 50mL conical in location 5
tuberack_50_mL =
protocol.load_labware (‘opentrons_10_tuberack_falcon_4x50ml_6x15ml_conical’,
location = ‘5’)
#load opentrons 96 filter tip rack 1000uL in location 6
tiprack_1000 =
protocol.load_labware (‘opentrons_96_filtertiprack_1000ul’, location = ‘6’)
#tip racks
right_pipette = protocol.load_instrument (‘p20_single_gen2’, mount =
‘right’, tip_racks =
[filter_tips]) left_pipette =
protocol.load_instrument (‘p1000_single_gen2’, mount = ‘left’, tip_racks =
[filter_tips]) twenty_mL_filter_tips.
pick_up_tip ()twenty_mL_filter_tips.aspirate (1.5,
tuberack_50_mL[‘A1’])
twenty_mL_filter_tips.dispense (1.5,
eppendorf_24[‘A1’]) twenty_mL_filter_tips.
drop_tip ()twenty_mL_filter_tips.pick_up_tip ()twenty_mL_filter_tips.
aspirate (1.5, tuberack_50_mL[‘A2’]) twenty_mL_filter_tips.dispense (1.5,
eppendorf_24
[‘A2’])
twenty_mL_filter_tips.drop_tip ()twenty_mL_filter_tips.
pick_up_tip ()twenty_mL_filter_tips.aspirate (1.5,
tuberack_50_mL[‘B1’])
twenty_mL_filter_tips.dispense (1.5,
eppendorf_24[‘B1’]) twenty_mL_filter_tips.
drop_tip ()twenty_mL_filter_tips.pick_up_tip ()twenty_mL_filter_tips.
aspirate (1.5, tuberack_50_mL[‘B2’]) twenty_mL_filter_tips.dispense (1.5,
eppendorf_24
[‘B2’])
twenty_mL_filter_tips.drop_tip ()twenty_mL_filter_tips.
pick_up_tip ()twenty_mL_filter_tips.aspirate (1.5,
tuberack_50_mL[‘C1’])
twenty_mL_filter_tips.dispense (1.5,
eppendorf_24[‘C1’]) twenty_mL_filter_tips.
drop_tip ()twenty_mL_filter_tips.pick_up_tip ()twenty_mL_filter_tips.
aspirate (1.5, tuberack_50_mL[‘C2’]) twenty_mL_filter_tips.dispense (1.5,
eppendorf_24
[‘C2’])
twenty_mL_filter_tips.drop_tip ()twenty_mL_filter_tips.
pick_up_tip ()twenty_mL_filter_tips.aspirate (1.5,
tuberack_50_mL[‘D1’])
twenty_mL_filter_tips.dispense (1.5,
eppendorf_24[‘D1’]) twenty_mL_filter_tips.
drop_tip ()twenty_mL_filter_tips.pick_up_tip ()twenty_mL_filter_tips.
aspirate (1.5, tuberack_50_mL[‘D2’]) twenty_mL_filter_tips.dispense (1.5,
eppendorf_24
[‘D2’])
twenty_mL_filter_tips.drop_tip ()

--

--