吸光度板阅读器自动化技能Skill opentrons-absorbance-reader

这个技能用于在Opentrons Flex平台上自动化进行微板吸光度测量,支持单波长和多波长读取(450、562、600、650纳米),适用于ELISA、细胞生长监测、比色测定和动力学实验等生物医药应用。关键词:吸光度测量、自动化、ELISA、细胞密度、分光光度计、Opentrons Flex、生物实验、数据导出。

生物制药 1 次安装 2 次浏览 更新于 3/12/2026

name: opentrons-absorbance-reader description: Opentrons吸光度板阅读器模块用于Flex - 甲板上的微板分光光度测量,具有单/多波长读取(450、562、600、650纳米)、自动盖控制,以及用于ELISA、细胞生长和比色测定的CSV数据导出 allowed-tools: [“*”]

Opentrons吸光度板阅读器模块

概述

吸光度板阅读器模块是专为Opentrons Flex设计的甲板上微板分光光度计。它可同时测量96孔板中最多6个波长的光吸收,实现自动化ELISA、细胞密度测量、比色测定和动力学读数,无需手动板转移。

核心价值: 消除手动板读取器转移。在协议中读取吸光度以做出实时决策或通过自动定时和液体处理收集动力学数据。

平台: 仅限Opentrons Flex(与OT-2不兼容)

使用时机

在以下情况下使用吸光度阅读器技能:

  • 运行ELISA或其他需要吸光度读数的比色测定
  • 测量细菌或细胞培养生长(OD600)
  • 执行带定时读数的动力学测定
  • 收集多波长吸光度数据
  • 协议要求基于吸光度值进行实时决策
  • 自动化基于板的生物化学测定

不要在以下情况使用:

  • 使用OT-2机器人(模块仅限Flex)
  • 需要450、562、600、650纳米以外的波长
  • 需要荧光或发光测量
  • 需要更高的光谱分辨率或更宽的波长范围

快速参考

操作 方法 关键参数
加载模块 protocol.load_module() "absorbanceReaderV1", “D3”(或A3-C3)
关闭盖子 close_lid() -
打开盖子 open_lid() -
检查盖子状态 is_lid_on() 返回布尔值
初始化阅读器 initialize() mode、wavelengths、reference_wavelength
读取板 read() export_filename(可选)

可用波长: 450纳米(蓝色)、562纳米(绿色)、600纳米(橙色)、650纳米(红色)

平台要求

仅限Opentrons Flex

  • API版本: 2.21或更高
  • 兼容甲板插槽: A3、B3、C3、D3(仅限第3列)
  • 暂存区域: 第4列(整个列保留用于盖子存储)

重要: 当吸光度阅读器存在时,无法在第4列(A4、B4、C4、D4)加载任何实验器皿。

甲板布局

第3列(阅读器)  第4列(暂存 - 保留)
┌─────────────┐    ┌─────────────┐
│     A3      │───▶│  A4(盖子) │
│   阅读器     │    │   保留      │
│   模块      │    │             │
└─────────────┘    └─────────────┘

阅读器占用第3列 - 检测单元和板架 第4列保留 - 盖子暂存区域(夹持器打开时移动盖子到此)

加载模块

from opentrons import protocol_api

metadata = {'apiLevel': '2.21'}
requirements = {"robotType": "Flex", "apiLevel": "2.21"}

def run(protocol: protocol_api.ProtocolContext):
    # 在第3列加载吸光度阅读器
    reader = protocol.load_module("absorbanceReaderV1", "D3")

    # 注意:第4列现在无法用于实验器皿

兼容插槽: A3、B3、C3、D3 推荐: D3(右下位置便于夹持器访问)

盖子控制

夹持器自动管理盖子位置:

# 关闭盖子(初始化前必需)
reader.close_lid()

# 检查盖子状态
if reader.is_lid_on():
    protocol.comment("盖子在检测单元上")

# 打开盖子(移动到第4列的暂存区域)
reader.open_lid()

盖子位置:

  • 关闭: 盖子覆盖模块上的检测单元
  • 打开: 盖子存储在暂存区域(第4列)

关键: 始终在initialize()前调用close_lid(),即使盖子已经关闭。

初始化

initialize()方法配置阅读器的测量参数。

单波长读取

最简单模式 - 在一个波长读取:

# 初始化单波长
reader.close_lid()
reader.initialize(mode="single", wavelengths=[450])
reader.open_lid()

用例: OD600细菌生长、单色ELISA

带参考的单波长读取

针对参考波长标准化读数:

# 初始化带参考波长
reader.close_lid()
reader.initialize(
    mode="single",
    wavelengths=[450],
    reference_wavelength=562
)
reader.open_lid()

用例: 减少背景噪音、标准化板伪影

多波长读取

同时读取最多6个波长:

# 初始化多波长
reader.close_lid()
reader.initialize(
    mode="multi",
    wavelengths=[450, 562, 600, 650]
)
reader.open_lid()

用例: 多分析物测定、光谱分析、双波长ELISA

可用波长:

  • 450纳米 - 蓝色(常见ELISA底物TMB)
  • 562纳米 - 绿色(BCA蛋白质测定)
  • 600纳米 - 橙色(细菌生长OD600)
  • 650纳米 - 红色(替代参考波长)

最大: 每次读取6个波长

读取板

基本读取

# 使用夹持器将板移动到阅读器
protocol.move_labware(assay_plate, reader, use_gripper=True)

# 关闭盖子
reader.close_lid()

# 读取板
absorbance_data = reader.read()

# 打开盖子
reader.open_lid()

# 将板移离阅读器
protocol.move_labware(assay_plate, "C1", use_gripper=True)

带CSV导出的读取

# 读取并导出数据
absorbance_data = reader.read(export_filename="experiment_001_plate1")

# CSV文件保存到机器人,可通过Opentrons应用程序访问

导出格式: 带板布局、元数据(波长、序列号、时间戳)的CSV文件

访问读取结果

结果作为嵌套字典返回:{wavelength: {well: absorbance}}

# 在450纳米读取板
data = reader.read()

# 访问450纳米的特定孔
absorbance_a1 = data[450]["A1"]

protocol.comment(f"孔A1在450纳米的吸光度:{absorbance_a1}")

# 遍历600纳米的所有孔
for well_name, absorbance in data[600].items():
    protocol.comment(f"{well_name}: {absorbance}")

值范围: 0.0 - 4.0 OD(光密度)

多波长数据访问

# 用多个波长初始化
reader.initialize(mode="multi", wavelengths=[450, 600])

# 读取板
data = reader.read()

# 访问不同波长
od450_a1 = data[450]["A1"]
od600_a1 = data[600]["A1"]

protocol.comment(f"A1: OD450={od450_a1}, OD600={od600_a1}")

# 计算比率
if od600_a1 > 0:
    ratio = od450_a1 / od600_a1
    protocol.comment(f"450/600比率:{ratio}")

数据格式

协议内字典格式

{
    450: {
        "A1": 0.123,
        "A2": 0.145,
        "A3": 0.167,
        # ... 所有96个孔
        "H12": 0.089
    },
    600: {
        "A1": 0.456,
        # ... 所有96个孔
    }
}

结构:

  • 顶层:波长(450、562、600、650)
  • 第二层:孔名(“A1” - “H12”)
  • 值:吸光度(0.0 - 4.0 OD)

CSV导出格式

Opentrons Flex吸光度板阅读器
序列号:ABC123456
波长:450纳米
日期:2024-11-09
时间:14:32:01

    1      2      3      4      5      6  ...  12
A  0.123  0.145  0.167  0.189  0.201  0.223  ...  0.089
B  0.234  0.256  0.278  0.290  0.312  0.334  ...  0.190
C  0.345  0.367  0.389  0.401  0.423  0.445  ...  0.291
...
H  0.456  0.478  0.490  0.512  0.534  0.556  ...  0.392

包含的元数据:

  • 模块序列号
  • 测量的波长
  • 时间戳
  • 带行/列标签的板布局

完整工作流模式

标准读取工作流

# 1. 加载和设置
reader = protocol.load_module("absorbanceReaderV1", "D3")
plate = protocol.load_labware("corning_96_wellplate_360ul_flat", "B1")
pipette = protocol.load_instrument("flex_8channel_1000", "left")

# 2. 初始化阅读器(空)
reader.close_lid()
reader.initialize(mode="single", wavelengths=[450])
reader.open_lid()

# 3. 准备样本
# ... 移液操作 ...

# 4. 将板移动到阅读器
protocol.move_labware(plate, reader, use_gripper=True)

# 5. 读取板
reader.close_lid()
data = reader.read(export_filename="my_assay_data")
reader.open_lid()

# 6. 处理结果或继续协议
for well in plate.wells():
    if data[450][well.well_name] > 1.0:
        protocol.comment(f"{well.well_name}是阳性")

# 7. 将板移离阅读器
protocol.move_labware(plate, "C1", use_gripper=True)

常见模式

ELISA协议

# 设置
reader = protocol.load_module("absorbanceReaderV1", "D3")
elisa_plate = protocol.load_labware("corning_96_wellplate_360ul_flat", "C2")
pipette = protocol.load_instrument("flex_8channel_1000", "left")

# 初始化阅读器
reader.close_lid()
reader.initialize(mode="single", wavelengths=[450], reference_wavelength=562)
reader.open_lid()

# 1. 包被板、孵育、洗涤(未显示)

# 2. 添加样本
pipette.transfer(100, samples, elisa_plate.wells()[:24])

# 3. 孵育
protocol.delay(minutes=60)

# 4. 洗涤步骤
for _ in range(3):
    # 洗涤逻辑(未显示)
    pass

# 5. 添加底物
pipette.transfer(100, substrate, elisa_plate.wells()[:24])

# 6. 孵育
protocol.delay(minutes=15)

# 7. 添加停止溶液
pipette.transfer(50, stop_solution, elisa_plate.wells()[:24])

# 8. 读取板
protocol.move_labware(elisa_plate, reader, use_gripper=True)
reader.close_lid()
elisa_data = reader.read(export_filename="elisa_450nm_results")
reader.open_lid()

# 9. 分析结果
for well in elisa_plate.wells()[:24]:
    od450 = elisa_data[450][well.well_name]
    if od450 > 0.5:
        protocol.comment(f"{well.well_name}: 阳性 (OD450={od450:.3f})")
    else:
        protocol.comment(f"{well.well_name}: 阴性 (OD450={od450:.3f})")

细菌生长动力学

# 设置
reader = protocol.load_module("absorbanceReaderV1", "D3")
culture_plate = protocol.load_labware("corning_96_wellplate_360ul_flat", "C2")
hs_mod = protocol.load_module("heaterShakerModuleV1", "D1")

# 为OD600初始化阅读器
reader.close_lid()
reader.initialize(mode="single", wavelengths=[600])
reader.open_lid()

# 接种培养物(未显示)

# 动力学读取循环
for timepoint in range(8):  # 8个时间点
    # 在加热摇床上孵育
    protocol.move_labware(culture_plate, hs_mod, use_gripper=True)
    hs_mod.set_and_wait_for_temperature(37)
    hs_mod.close_labware_latch()
    hs_mod.set_and_wait_for_shake_speed(300)
    protocol.delay(hours=1)
    hs_mod.deactivate_shaker()
    hs_mod.deactivate_heater()
    hs_mod.open_labware_latch()

    # 读取OD600
    protocol.move_labware(culture_plate, reader, use_gripper=True)
    reader.close_lid()
    od_data = reader.read(export_filename=f"growth_curve_t{timepoint}")
    reader.open_lid()

    # 记录生长
    for well in culture_plate.wells()[:8]:
        od600 = od_data[600][well.well_name]
        protocol.comment(f"T{timepoint}h {well.well_name}: OD600={od600:.3f}")

# 将板返回甲板
protocol.move_labware(culture_plate, "B1", use_gripper=True)

多波长蛋白质测定

# 为BCA或Bradford测定设置
reader = protocol.load_module("absorbanceReaderV1", "D3")
assay_plate = protocol.load_labware("corning_96_wellplate_360ul_flat", "C2")

# 初始化多波长
reader.close_lid()
reader.initialize(mode="multi", wavelengths=[562, 600])
reader.open_lid()

# 准备标准曲线 + 样本(未显示)

# 孵育
protocol.delay(minutes=30)

# 在多波长读取
protocol.move_labware(assay_plate, reader, use_gripper=True)
reader.close_lid()
absorbance = reader.read(export_filename="protein_assay_multi_wl")
reader.open_lid()

# 使用标准曲线计算蛋白质浓度
for well in assay_plate.wells()[:24]:
    od562 = absorbance[562][well.well_name]
    od600 = absorbance[600][well.well_name]

    # 示例:简单线性标准曲线
    protein_conc = od562 * 100  # µg/mL(简化)
    protocol.comment(f"{well.well_name}: {protein_conc:.1f} µg/mL")

实时决策制定

# 读取板并执行条件操作
protocol.move_labware(screening_plate, reader, use_gripper=True)
reader.close_lid()
screen_data = reader.read()
reader.open_lid()
protocol.move_labware(screening_plate, "C1", use_gripper=True)

# 识别命中和拣选
hit_wells = []
for well_name, absorbance in screen_data[450].items():
    if absorbance > 2.0:  # 命中阈值
        hit_wells.append(screening_plate.wells_by_name()[well_name])
        protocol.comment(f"命中:{well_name} (OD450={absorbance:.3f})")

# 将命中转移到新板进行后续
if hit_wells:
    pipette.transfer(50, hit_wells, hit_plate.wells()[:len(hit_wells)])
    protocol.comment(f"找到{len(hit_wells)}个命中 - 转移以验证")

最佳实践

  1. 始终在初始化前关闭盖子 - 即使已经关闭
  2. 使用描述性文件名导出数据 - 包含实验ID、日期、板号
  3. 使用参考波长 - 减少背景和板伪影
  4. 读取空白孔 - 为背景扣除建立基线
  5. 包含标准曲线 - 用于定量测定
  6. 仔细规划甲板布局 - 第4列保留用于盖子存储
  7. 保护第4列 - 切勿尝试在暂存区域加载实验器皿
  8. 允许板平衡 - 移动到阅读器后短暂延迟以防止冷凝问题
  9. 检查夹持器兼容性 - 确保板具有可夹持几何形状
  10. 文档化波长选择 - 注释选择特定波长的原因

常见错误

❌ 盖子打开时初始化:

reader.initialize(mode="single", wavelengths=[450])  # 错误:盖子必须关闭

✅ 正确:

reader.close_lid()
reader.initialize(mode="single", wavelengths=[450])
reader.open_lid()

❌ 在第4列加载实验器皿:

reader = protocol.load_module("absorbanceReaderV1", "D3")
tips = protocol.load_labware("opentrons_flex_96_tiprack_1000ul", "D4")  # 错误:保留

✅ 正确:

reader = protocol.load_module("absorbanceReaderV1", "D3")
tips = protocol.load_labware("opentrons_flex_96_tiprack_1000ul", "D2")  # 使用不同列

❌ 不关闭盖子读取:

protocol.move_labware(plate, reader, use_gripper=True)
data = reader.read()  # 错误:读取时必须关闭盖子

✅ 正确:

protocol.move_labware(plate, reader, use_gripper=True)
reader.close_lid()
data = reader.read()
reader.open_lid()

❌ 使用不支持的波长:

reader.initialize(mode="single", wavelengths=[550])  # 错误:不支持

✅ 正确:

reader.initialize(mode="single", wavelengths=[562])  # 使用450、562、600或650

❌ 访问数据中的错误波长:

reader.initialize(mode="single", wavelengths=[450])
data = reader.read()
od600 = data[600]["A1"]  # 错误:只测量了450纳米

✅ 正确:

reader.initialize(mode="single", wavelengths=[450])
data = reader.read()
od450 = data[450]["A1"]  # 访问测量的波长

故障排除

模块无法加载:

  • 验证API版本为2.21或更高
  • 检查requirements中的robotType: "Flex"
  • 确保模块在第3列插槽(A3-D3)

盖子错误:

  • 始终在initialize()前调用close_lid()
  • 确保第4列暂存区域清空
  • 检查夹持器功能正常

读取错误:

  • 验证read()前盖子关闭
  • 检查板在模块上
  • 确保波长与initialize()中设置匹配

数据访问错误:

  • 访问初始化的波长
  • 使用正确的孔名(“A1"而非"a1”)
  • 检查数据类型(字典,非列表)

夹持器无法移动板:

  • 验证板具有可夹持几何形状
  • 确保在将板移上/移离模块前阅读器盖子打开
  • 检查板与阅读器兼容(96孔板)

与其他模块集成

与加热摇床模块

# 用摇动孵育,读取吸光度
hs_mod = protocol.load_module("heaterShakerModuleV1", "D1")
reader = protocol.load_module("absorbanceReaderV1", "D3")

# 在加热摇床上设置板
protocol.move_labware(assay_plate, hs_mod, use_gripper=True)
hs_mod.set_and_wait_for_temperature(37)
hs_mod.close_labware_latch()
hs_mod.set_and_wait_for_shake_speed(400)
protocol.delay(minutes=30)
hs_mod.deactivate_shaker()
hs_mod.deactivate_heater()
hs_mod.open_labware_latch()

# 移动到阅读器
protocol.move_labware(assay_plate, reader, use_gripper=True)
reader.close_lid()
data = reader.read()
reader.open_lid()

与温度模块

# 冷却样本,然后读取
temp_mod = protocol.load_module("temperature module gen2", "D1")
reader = protocol.load_module("absorbanceReaderV1", "C3")

# 冷却板
protocol.move_labware(assay_plate, temp_mod, use_gripper=True)
temp_mod.set_temperature(4)
protocol.delay(minutes=5)

# 读取冷却的板
protocol.move_labware(assay_plate, reader, use_gripper=True)
reader.close_lid()
data = reader.read()
reader.open_lid()

temp_mod.deactivate()

CSV数据导出

导出的CSV文件存储在机器人上,可通过Opentrons应用程序访问:

  1. 完成协议运行
  2. 打开Opentrons应用程序
  3. 导航到已完成的协议运行
  4. 下载导出的CSV文件
  5. 在Excel、Python、R或其他工具中分析

文件命名: 使用描述性export_filename参数以便识别

data = reader.read(export_filename=f"experiment_{exp_id}_plate_{plate_num}_timepoint_{t}")

API版本要求

  • 最低API版本: 2.21
  • 机器人类型: 仅限Opentrons Flex
  • 推荐: 最新API版本以支持完整功能

附加资源

相关技能

  • opentrons - 主要Opentrons Python API技能
  • opentrons-gripper - 自动化实验器皿移动(阅读器必需)
  • opentrons-heater-shaker - 带混合的温度控制(常见集成)
  • opentrons-temperature-module - 测定的温度控制