I’m trying to implement liquid level detection on a STAR. When I run my aspiration cycle (code below), the following happens:
- Tip moves to above correct well
- Plunger moves to completely empty state
- Very rapidly (takes ~1 second), the tip moves down while the plunger moves up.
- (a) If a tall water column is present, this movement stops after a few mm, and the liquid level is detected quite accurately. Aspiration occurs at the liquid level.
- (b) If only a thin layer of water was present, instead the tip rams into the plate. The z-definition of my labware is correct, I verified that by moving the tip to
plate[5][0].get_absolute_location("center", "center", "bottom")
. The ram is quite hard, when I run the aspiration without carrier present, the tip dips below the carrier level.
Is there an argument that slows down step 3 so that small amounts of liquid can be detected? We’re working with 6 well plates that contain only 3 mL of liquid, which equates to a water column of only around 3 mm. The robot is not able to detect this liquid level. In my observations, the argument lld_search_height
doesn’t seem to do much. Step 3 always starts very high above the liquid level no matter which value I enter here.
Code:
# some function definitions
def _serialize(single_arg, channels_to_use: list[int]) -> list:
return [single_arg] * len(channels_to_use)
def _mm2dmm(distance_in_mm: float) -> int:
return int(round(distance_in_mm * 10, 0))
def _serialize_and_convert(single_arg: float, channels_to_use: list[int]) -> list[int]:
serialized_args = _serialize(single_arg, channels_to_use)
return [_mm2dmm(arg) for arg in serialized_args]
# parameters
channels_to_use = [9]
well_source = plate[1]
vol_transfer = 500 # volume to transfer
vol_source = 500 # volume in source well
vol_dest = 0 # volume in destination well
well_source_liquid_level = well_source[0].compute_height_from_volume(liquid_volume=vol_source)
well_source_following_distance = well_source[0].compute_height_from_volume(vol_source) - well_source[
0
].compute_height_from_volume(vol_source - vol_transfer)
await lh.aspirate(
resources=well_source,
vols=_serialize(vol_transfer, channels_to_use),
use_channels=channels_to_use,
lld_mode=_serialize(STAR.LLDMode.PRESSURE, channels_to_use),
lld_search_height=_serialize_and_convert(well_source_liquid_level, channels_to_use),
liquid_height=_serialize(well_source_liquid_level, channels_to_use),
surface_following_distance=_serialize_and_convert(well_source_following_distance, channels_to_use),
swap_speed=100,
)
I must be doing something wrong!