Subdevice error in EVO200 dispensing

Hi Rick,
We are now facing a new problem. When using pylabrobot to operate EVO200, the aspirate part runs normally, but the dispense part fails with the error ‘Subdevice error’, ‘C5’, 28.
We tried to change some codes, such as adding a delay time between aspirate and dispense, but it didn’t work.
We solved this problem by running the dispense code a second time, and it worked the second time. This problem makes us very confused. Do you have any good solution?

1 Like

Tecan_operation.txt.pdf (20.9 KB)
Here is our log file!Thanks!

I’ll take a look this weekend to see if there’s anything I can see, but it’s difficult since I never worked really closely with the EVO and we don’t have one right now

That sounds nice!! Thank you!

One thing that I noticed was the “Set End Speed” SEP command was too high for dispense

I found this in your log file:
2025-02-21 11:50:51,132 - pylabrobot - INFO - Sent command: C5SEP7200,7200,7200,

The max value for this command is 6000

Does it aspirate the correct amount? I found that it was 2x higher volume.

I changed a few multipliers for converting ul to steps. Not sure this is the correct way to do this.

  def _dispense_action(
    self,
    ops: Sequence[Union[SingleChannelAspiration, SingleChannelDispense]],
    use_channels: List[int],
    tecan_liquid_classes: List[Optional[TecanLiquidClass]],
  ) -> Tuple[
    List[Optional[int]],
    List[Optional[int]],
    List[Optional[int]],
    List[Optional[int]],
  ]:
    """Creates parameters used for dispense action.

    Returns:
      sep: set_end_speed_plunger
      spp: set_stop_speed_plunger
      stz: set_tracking_distance_z
      mtr: move_tracking_relative
    """

    sep: List[Optional[int]] = [None] * self.num_channels
    spp: List[Optional[int]] = [None] * self.num_channels
    stz: List[Optional[int]] = [None] * self.num_channels
    mtr: List[Optional[int]] = [None] * self.num_channels

    for i, channel in enumerate(use_channels):
      tlc = tecan_liquid_classes[i]
      assert tlc is not None
      flow_rate = ops[i].flow_rate or tlc.dispense_speed
      sep[channel] = int(flow_rate * 6)  # 6?
      spp[channel] = int(tlc.dispense_breakoff * 6)  # 6?
      stz[channel] = 0
      volume = (
        tlc.compute_corrected_volume(ops[i].volume)
        + tlc.aspirate_lag_volume
        + tlc.aspirate_tag_volume
      )
      mtr[channel] = -round(volume * 3)  # 3?

    return sep, spp, stz, mtr

The multipliers, or generally the conversion from mm to robot-specific steps, can be a bit annoying at times.

7200 means you set it to 7200/6 = 1200 uL/s.

Perplexity says the maximum flow rate is actually 600 uL/s:

https://www.perplexity.ai/search/maximum-flow-rate-tecan-evo-u2WxckjHTAWioLDChLBskw

When we confirm this we should build it into PLR as a check.

This makes me think the conversion should be *10 not *6. This would a) match 600uL/s to the maximum firmware value, b) be consistent with other conversions in the evo backend, implying all units are [0.1 SI unit], c) which is actually the same as it is on Hamilton STARs and some parts of Vantage.

But the way to really figure these things out is to have EVOWare send a command with known flow rates and see what firmware command is sent. But since neither of us has a computer with evoware that might be difficult. Hopefully someone with evoware can confirm.

In the meantime, is it possible to use a manual pipette to determine how much liquid is aspirated/dispensed somewhere? And from there, by timing, we can figure out the flow rate.