|
|
@ -9,6 +9,9 @@ |
|
|
|
|
|
|
|
#define TAG "PipetteModuleV2"
|
|
|
|
|
|
|
|
/***********************************************************************************************************************
|
|
|
|
* MARCO * |
|
|
|
***********************************************************************************************************************/ |
|
|
|
#define ZSLICE(...) ZSlice slice(this, TAG, __FUNCTION__, __VA_ARGS__)
|
|
|
|
#define DO_IN_THREAD(func) \
|
|
|
|
{ \ |
|
|
@ -28,12 +31,18 @@ |
|
|
|
} \ |
|
|
|
} |
|
|
|
|
|
|
|
using namespace iflytop; |
|
|
|
// using namespace pipette_module_v3;
|
|
|
|
|
|
|
|
#define PIPETTE_PREPARE_POS 800
|
|
|
|
#define LLD_PREPARE_DISTRIBUT_POS 100
|
|
|
|
#define LLF_DPOS 1000
|
|
|
|
#define ASPIRATE_POS 0
|
|
|
|
|
|
|
|
using namespace iflytop; |
|
|
|
// using namespace pipette_module_v3;
|
|
|
|
|
|
|
|
static int32_t assign_int32(int32_t *toval, int32_t val) { |
|
|
|
*toval = val; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
void PipetteModuleV2::initialize(int32_t id, config_t *config, hardward_config_t *hardwaredcfg) { //
|
|
|
|
ZASSERT(config != nullptr); |
|
|
@ -67,15 +76,14 @@ void PipetteModuleV2::create_default_cfg(config_t *defaultcfg) { |
|
|
|
cfg.lld_prepare_pos = PIPETTE_PREPARE_POS; |
|
|
|
cfg.lld_prepare_pre_distribut_ul = LLD_PREPARE_DISTRIBUT_POS; |
|
|
|
|
|
|
|
cfg.motor_one_circle_pulse = 10000; |
|
|
|
cfg.motor_one_circle_pulse_denominator = 1; |
|
|
|
cfg.motor_ihold = 1; |
|
|
|
cfg.motor_irun = 3; |
|
|
|
cfg.motor_iholddelay = 100; |
|
|
|
cfg.motor_default_velocity = 500; |
|
|
|
cfg.motor_run_to_zero_speed = 100; |
|
|
|
cfg.motor_look_zero_edge_speed = 100; |
|
|
|
|
|
|
|
cfg.zm_one_circle_pulse = 10000; |
|
|
|
cfg.zm_one_circle_pulse_denominator = 1; |
|
|
|
cfg.zm_ihold = 1; |
|
|
|
cfg.zm_irun = 3; |
|
|
|
cfg.zm_iholddelay = 100; |
|
|
|
cfg.zm_default_velocity = 500; |
|
|
|
cfg.zm_run_to_zero_speed = 100; |
|
|
|
cfg.zm_look_zero_edge_speed = 100; |
|
|
|
} |
|
|
|
int32_t PipetteModuleV2::getid(int32_t *id) { |
|
|
|
*id = m_id; |
|
|
@ -91,21 +99,21 @@ int32_t PipetteModuleV2::module_active_cfg() { |
|
|
|
DO(m_smtp2.pump_set_vstop(m_cfg.pump_vstop)); |
|
|
|
|
|
|
|
m_zm->enable(false); |
|
|
|
m_zm->setIHOLD_IRUN(m_cfg.motor_ihold, m_cfg.motor_irun, m_cfg.motor_iholddelay); |
|
|
|
m_zm->setScale(m_cfg.motor_one_circle_pulse); |
|
|
|
m_zm->setScaleDenominator(m_cfg.motor_one_circle_pulse_denominator); |
|
|
|
m_zm->setMotorShaft(m_cfg.motor_shaft); |
|
|
|
m_zm->setGlobalScale(m_cfg.motor_iglobalscaler); |
|
|
|
|
|
|
|
m_zm->set_vstart(m_cfg.motor_vstart); |
|
|
|
m_zm->set_a1(m_cfg.motor_a1); |
|
|
|
m_zm->set_amax(m_cfg.motor_amax); |
|
|
|
m_zm->set_v1(m_cfg.motor_v1); |
|
|
|
m_zm->set_dmax(m_cfg.motor_dmax); |
|
|
|
m_zm->set_d1(m_cfg.motor_d1); |
|
|
|
m_zm->set_vstop(m_cfg.motor_vstop); |
|
|
|
m_zm->set_tzerowait(m_cfg.motor_tzerowait); |
|
|
|
m_zm->set_enc_resolution(m_cfg.motor_enc_resolution); |
|
|
|
m_zm->setIHOLD_IRUN(m_cfg.zm_ihold, m_cfg.zm_irun, m_cfg.zm_iholddelay); |
|
|
|
m_zm->setScale(m_cfg.zm_one_circle_pulse); |
|
|
|
m_zm->setScaleDenominator(m_cfg.zm_one_circle_pulse_denominator); |
|
|
|
m_zm->setMotorShaft(m_cfg.zm_shaft); |
|
|
|
m_zm->setGlobalScale(m_cfg.zm_iglobalscaler); |
|
|
|
|
|
|
|
m_zm->set_vstart(m_cfg.zm_vstart); |
|
|
|
m_zm->set_a1(m_cfg.zm_a1); |
|
|
|
m_zm->set_amax(m_cfg.zm_amax); |
|
|
|
m_zm->set_v1(m_cfg.zm_v1); |
|
|
|
m_zm->set_dmax(m_cfg.zm_dmax); |
|
|
|
m_zm->set_d1(m_cfg.zm_d1); |
|
|
|
m_zm->set_vstop(m_cfg.zm_vstop); |
|
|
|
m_zm->set_tzerowait(m_cfg.zm_tzerowait); |
|
|
|
m_zm->set_enc_resolution(m_cfg.zm_enc_resolution); |
|
|
|
|
|
|
|
if (m_state.enable) { |
|
|
|
m_zm->enable(true); |
|
|
@ -114,8 +122,8 @@ int32_t PipetteModuleV2::module_active_cfg() { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
#define XXX_CFG_REG(cfgkey, cfg) \
|
|
|
|
case cfgkey: { \ |
|
|
|
#define XXX_CFG_REG(cfg) \
|
|
|
|
case kreg_pipette_##cfg: { \ |
|
|
|
if (read) { \ |
|
|
|
return REG_GET(m_cfg.cfg); \ |
|
|
|
} else { \ |
|
|
@ -127,52 +135,58 @@ int32_t PipetteModuleV2::module_active_cfg() { |
|
|
|
#define XXX_STATE_REG(statekey, action) PROCESS_REG(statekey, action, ACTION_NONE)
|
|
|
|
int32_t PipetteModuleV2::_module_xxx_reg(int32_t param_id, bool read, int32_t &val) { |
|
|
|
switch (param_id) { |
|
|
|
// XXX_STATE_REG(kreg_pipette_pos_ul, /* */ read_pos_ul(&val));
|
|
|
|
// XXX_STATE_REG(kreg_pipette_capactitance_val, /* */ read_capactitance(&val));
|
|
|
|
// XXX_STATE_REG(kreg_pipette_tip_state, /* */ read_tip_state(&val));
|
|
|
|
// XXX_STATE_REG(kreg_step_motor_pos, getnowpos(val), ACTION_NONE);
|
|
|
|
// XXX_STATE_REG(kreg_step_motor_is_enable, REG_GET(m_state.enable), ACTION_NONE);
|
|
|
|
// XXX_STATE_REG(kreg_step_motor_has_move_zero, REG_GET(m_state.has_move_to_zero), ACTION_NONE);
|
|
|
|
// XXX_CFG_REG(kreg_step_motor_dpos, REG_GET(m_state.dpos), ACTION_NONE);
|
|
|
|
|
|
|
|
XXX_CFG_REG(kreg_pipette_limit_ul, limit_ul); |
|
|
|
XXX_CFG_REG(kreg_pipette_pump_acc, pump_acc); |
|
|
|
XXX_CFG_REG(kreg_pipette_pump_dec, pump_dec); |
|
|
|
XXX_CFG_REG(kreg_pipette_pump_vstart, pump_vstart); |
|
|
|
XXX_CFG_REG(kreg_pipette_pump_vstop, pump_vstop); |
|
|
|
XXX_CFG_REG(kreg_pipette_pump_vmax, pump_vmax); |
|
|
|
XXX_CFG_REG(kreg_pipette_aspirate_pump_vel, aspirate_pump_vel); |
|
|
|
XXX_CFG_REG(kreg_pipette_lld_pump_vel, lld_pump_vel); |
|
|
|
XXX_CFG_REG(kreg_pipette_lld_motor_vel_rpm, lld_motor_vel_rpm); |
|
|
|
XXX_CFG_REG(kreg_pipette_lld_detect_period_ms, lld_detect_period_ms); |
|
|
|
XXX_CFG_REG(kreg_pipette_lld_prepare_pos, lld_prepare_pos); |
|
|
|
XXX_CFG_REG(kreg_pipette_lld_prepare_pre_distribut_ul, lld_prepare_pre_distribut_ul); |
|
|
|
|
|
|
|
XXX_CFG_REG(kreg_step_motor_shaft, motor_shaft); |
|
|
|
XXX_CFG_REG(kreg_step_motor_one_circle_pulse, motor_one_circle_pulse); |
|
|
|
XXX_CFG_REG(kreg_step_motor_one_circle_pulse_denominator, motor_one_circle_pulse_denominator); |
|
|
|
XXX_CFG_REG(kreg_step_motor_default_velocity, motor_default_velocity); |
|
|
|
XXX_CFG_REG(kreg_step_motor_run_to_zero_speed, motor_run_to_zero_speed); |
|
|
|
XXX_CFG_REG(kreg_step_motor_look_zero_edge_speed, motor_look_zero_edge_speed); |
|
|
|
XXX_CFG_REG(kreg_step_motor_ihold, motor_ihold); |
|
|
|
XXX_CFG_REG(kreg_step_motor_irun, motor_irun); |
|
|
|
XXX_CFG_REG(kreg_step_motor_iholddelay, motor_iholddelay); |
|
|
|
XXX_CFG_REG(kreg_step_motor_max_d, motor_max_d); |
|
|
|
XXX_CFG_REG(kreg_step_motor_min_d, motor_min_d); |
|
|
|
XXX_CFG_REG(kreg_step_motor_iglobalscaler, motor_iglobalscaler); |
|
|
|
|
|
|
|
XXX_CFG_REG(kreg_step_motor_vstart, motor_vstart); |
|
|
|
XXX_CFG_REG(kreg_step_motor_a1, motor_a1); |
|
|
|
XXX_CFG_REG(kreg_step_motor_amax, motor_amax); |
|
|
|
XXX_CFG_REG(kreg_step_motor_v1, motor_v1); |
|
|
|
XXX_CFG_REG(kreg_step_motor_dmax, motor_dmax); |
|
|
|
XXX_CFG_REG(kreg_step_motor_d1, motor_d1); |
|
|
|
XXX_CFG_REG(kreg_step_motor_vstop, motor_vstop); |
|
|
|
XXX_CFG_REG(kreg_step_motor_tzerowait, motor_tzerowait); |
|
|
|
XXX_CFG_REG(kreg_step_motor_enc_resolution, motor_enc_resolution); |
|
|
|
XXX_CFG_REG(kreg_step_motor_enable_enc, motor_enable_enc); |
|
|
|
XXX_CFG_REG(kreg_step_motor_dzero_pos, motor_dzero); |
|
|
|
XXX_CFG_REG(kreg_step_motor_pos_devi_tolerance, pos_devi_tolerance); |
|
|
|
/***********************************************************************************************************************
|
|
|
|
* STATE * |
|
|
|
***********************************************************************************************************************/ |
|
|
|
XXX_STATE_REG(kreg_pipette_pos_ul, /* */ pump_read_pos_ul(&val)); |
|
|
|
XXX_STATE_REG(kreg_pipette_capactitance_val, /* */ pump_read_capactitance(&val)); |
|
|
|
XXX_STATE_REG(kreg_pipette_tip_state, /* */ pump_read_tip_state(&val)); |
|
|
|
XXX_STATE_REG(kreg_pipette_zm_pos, assign_int32(&val, zm_get_now_pos())); |
|
|
|
XXX_STATE_REG(kreg_pipette_zm_is_enable, REG_GET(m_state.enable)); |
|
|
|
XXX_STATE_REG(kreg_pipette_zm_dpos, REG_GET(m_state.dpos)); |
|
|
|
|
|
|
|
/***********************************************************************************************************************
|
|
|
|
* CFG * |
|
|
|
***********************************************************************************************************************/ |
|
|
|
XXX_CFG_REG(limit_ul); |
|
|
|
XXX_CFG_REG(pump_acc); |
|
|
|
XXX_CFG_REG(pump_dec); |
|
|
|
XXX_CFG_REG(pump_vstart); |
|
|
|
XXX_CFG_REG(pump_vstop); |
|
|
|
XXX_CFG_REG(pump_vmax); |
|
|
|
XXX_CFG_REG(aspirate_pump_vel); |
|
|
|
XXX_CFG_REG(lld_pump_vel); |
|
|
|
XXX_CFG_REG(lld_motor_vel_rpm); |
|
|
|
XXX_CFG_REG(lld_detect_period_ms); |
|
|
|
XXX_CFG_REG(lld_prepare_pos); |
|
|
|
XXX_CFG_REG(lld_prepare_pre_distribut_ul); |
|
|
|
|
|
|
|
XXX_CFG_REG(zm_shaft); |
|
|
|
XXX_CFG_REG(zm_one_circle_pulse); |
|
|
|
XXX_CFG_REG(zm_one_circle_pulse_denominator); |
|
|
|
XXX_CFG_REG(zm_default_velocity); |
|
|
|
XXX_CFG_REG(zm_run_to_zero_speed); |
|
|
|
XXX_CFG_REG(zm_look_zero_edge_speed); |
|
|
|
XXX_CFG_REG(zm_ihold); |
|
|
|
XXX_CFG_REG(zm_irun); |
|
|
|
XXX_CFG_REG(zm_iholddelay); |
|
|
|
XXX_CFG_REG(zm_max_d); |
|
|
|
XXX_CFG_REG(zm_min_d); |
|
|
|
XXX_CFG_REG(zm_iglobalscaler); |
|
|
|
|
|
|
|
XXX_CFG_REG(zm_vstart); |
|
|
|
XXX_CFG_REG(zm_a1); |
|
|
|
XXX_CFG_REG(zm_amax); |
|
|
|
XXX_CFG_REG(zm_v1); |
|
|
|
XXX_CFG_REG(zm_dmax); |
|
|
|
XXX_CFG_REG(zm_d1); |
|
|
|
XXX_CFG_REG(zm_vstop); |
|
|
|
XXX_CFG_REG(zm_tzerowait); |
|
|
|
XXX_CFG_REG(zm_enc_resolution); |
|
|
|
XXX_CFG_REG(zm_enable_enc); |
|
|
|
XXX_CFG_REG(zm_dzero); |
|
|
|
XXX_CFG_REG(zm_pos_devi_tolerance); |
|
|
|
XXX_CFG_REG(zm_io_trigger_append_distance); |
|
|
|
|
|
|
|
default: |
|
|
|
return err::kmodule_not_find_reg; |
|
|
@ -194,6 +208,17 @@ int32_t PipetteModuleV2::module_xxx_reg(int32_t param_id, bool read, int32_t &va |
|
|
|
* EXT_API * |
|
|
|
***********************************************************************************************************************/ |
|
|
|
|
|
|
|
int32_t PipetteModuleV2::pipette_zmotor_enable(int32_t enable) { |
|
|
|
ZLOGI(TAG, "m%d pipette_zmotor_enable %ld", m_id, enable); |
|
|
|
m_thread.stop(); |
|
|
|
m_zm->enable(enable); |
|
|
|
m_state.enable = enable; |
|
|
|
if (enable == 0 && m_cfg.zm_enable_enc == 0) { |
|
|
|
m_state.has_move_to_zero = 0; |
|
|
|
} |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief 移动到零点 |
|
|
|
* |
|
|
@ -203,7 +228,8 @@ int32_t PipetteModuleV2::pipette_zmotor_move_zero() { // |
|
|
|
thread_start_work([this]() { |
|
|
|
do_zm_move_0p(); // 移动到零点
|
|
|
|
if (creg.module_errorcode != 0) { // 计算并更新零点坐标
|
|
|
|
zm_set_now_pos(0 + m_cfg.motor_dzero - m_cfg.io_trigger_append_distance); |
|
|
|
zm_set_now_pos(0 + m_cfg.zm_dzero - m_cfg.zm_io_trigger_append_distance); |
|
|
|
m_state.has_move_to_zero = 1; |
|
|
|
} |
|
|
|
}); |
|
|
|
return 0; |
|
|
@ -220,9 +246,10 @@ int32_t PipetteModuleV2::pipette_zmotor_measure_distance() { |
|
|
|
do_zm_move_0p(); // 移动到零点
|
|
|
|
int32_t dpos = zm_get_now_pos() - startpos; |
|
|
|
if (creg.module_errorcode != 0) { // 计算并更新零点坐标
|
|
|
|
zm_set_now_pos(0 + m_cfg.motor_dzero - m_cfg.io_trigger_append_distance); |
|
|
|
zm_set_now_pos(0 + m_cfg.zm_dzero - m_cfg.zm_io_trigger_append_distance); |
|
|
|
m_state.has_move_to_zero = 1; |
|
|
|
} |
|
|
|
m_asynchronous_result.result0 = 0 + m_cfg.motor_dzero - m_cfg.io_trigger_append_distance - dpos; |
|
|
|
m_asynchronous_result.result0 = 0 + m_cfg.zm_dzero - m_cfg.zm_io_trigger_append_distance - dpos; |
|
|
|
}); |
|
|
|
return 0; |
|
|
|
} |
|
|
@ -237,7 +264,6 @@ int32_t PipetteModuleV2::pipette_zmotor_read_measure_distance_result(int32_t *re |
|
|
|
*result0 = m_asynchronous_result.result0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief 相对位移 |
|
|
|
* |
|
|
@ -246,7 +272,7 @@ int32_t PipetteModuleV2::pipette_zmotor_read_measure_distance_result(int32_t *re |
|
|
|
*/ |
|
|
|
int32_t PipetteModuleV2::pipette_zmotor_move_by(int32_t distance) { |
|
|
|
thread_start_work([this, distance]() { |
|
|
|
zm_move_by(distance, m_cfg.motor_default_velocity); |
|
|
|
zm_move_by(distance, m_cfg.zm_default_velocity); |
|
|
|
zm_waitfor_stop(); |
|
|
|
}); |
|
|
|
return 0; |
|
|
@ -257,11 +283,16 @@ int32_t PipetteModuleV2::pipette_zmotor_move_by(int32_t distance) { |
|
|
|
* @param position |
|
|
|
* @return int32_t |
|
|
|
*/ |
|
|
|
int32_t PipetteModuleV2::pipette_zmotor_move_to(int32_t position) { |
|
|
|
thread_start_work([this, position]() { |
|
|
|
zm_move_to(position, m_cfg.motor_default_velocity); |
|
|
|
int32_t PipetteModuleV2::pipette_zmotor_move_to(int32_t tox) { |
|
|
|
if (m_state.has_move_to_zero == 0) return err::kstep_motor_not_move_to_zero; |
|
|
|
if (m_cfg.zm_min_d != 0 && tox < m_cfg.zm_min_d) tox = m_cfg.zm_min_d; |
|
|
|
if (m_cfg.zm_max_d != 0 && tox > m_cfg.zm_max_d) tox = m_cfg.zm_max_d; |
|
|
|
|
|
|
|
thread_start_work([this, tox]() { |
|
|
|
zm_move_to(tox, m_cfg.zm_default_velocity); |
|
|
|
zm_waitfor_stop(); |
|
|
|
}); |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
/**
|
|
|
@ -270,6 +301,7 @@ int32_t PipetteModuleV2::pipette_zmotor_move_to(int32_t position) { |
|
|
|
* @return int32_t |
|
|
|
*/ |
|
|
|
int32_t PipetteModuleV2::pipette_zmotor_move_to_zero_point_quick() { |
|
|
|
if (m_state.has_move_to_zero == 0) return err::kstep_motor_not_move_to_zero; |
|
|
|
thread_start_work([this]() { do_pipette_zmotor_move_to_zero_point_quick(); }); |
|
|
|
return 0; |
|
|
|
} |
|
|
@ -280,7 +312,6 @@ int32_t PipetteModuleV2::pipette_init_device() { |
|
|
|
pump_waitfor_stop(); |
|
|
|
//
|
|
|
|
m_state.load_val_ul = 0; |
|
|
|
m_state.aspirated = 0; |
|
|
|
m_state.lld_prepared = 0; |
|
|
|
m_state.pipette_is_inited = 1; |
|
|
|
}); |
|
|
@ -293,6 +324,8 @@ int32_t PipetteModuleV2::pipette_put_tip() { |
|
|
|
} |
|
|
|
|
|
|
|
int32_t PipetteModuleV2::pipette_lld_prepare() { |
|
|
|
if (m_state.pipette_is_inited == 0) return err::kpipette_error_uninited; |
|
|
|
|
|
|
|
thread_start_work([this]() { |
|
|
|
DO_IN_THREAD(m_smtp2.pump_move_to_ul(m_cfg.pump_vmax, m_cfg.lld_prepare_pos)); // 移动到中点
|
|
|
|
pump_waitfor_stop(); |
|
|
@ -301,6 +334,14 @@ int32_t PipetteModuleV2::pipette_lld_prepare() { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
int32_t PipetteModuleV2::pipette_lld(int32_t lldtype, int32_t zdpos, int32_t c_threshold, int32_t p_threshold) { |
|
|
|
// 检查泵机是否初始化过
|
|
|
|
if (m_state.pipette_is_inited == 0) return err::kpipette_error_uninited; |
|
|
|
|
|
|
|
// 检查tip头状态
|
|
|
|
int32_t tipstate = 0; |
|
|
|
DO(m_smtp2.pump_get_tip_state(&tipstate)); |
|
|
|
if (tipstate != 0) return err::kpipette_error_tipisload_when_lld_prepare; |
|
|
|
|
|
|
|
thread_start_work([this, lldtype, zdpos, c_threshold, p_threshold]() { //
|
|
|
|
m_state.lld_prepared = 0; // 失效m_state.lld_prepared
|
|
|
|
|
|
|
@ -391,12 +432,14 @@ int32_t PipetteModuleV2::pipette_lld(int32_t lldtype, int32_t zdpos, int32_t c_t |
|
|
|
} |
|
|
|
|
|
|
|
int32_t PipetteModuleV2::pipette_aspirate_prepare() { |
|
|
|
if (m_state.pipette_is_inited == 0) return err::kpipette_error_uninited; |
|
|
|
|
|
|
|
thread_start_work([this]() { //
|
|
|
|
ZLOGI(TAG, "pipette_aspirate_prepare"); |
|
|
|
m_state.aspirate_cfg_eigen_time = 0; |
|
|
|
m_state.aspirate_cfg_p_thre = 0; |
|
|
|
m_state.aspirate_cfg_llf_zm_rpm = 0; |
|
|
|
DO_IN_THREAD(m_smtp2.pump_move_to_ul(m_cfg.pump_vmax, 0)); |
|
|
|
DO_IN_THREAD(m_smtp2.pump_move_to_ul(m_cfg.pump_vmax, ASPIRATE_POS)); |
|
|
|
pump_waitfor_stop(); |
|
|
|
ZLOGI(TAG, "pipette_aspirate_prepare end..."); |
|
|
|
}); |
|
|
@ -426,10 +469,14 @@ int32_t PipetteModuleV2::pipette_aspirate_set_operation_verifi_tolerance(int32_t |
|
|
|
} |
|
|
|
|
|
|
|
int32_t PipetteModuleV2::pipette_aspirate(int32_t ul) { |
|
|
|
if (m_state.pipette_is_inited == 0) return err::kpipette_error_uninited; |
|
|
|
|
|
|
|
thread_start_work([this, ul]() { |
|
|
|
m_state.aspirated = 1; |
|
|
|
m_state.lld_prepared = 0; |
|
|
|
|
|
|
|
DO_IN_THREAD(m_smtp2.pump_move_to_ul(m_cfg.pump_vmax, ASPIRATE_POS)); |
|
|
|
pump_waitfor_stop(); |
|
|
|
|
|
|
|
if (ul > 0) { |
|
|
|
// zmotor and pump move
|
|
|
|
if (m_state.aspirate_cfg_llf_zm_rpm != 0) zm_move_by(m_cfg.aspirate_zmotor_max_move_by, m_state.aspirate_cfg_llf_zm_rpm); |
|
|
@ -450,8 +497,9 @@ int32_t PipetteModuleV2::pipette_aspirate(int32_t ul) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
int32_t PipetteModuleV2::pipette_aspirate_and_verify(int32_t ul) { |
|
|
|
if (m_state.pipette_is_inited == 0) return err::kpipette_error_uninited; |
|
|
|
|
|
|
|
thread_start_work([this, ul]() { |
|
|
|
m_state.aspirated = 1; |
|
|
|
m_state.lld_prepared = 0; |
|
|
|
|
|
|
|
// zmotor and pump move
|
|
|
@ -473,6 +521,8 @@ int32_t PipetteModuleV2::pipette_aspirate_and_verify(int32_t ul) { |
|
|
|
} |
|
|
|
|
|
|
|
int32_t PipetteModuleV2::pipette_shake_up(int32_t ul, int32_t times) { |
|
|
|
if (m_state.pipette_is_inited == 0) return err::kpipette_error_uninited; |
|
|
|
|
|
|
|
thread_start_work([this, ul, times]() { |
|
|
|
//
|
|
|
|
int32_t dpos = 0; |
|
|
@ -512,6 +562,8 @@ int32_t PipetteModuleV2::pipette_shake_up(int32_t ul, int32_t times) { |
|
|
|
} |
|
|
|
|
|
|
|
int32_t PipetteModuleV2::pipette_aspirate_infer_pressure(int32_t ul) { |
|
|
|
if (m_state.pipette_is_inited == 0) return err::kpipette_error_uninited; |
|
|
|
|
|
|
|
thread_start_work([this, ul]() { |
|
|
|
//
|
|
|
|
ZLOGI(TAG, "pipette_aspirate_infer_pressure %d", ul); |
|
|
@ -528,6 +580,8 @@ int32_t PipetteModuleV2::pipette_get_aspirate_infer_pressure_result(int32_t *res |
|
|
|
return 0; |
|
|
|
} |
|
|
|
int32_t PipetteModuleV2::pipette_aspirate_infer_eigen_time(int32_t ul) { |
|
|
|
if (m_state.pipette_is_inited == 0) return err::kpipette_error_uninited; |
|
|
|
|
|
|
|
//
|
|
|
|
thread_start_work([this, ul]() { |
|
|
|
//
|
|
|
@ -560,39 +614,39 @@ int32_t PipetteModuleV2::pipette_get_aspirate_infer_eigen_time_result(int32_t *r |
|
|
|
***********************************************************************************************************************/ |
|
|
|
void PipetteModuleV2::do_zm_move_0p() { |
|
|
|
if (!zm0p_is_trigger()) { |
|
|
|
zm_move_to_end(-1, m_cfg.motor_run_to_zero_speed); |
|
|
|
zm_move_to_end(-1, m_cfg.zm_run_to_zero_speed); |
|
|
|
zm_waitfor_zm0p_trigger_and_stop_motor(); |
|
|
|
} |
|
|
|
|
|
|
|
// leave from zero
|
|
|
|
if (zm0p_is_trigger()) { |
|
|
|
zm_move_to_end(1, m_cfg.motor_look_zero_edge_speed); |
|
|
|
zm_move_to_end(1, m_cfg.zm_look_zero_edge_speed); |
|
|
|
zm_waitfor_zm0p_not_trigger_and_stop_motor(); |
|
|
|
} |
|
|
|
|
|
|
|
// move to zero again
|
|
|
|
if (!zm0p_is_trigger()) { |
|
|
|
zm_move_to_end(-1, m_cfg.motor_run_to_zero_speed); |
|
|
|
zm_move_to_end(-1, m_cfg.zm_run_to_zero_speed); |
|
|
|
zm_waitfor_zm0p_trigger_and_stop_motor(); |
|
|
|
} |
|
|
|
|
|
|
|
// move to zero
|
|
|
|
zm_move_by(m_cfg.io_trigger_append_distance, m_cfg.motor_run_to_zero_speed); |
|
|
|
zm_move_by(m_cfg.zm_io_trigger_append_distance, m_cfg.zm_run_to_zero_speed); |
|
|
|
zm_waitfor_stop(); |
|
|
|
} |
|
|
|
|
|
|
|
void PipetteModuleV2::do_pipette_zmotor_move_to_zero_point_quick() { |
|
|
|
// 期望偏差
|
|
|
|
int32_t expectation_dpos = -m_cfg.io_trigger_append_distance + 0 + m_cfg.motor_dzero - zm_get_now_pos(); |
|
|
|
int32_t expectation_dpos = -m_cfg.zm_io_trigger_append_distance + 0 + m_cfg.zm_dzero - zm_get_now_pos(); |
|
|
|
int32_t startpos = zm_get_now_pos(); |
|
|
|
if (!zm0p_is_trigger()) { |
|
|
|
// 快速移动到零点
|
|
|
|
// moveTo(0 + m_cfg.motor_dzero, m_cfg.motor_default_velocity);
|
|
|
|
zm_move_to(0 + m_cfg.motor_dzero, m_cfg.motor_default_velocity); |
|
|
|
// moveTo(0 + m_cfg.zm_dzero, m_cfg.zm_default_velocity);
|
|
|
|
zm_move_to(0 + m_cfg.zm_dzero, m_cfg.zm_default_velocity); |
|
|
|
zm_waitfor_zm0p_trigger_and_stop_motor(); |
|
|
|
} else { |
|
|
|
// 快速移动到零点
|
|
|
|
zm_move_to(0 + m_cfg.motor_dzero, m_cfg.motor_default_velocity); |
|
|
|
zm_move_to(0 + m_cfg.zm_dzero, m_cfg.zm_default_velocity); |
|
|
|
zm_waitfor_zm0p_not_trigger_and_stop_motor(); |
|
|
|
} |
|
|
|
// 移动到零点
|
|
|
@ -600,7 +654,7 @@ void PipetteModuleV2::do_pipette_zmotor_move_to_zero_point_quick() { |
|
|
|
|
|
|
|
// 校验偏差
|
|
|
|
int32_t dpos = zm_get_now_pos() - startpos; |
|
|
|
if (m_cfg.pos_devi_tolerance != 0 && (abs(expectation_dpos - dpos) > m_cfg.pos_devi_tolerance)) { |
|
|
|
if (m_cfg.zm_pos_devi_tolerance != 0 && (abs(expectation_dpos - dpos) > m_cfg.zm_pos_devi_tolerance)) { |
|
|
|
throw zapp_exception(err::kstep_motor_lost_step); |
|
|
|
} |
|
|
|
} |
|
|
@ -620,7 +674,7 @@ int32_t PipetteModuleV2::pipette_zmotor_read_dev_status_cache(int32_t *devStatus |
|
|
|
* ZM_UTILS * |
|
|
|
***********************************************************************************************************************/ |
|
|
|
int32_t PipetteModuleV2::zm_get_now_pos() { |
|
|
|
if (m_cfg.motor_enable_enc == 0) { |
|
|
|
if (m_cfg.zm_enable_enc == 0) { |
|
|
|
return m_zm->getXACTUAL(); |
|
|
|
} |
|
|
|
return m_zm->read_enc_val(); |
|
|
@ -630,29 +684,29 @@ void PipetteModuleV2::zm_set_now_pos(int32_t x) { |
|
|
|
m_zm->set_enc_val(x); |
|
|
|
} |
|
|
|
void PipetteModuleV2::zm_move_to(int32_t x, int32_t v) { |
|
|
|
if (m_cfg.motor_enable_enc != 0) { |
|
|
|
if (m_cfg.zm_enable_enc != 0) { |
|
|
|
m_zm->setXACTUAL(m_zm->read_enc_val()); |
|
|
|
} |
|
|
|
m_zm->moveTo(x, v); |
|
|
|
} |
|
|
|
void PipetteModuleV2::zm_move_by(int32_t dx, int32_t v) { |
|
|
|
if (m_cfg.motor_enable_enc != 0) { |
|
|
|
if (m_cfg.zm_enable_enc != 0) { |
|
|
|
m_zm->setXACTUAL(m_zm->read_enc_val()); |
|
|
|
} |
|
|
|
m_zm->moveBy(dx, v); |
|
|
|
} |
|
|
|
|
|
|
|
void PipetteModuleV2::zm_move_to_end(int32_t direction, int32_t v) { |
|
|
|
if (m_cfg.motor_enable_enc != 0) { |
|
|
|
if (m_cfg.zm_enable_enc != 0) { |
|
|
|
m_zm->setXACTUAL(m_zm->read_enc_val()); |
|
|
|
} |
|
|
|
m_zm->moveToEnd(direction, v); |
|
|
|
} |
|
|
|
|
|
|
|
void PipetteModuleV2::zm_update_dzero(int32_t dzero) { |
|
|
|
int32_t nowabs = zm_get_now_pos() - m_cfg.motor_dzero; |
|
|
|
m_cfg.motor_dzero = dzero; |
|
|
|
zm_set_now_pos(nowabs + m_cfg.motor_dzero); |
|
|
|
int32_t nowabs = zm_get_now_pos() - m_cfg.zm_dzero; |
|
|
|
m_cfg.zm_dzero = dzero; |
|
|
|
zm_set_now_pos(nowabs + m_cfg.zm_dzero); |
|
|
|
} |
|
|
|
bool PipetteModuleV2::zm0p_is_trigger() { return m_zm0p->getState(); } |
|
|
|
|
|
|
@ -674,6 +728,21 @@ void PipetteModuleV2::pump_waitfor_stop() { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
int32_t PipetteModuleV2::pump_read_pos_ul(int32_t *val) { |
|
|
|
//
|
|
|
|
*val = m_state.load_val_ul; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
int32_t PipetteModuleV2::pump_read_capactitance(int32_t *val) { |
|
|
|
m_smtp2.pump_get_capacitance(val); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
int32_t PipetteModuleV2::pump_read_tip_state(int32_t *val) { |
|
|
|
*val = 0; |
|
|
|
m_smtp2.pump_get_tip_state(val); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
void PipetteModuleV2::zm_waitfor_zm0p_not_trigger_and_stop_motor() { |
|
|
|
// 等待触发
|
|
|
|
while (zm0p_is_trigger()) thread_delay(2); |
|
|
@ -708,6 +777,45 @@ void PipetteModuleV2::push_snesor_sample_data(int32_t motor_pos, int32_t cap_val |
|
|
|
*/ |
|
|
|
int32_t PipetteModuleV2::bfcall(int32_t cmdid, uint8_t *param, int32_t len) { |
|
|
|
ZLOGI(TAG, "bfcall %s", cmdid2str(cmdid)); |
|
|
|
|
|
|
|
if (cmdid == kpipette_zmotor_move_zero) goto check; |
|
|
|
if (cmdid == kpipette_zmotor_move_to_zero_point_quick) goto check; |
|
|
|
if (cmdid == kpipette_zmotor_measure_distance) goto check; |
|
|
|
if (cmdid == kpipette_zmotor_read_measure_distance_result) goto check; |
|
|
|
if (cmdid == kpipette_zmotor_move_by) goto check; |
|
|
|
if (cmdid == kpipette_zmotor_move_to) goto check; |
|
|
|
if (cmdid == kpipette_init_device) goto check; |
|
|
|
if (cmdid == kpipette_put_tip) goto check; |
|
|
|
if (cmdid == kpipette_lld_prepare) goto check; |
|
|
|
if (cmdid == kpipette_lld) goto check; |
|
|
|
if (cmdid == kpipette_aspirate_prepare) goto check; |
|
|
|
if (cmdid == kpipette_aspirate_set_llf_velocity) goto check; |
|
|
|
if (cmdid == kpipette_aspirate_set_operation_verifi_p_thre) goto check; |
|
|
|
if (cmdid == kpipette_aspirate_set_operation_verifi_eigen_time) goto check; |
|
|
|
if (cmdid == kpipette_aspirate_set_operation_verifi_tolerance) goto check; |
|
|
|
if (cmdid == kpipette_aspirate) goto check; |
|
|
|
if (cmdid == kpipette_aspirate_and_verify) goto check; |
|
|
|
if (cmdid == kpipette_shake_up) goto check; |
|
|
|
if (cmdid == kpipette_aspirate_infer_pressure) goto check; |
|
|
|
if (cmdid == kpipette_aspirate_infer_eigen_time) goto check; |
|
|
|
|
|
|
|
check: |
|
|
|
if (!m_state.enable) { |
|
|
|
return err::kstep_motor_not_enable; |
|
|
|
} |
|
|
|
if (creg.module_errorcode == err::kstep_motor_subic_reset) { |
|
|
|
return creg.module_errorcode; |
|
|
|
} else if (creg.module_errorcode == err::kstep_motor_drv_err) { |
|
|
|
return creg.module_errorcode; |
|
|
|
} else if (creg.module_errorcode == err::kstep_motor_uv_cp) { |
|
|
|
return creg.module_errorcode; |
|
|
|
} else { |
|
|
|
/**
|
|
|
|
* @brief 其他错误允许设备继续运行 |
|
|
|
*/ |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
void PipetteModuleV2::aftercall(int32_t val) { |
|
|
@ -719,7 +827,7 @@ void PipetteModuleV2::aftercall(int32_t val) { |
|
|
|
} |
|
|
|
void PipetteModuleV2::runingcheck() { |
|
|
|
// 检查是否丢步
|
|
|
|
if (m_cfg.motor_enable_enc != 0) { |
|
|
|
if (m_cfg.zm_enable_enc != 0) { |
|
|
|
vPortEnterCritical(); |
|
|
|
|
|
|
|
int32_t m1enc = m_zm->read_enc_val(); |
|
|
@ -729,8 +837,8 @@ void PipetteModuleV2::runingcheck() { |
|
|
|
|
|
|
|
int32_t dm1 = abs(m1enc - m1pos); |
|
|
|
|
|
|
|
if (m_cfg.pos_devi_tolerance != 0) { |
|
|
|
if (dm1 > m_cfg.pos_devi_tolerance) { |
|
|
|
if (m_cfg.zm_pos_devi_tolerance != 0) { |
|
|
|
if (dm1 > m_cfg.zm_pos_devi_tolerance) { |
|
|
|
ZLOGE(TAG, "motor pos devi %d", dm1); |
|
|
|
creg.module_errorcode = err::kstep_motor_lost_step; |
|
|
|
} |
|
|
|