|
@ -66,22 +66,24 @@ void PipetteModuleV2::initialize(int32_t id, config_t *config, hardward_config_t |
|
|
|
|
|
|
|
|
m_zm->getGState(); // 读取状态,清空下复位标识
|
|
|
m_zm->getGState(); // 读取状态,清空下复位标识
|
|
|
module_active_cfg(); |
|
|
module_active_cfg(); |
|
|
|
|
|
|
|
|
|
|
|
// m_smtp2.dumpparam();
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void PipetteModuleV2::create_default_cfg(config_t *defaultcfg) { |
|
|
void PipetteModuleV2::create_default_cfg(config_t *defaultcfg) { |
|
|
// defaultcfg->limit_ul = 250;
|
|
|
// defaultcfg->limit_ul = 250;
|
|
|
defaultcfg->pump_acc = 18; |
|
|
|
|
|
defaultcfg->pump_dec = 18; |
|
|
|
|
|
defaultcfg->pump_vstart = 200; |
|
|
|
|
|
defaultcfg->pump_vstop = 300; |
|
|
|
|
|
defaultcfg->aspirate_pump_vel = 500; //
|
|
|
|
|
|
defaultcfg->distribu_pump_vel = 1000; //
|
|
|
|
|
|
defaultcfg->pump_vmax = 1000; // 1000已经是最大速度
|
|
|
|
|
|
defaultcfg->lld_pump_vel = 30; // lld推荐使用速度为50->200,这里
|
|
|
|
|
|
defaultcfg->lld_motor_vel_rpm = 80; |
|
|
|
|
|
defaultcfg->lld_detect_period_ms = 1; // 100ms
|
|
|
|
|
|
defaultcfg->lld_prepare_pos = PIPETTE_PREPARE_POS; |
|
|
|
|
|
defaultcfg->lld_prepare_pre_distribut_ul = LLD_PREPARE_DISTRIBUT_POS; |
|
|
|
|
|
|
|
|
// defaultcfg->pump_acc = 18;
|
|
|
|
|
|
// defaultcfg->pump_dec = 18;
|
|
|
|
|
|
// defaultcfg->pump_vstart = 200;
|
|
|
|
|
|
// defaultcfg->pump_vstop = 300;
|
|
|
|
|
|
// defaultcfg->aspirate_pump_vel = 500; //
|
|
|
|
|
|
// defaultcfg->distribu_pump_vel = 1000; //
|
|
|
|
|
|
// defaultcfg->pump_vmax = 8000; // 8000已经是最大速度
|
|
|
|
|
|
// defaultcfg->lld_pump_vel = 30; // lld推荐使用速度为50->200,这里
|
|
|
|
|
|
// defaultcfg->lld_motor_vel_rpm = 80;
|
|
|
|
|
|
// defaultcfg->lld_detect_period_ms = 1; // 100ms
|
|
|
|
|
|
// defaultcfg->lld_prepare_pos = PIPETTE_PREPARE_POS;
|
|
|
|
|
|
// defaultcfg->lld_prepare_pre_distribut_ul = LLD_PREPARE_DISTRIBUT_POS;
|
|
|
|
|
|
|
|
|
defaultcfg->zm_one_circle_pulse = 10000; |
|
|
defaultcfg->zm_one_circle_pulse = 10000; |
|
|
defaultcfg->zm_one_circle_pulse_denominator = 1; |
|
|
defaultcfg->zm_one_circle_pulse_denominator = 1; |
|
@ -101,9 +103,9 @@ int32_t PipetteModuleV2::module_stop() { |
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
int32_t PipetteModuleV2::module_active_cfg() { |
|
|
int32_t PipetteModuleV2::module_active_cfg() { |
|
|
m_smtp2.pump_set_acc_and_dec(m_cfg.pump_acc, m_cfg.pump_dec); |
|
|
|
|
|
m_smtp2.pump_set_vstart(m_cfg.pump_vstart); |
|
|
|
|
|
m_smtp2.pump_set_vstop(m_cfg.pump_vstop); |
|
|
|
|
|
|
|
|
// m_smtp2.pump_set_acc_and_dec(m_cfg.pump_acc, m_cfg.pump_dec);
|
|
|
|
|
|
// m_smtp2.pump_set_vstart(m_cfg.pump_vstart);
|
|
|
|
|
|
// m_smtp2.pump_set_vstop(m_cfg.pump_vstop);
|
|
|
|
|
|
|
|
|
m_zm->enable(false); |
|
|
m_zm->enable(false); |
|
|
m_zm->setIHOLD_IRUN(m_cfg.zm_ihold, m_cfg.zm_irun, m_cfg.zm_iholddelay); |
|
|
m_zm->setIHOLD_IRUN(m_cfg.zm_ihold, m_cfg.zm_irun, m_cfg.zm_iholddelay); |
|
@ -155,21 +157,6 @@ int32_t PipetteModuleV2::module_xxx_reg_impl(int32_t param_id, bool read, int32_ |
|
|
/***********************************************************************************************************************
|
|
|
/***********************************************************************************************************************
|
|
|
* CFG * |
|
|
* 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(lld_enable_record_data); |
|
|
|
|
|
XXX_CFG_REG(distribu_pump_vel); |
|
|
|
|
|
|
|
|
|
|
|
XXX_CFG_REG(zm_shaft); |
|
|
XXX_CFG_REG(zm_shaft); |
|
|
XXX_CFG_REG(zm_one_circle_pulse); |
|
|
XXX_CFG_REG(zm_one_circle_pulse); |
|
|
XXX_CFG_REG(zm_one_circle_pulse_denominator); |
|
|
XXX_CFG_REG(zm_one_circle_pulse_denominator); |
|
@ -312,20 +299,84 @@ int32_t PipetteModuleV2::pipette_zmotor_move_to_zero_point_quick() { |
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/***********************************************************************************************************************
|
|
|
|
|
|
* PUMP * |
|
|
|
|
|
***********************************************************************************************************************/ |
|
|
|
|
|
int32_t PipetteModuleV2::liquid_operation_clear_params() { |
|
|
|
|
|
memset(&liquid_operation_runparam, 0, sizeof(liquid_operation_runparam)); |
|
|
|
|
|
return 0; |
|
|
|
|
|
} |
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 设置泵机液体操作-枪运动参数 |
|
|
|
|
|
* |
|
|
|
|
|
* @param acc 1->20 deafault 14 datasheet:page-29 |
|
|
|
|
|
* @param dec 1->20 deafault 14 datasheet:page-29 |
|
|
|
|
|
* @param vstart 0->1000 default 0 |
|
|
|
|
|
* @param vstop 0->1000 default 900 |
|
|
|
|
|
* @param vmax 0->8000 default 1400 |
|
|
|
|
|
* @return int32_t |
|
|
|
|
|
*/ |
|
|
|
|
|
int32_t PipetteModuleV2::liquid_operation_set_gun_runparams(int32_t acc, int32_t dec, int32_t vstart, int32_t vstop, int32_t vmax) { |
|
|
|
|
|
liquid_operation_runparam.pump_acc = acc; |
|
|
|
|
|
liquid_operation_runparam.pump_dec = dec; |
|
|
|
|
|
liquid_operation_runparam.pump_vstart = vstart; |
|
|
|
|
|
liquid_operation_runparam.pump_vstop = vstop; |
|
|
|
|
|
liquid_operation_runparam.pump_vmax = vmax; |
|
|
|
|
|
return 0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 设置泵机液体操作-枪运动参数 |
|
|
|
|
|
* |
|
|
|
|
|
* @param posmin z轴运动范围最小值 |
|
|
|
|
|
* @param posmax z轴运动范围最大值 |
|
|
|
|
|
* @param vmax z轴运动最大速度 |
|
|
|
|
|
* @return int32_t |
|
|
|
|
|
*/ |
|
|
|
|
|
int32_t PipetteModuleV2::liquid_operation_set_zmotor_runparams(int32_t posmin, int32_t posmax, int32_t vmax) { |
|
|
|
|
|
liquid_operation_runparam.zmotor_posmin = posmin; |
|
|
|
|
|
liquid_operation_runparam.zmotor_posmax = posmax; |
|
|
|
|
|
liquid_operation_runparam.zmotor_vmax = vmax; |
|
|
|
|
|
return 0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int32_t PipetteModuleV2::liquid_operation_enable_lld_record() { |
|
|
|
|
|
liquid_operation_runparam.lld_enable_record_data = 1; |
|
|
|
|
|
return 0; |
|
|
|
|
|
} |
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 刷新液体操作参数 |
|
|
|
|
|
* |
|
|
|
|
|
* @return int32_t |
|
|
|
|
|
*/ |
|
|
|
|
|
int32_t PipetteModuleV2::liquid_operation_fresh_params() { |
|
|
|
|
|
ZLOGI(TAG, "liquid_operation_runparam:"); |
|
|
|
|
|
ZLOGI(TAG, "pump_acc :%d", liquid_operation_runparam.pump_acc); |
|
|
|
|
|
ZLOGI(TAG, "pump_dec :%d", liquid_operation_runparam.pump_dec); |
|
|
|
|
|
ZLOGI(TAG, "pump_vstart :%d", liquid_operation_runparam.pump_vstart); |
|
|
|
|
|
ZLOGI(TAG, "pump_vstop :%d", liquid_operation_runparam.pump_vstop); |
|
|
|
|
|
ZLOGI(TAG, "pump_vmax :%d", liquid_operation_runparam.pump_vmax); |
|
|
|
|
|
ZLOGI(TAG, "zmotor_posmin :%d", liquid_operation_runparam.zmotor_posmin); |
|
|
|
|
|
ZLOGI(TAG, "zmotor_posmax :%d", liquid_operation_runparam.zmotor_posmax); |
|
|
|
|
|
ZLOGI(TAG, "zmotor_vmax :%d", liquid_operation_runparam.zmotor_vmax); |
|
|
|
|
|
ZLOGI(TAG, "lld_enable_record_data :%d", liquid_operation_runparam.lld_enable_record_data); |
|
|
|
|
|
|
|
|
|
|
|
DO(m_smtp2.pump_set_acc_and_dec(liquid_operation_runparam.pump_acc, liquid_operation_runparam.pump_dec)); |
|
|
|
|
|
DO(m_smtp2.pump_set_vstart(liquid_operation_runparam.pump_vstart)); |
|
|
|
|
|
DO(m_smtp2.pump_set_vstop(liquid_operation_runparam.pump_vstop)); |
|
|
|
|
|
DO(m_smtp2.pump_set_io1_mode(0)); // lld输入高
|
|
|
|
|
|
DO(m_smtp2.pump_set_io2_mode(0)); // 通用输入
|
|
|
|
|
|
DO(m_smtp2.pump_set_tip_size(1)); // 250ul
|
|
|
|
|
|
DO(m_smtp2.pump_enable_temp_compensation(0)); // 关闭温度补偿
|
|
|
|
|
|
DO(m_smtp2.write_cmd("/1K0R\r")); // 设置背隙为0
|
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
int32_t PipetteModuleV2::pipette_init_device() { |
|
|
int32_t PipetteModuleV2::pipette_init_device() { |
|
|
THREAD_START_WORK([this]() { |
|
|
THREAD_START_WORK([this]() { |
|
|
DO_IN_THREAD(m_smtp2.pump_init(m_cfg.pump_vmax)); |
|
|
|
|
|
|
|
|
DO_IN_THREAD(m_smtp2.pump_init(liquid_operation_runparam.pump_vmax)); |
|
|
pump_waitfor_stop(); |
|
|
pump_waitfor_stop(); |
|
|
|
|
|
|
|
|
DO_IN_THREAD(m_smtp2.pump_set_io1_mode(0)); // lld输入高
|
|
|
|
|
|
DO_IN_THREAD(m_smtp2.pump_set_io2_mode(0)); // 通用输入
|
|
|
|
|
|
DO_IN_THREAD(m_smtp2.pump_set_tip_size(1)); // 250ul
|
|
|
|
|
|
DO_IN_THREAD(m_smtp2.pump_enable_temp_compensation(0)); // 温度补偿
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
// m_state.load_val_ul = 0;
|
|
|
|
|
|
// m_state.lld_prepared = 0;
|
|
|
|
|
|
m_state.pipette_is_inited = 1; |
|
|
|
|
|
}); |
|
|
}); |
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
@ -333,14 +384,14 @@ int32_t PipetteModuleV2::pipette_init_device() { |
|
|
int32_t PipetteModuleV2::pipette_put_tip() { |
|
|
int32_t PipetteModuleV2::pipette_put_tip() { |
|
|
THREAD_START_WORK([this]() { |
|
|
THREAD_START_WORK([this]() { |
|
|
DO_IN_THREAD(m_smtp2.pump_put_tip()); |
|
|
DO_IN_THREAD(m_smtp2.pump_put_tip()); |
|
|
// m_state.lld_prepared = 0;
|
|
|
|
|
|
pump_waitfor_stop(); |
|
|
pump_waitfor_stop(); |
|
|
}); |
|
|
}); |
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
int32_t PipetteModuleV2::pipette_pump_move_to(int32_t pumpv, int32_t nl) { |
|
|
|
|
|
THREAD_START_WORK([this, pumpv, nl]() { |
|
|
|
|
|
|
|
|
int32_t PipetteModuleV2::pipette_pump_move_to(int32_t nl) { |
|
|
|
|
|
THREAD_START_WORK([this, nl]() { |
|
|
|
|
|
int32_t pumpv = liquid_operation_runparam.pump_vmax; |
|
|
DO_IN_THREAD(m_smtp2.pump_move_to_nl(pumpv, nl)); |
|
|
DO_IN_THREAD(m_smtp2.pump_move_to_nl(pumpv, nl)); |
|
|
pump_waitfor_stop(); |
|
|
pump_waitfor_stop(); |
|
|
m_smtp2.pump_stop(); |
|
|
m_smtp2.pump_stop(); |
|
@ -348,7 +399,7 @@ int32_t PipetteModuleV2::pipette_pump_move_to(int32_t pumpv, int32_t nl) { |
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
int32_t PipetteModuleV2::pipette_lld(int32_t lldtype, int32_t maxzpos, int32_t c_threshold, int32_t p_threshold) { |
|
|
|
|
|
|
|
|
int32_t PipetteModuleV2::pipette_lld(int32_t lldtype, int32_t c_threshold, int32_t p_threshold) { |
|
|
// 检查泵机是否初始化过
|
|
|
// 检查泵机是否初始化过
|
|
|
if (lldtype < 0 || lldtype > klldtypemax) { |
|
|
if (lldtype < 0 || lldtype > klldtypemax) { |
|
|
return err::kparam_out_of_range; |
|
|
return err::kparam_out_of_range; |
|
@ -364,17 +415,12 @@ int32_t PipetteModuleV2::pipette_lld(int32_t lldtype, int32_t maxzpos, int32_t c |
|
|
return err::kpipette_error_no_tip_when_lld; |
|
|
return err::kpipette_error_no_tip_when_lld; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
int32_t recorddata = m_cfg.lld_enable_record_data; |
|
|
|
|
|
THREAD_START_WORK([this, recorddata, lldtype, maxzpos, c_threshold, p_threshold]() { //
|
|
|
|
|
|
int32_t start_capacitance = 0; // 启动时电容数值
|
|
|
|
|
|
int32_t start_pressure = 0; // 启动时压力数值
|
|
|
|
|
|
int32_t start_motor_pos = 0; // 启动时电机位置
|
|
|
|
|
|
|
|
|
int32_t recorddata = liquid_operation_runparam.lld_enable_record_data; |
|
|
|
|
|
thread_start_work(__FUNCTION__, [this, recorddata, lldtype, c_threshold, p_threshold]() { //
|
|
|
|
|
|
int32_t start_capacitance = 0; // 启动时电容数值
|
|
|
|
|
|
int32_t start_pressure = 0; // 启动时压力数值
|
|
|
|
|
|
int32_t start_motor_pos = 0; // 启动时电机位置
|
|
|
|
|
|
|
|
|
// 1. 泵机移动到0位
|
|
|
|
|
|
DO_IN_THREAD(m_smtp2.pump_distribut_all(m_cfg.pump_vmax)); |
|
|
|
|
|
pump_waitfor_stop(); |
|
|
|
|
|
|
|
|
|
|
|
// 2. 读取初值
|
|
|
|
|
|
DO_IN_THREAD(m_smtp2.pump_get_capacitance(&start_capacitance)); |
|
|
DO_IN_THREAD(m_smtp2.pump_get_capacitance(&start_capacitance)); |
|
|
DO_IN_THREAD(m_smtp2.pump_get_pressure(&start_pressure)); |
|
|
DO_IN_THREAD(m_smtp2.pump_get_pressure(&start_pressure)); |
|
|
start_motor_pos = m_zm->getXACTUAL(); |
|
|
start_motor_pos = m_zm->getXACTUAL(); |
|
@ -383,10 +429,10 @@ int32_t PipetteModuleV2::pipette_lld(int32_t lldtype, int32_t maxzpos, int32_t c |
|
|
if (lldtype == kclld) { |
|
|
if (lldtype == kclld) { |
|
|
DO_IN_THREAD(m_smtp2.pump_clld(c_threshold)); |
|
|
DO_IN_THREAD(m_smtp2.pump_clld(c_threshold)); |
|
|
} else if (lldtype == kplld) { |
|
|
} else if (lldtype == kplld) { |
|
|
DO_IN_THREAD(m_smtp2.pump_distribut_plld(m_cfg.lld_pump_vel, p_threshold)); |
|
|
|
|
|
|
|
|
DO_IN_THREAD(m_smtp2.pump_aspirate_plld(liquid_operation_runparam.pump_vmax, p_threshold)); |
|
|
} |
|
|
} |
|
|
osDelay(110); |
|
|
osDelay(110); |
|
|
zm_move_to(maxzpos, m_cfg.lld_motor_vel_rpm); |
|
|
|
|
|
|
|
|
zm_move_to(liquid_operation_runparam.zmotor_posmax, liquid_operation_runparam.zmotor_vmax); |
|
|
|
|
|
|
|
|
while (true) { |
|
|
while (true) { |
|
|
bool motorstoped = false; |
|
|
bool motorstoped = false; |
|
@ -408,7 +454,7 @@ int32_t PipetteModuleV2::pipette_lld(int32_t lldtype, int32_t maxzpos, int32_t c |
|
|
if (lldtype == kclld) { |
|
|
if (lldtype == kclld) { |
|
|
DO_IN_THREAD(m_smtp2.pump_clld_get_state(&detect_liquid)); |
|
|
DO_IN_THREAD(m_smtp2.pump_clld_get_state(&detect_liquid)); |
|
|
} else if (lldtype == kplld) { |
|
|
} else if (lldtype == kplld) { |
|
|
DO_IN_THREAD(m_smtp2.pump_distribut_plld_get_state(&detect_liquid)); |
|
|
|
|
|
|
|
|
DO_IN_THREAD(m_smtp2.pump_aspirate_plld_get_state(&detect_liquid)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 探测到液面
|
|
|
// 探测到液面
|
|
@ -429,7 +475,7 @@ int32_t PipetteModuleV2::pipette_lld(int32_t lldtype, int32_t maxzpos, int32_t c |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (recorddata) push_snesor_sample_data(motorpos, capacitance, pressure); |
|
|
if (recorddata) push_snesor_sample_data(motorpos, capacitance, pressure); |
|
|
m_thread.sleep(m_cfg.lld_detect_period_ms); |
|
|
|
|
|
|
|
|
m_thread.sleep(2); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
}); |
|
|
}); |
|
@ -441,14 +487,18 @@ int32_t PipetteModuleV2::pipette_lld_is_detect_liquid(int32_t *detect) { |
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
int32_t PipetteModuleV2::pipette_aspirate(int32_t llfrpm, int32_t llftpos, int32_t pumpv, int32_t nl) { |
|
|
|
|
|
|
|
|
int32_t PipetteModuleV2::pipette_aspirate(int32_t nl) { |
|
|
// pipette_aspirate
|
|
|
// pipette_aspirate
|
|
|
if (nl < 0) { |
|
|
if (nl < 0) { |
|
|
ZLOGE(TAG, "pipette_aspirate %d fail , ul < 0", nl); |
|
|
ZLOGE(TAG, "pipette_aspirate %d fail , ul < 0", nl); |
|
|
return err::kparam_out_of_range; |
|
|
return err::kparam_out_of_range; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
THREAD_START_WORK([this, llfrpm, llftpos, pumpv, nl]() { |
|
|
|
|
|
|
|
|
THREAD_START_WORK([this, nl]() { |
|
|
|
|
|
int32_t llfrpm = liquid_operation_runparam.zmotor_vmax; |
|
|
|
|
|
int32_t llftpos = liquid_operation_runparam.zmotor_posmax; |
|
|
|
|
|
int32_t pumpv = liquid_operation_runparam.pump_vmax; |
|
|
|
|
|
|
|
|
DO_IN_THREAD(m_smtp2.pump_aspirate_nl(pumpv, nl)); |
|
|
DO_IN_THREAD(m_smtp2.pump_aspirate_nl(pumpv, nl)); |
|
|
|
|
|
|
|
|
if (llfrpm != 0) zm_move_to(llftpos, llfrpm); |
|
|
if (llfrpm != 0) zm_move_to(llftpos, llfrpm); |
|
@ -460,17 +510,20 @@ int32_t PipetteModuleV2::pipette_aspirate(int32_t llfrpm, int32_t llftpos, int32 |
|
|
}); |
|
|
}); |
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
int32_t PipetteModuleV2::pipette_distribu(int32_t llfrpm, int32_t pumpv, int32_t nl) { |
|
|
|
|
|
|
|
|
int32_t PipetteModuleV2::pipette_distribu(int32_t nl) { |
|
|
// pipette_aspirate
|
|
|
// pipette_aspirate
|
|
|
if (nl < 0) { |
|
|
if (nl < 0) { |
|
|
ZLOGE(TAG, "pipette_distribu %d fail , nl < 0", nl); |
|
|
ZLOGE(TAG, "pipette_distribu %d fail , nl < 0", nl); |
|
|
return err::kparam_out_of_range; |
|
|
return err::kparam_out_of_range; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
THREAD_START_WORK([this, llfrpm, pumpv, nl]() { |
|
|
|
|
|
|
|
|
THREAD_START_WORK([this, nl]() { |
|
|
|
|
|
int32_t llfrpm = liquid_operation_runparam.zmotor_vmax; |
|
|
|
|
|
int32_t pumpv = liquid_operation_runparam.pump_vmax; |
|
|
|
|
|
|
|
|
DO_IN_THREAD(m_smtp2.pump_aspirate_nl(pumpv, -nl)); |
|
|
DO_IN_THREAD(m_smtp2.pump_aspirate_nl(pumpv, -nl)); |
|
|
|
|
|
|
|
|
if (llfrpm != 0) zm_move_to(0, llfrpm); |
|
|
|
|
|
|
|
|
if (llfrpm != 0) zm_move_to(liquid_operation_runparam.zmotor_posmin, llfrpm); |
|
|
|
|
|
|
|
|
pump_waitfor_stop(); |
|
|
pump_waitfor_stop(); |
|
|
|
|
|
|
|
@ -479,14 +532,18 @@ int32_t PipetteModuleV2::pipette_distribu(int32_t llfrpm, int32_t pumpv, int32_t |
|
|
}); |
|
|
}); |
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
int32_t PipetteModuleV2::pipette_shake_up(int32_t llfrpm, int32_t maxzpos, int32_t pumpv, int32_t nl, int32_t times) { |
|
|
|
|
|
THREAD_START_WORK([this, llfrpm, maxzpos, pumpv, nl, times]() { |
|
|
|
|
|
|
|
|
int32_t PipetteModuleV2::pipette_shake_up(int32_t nl, int32_t times) { |
|
|
|
|
|
thread_start_work(__FUNCTION__, [this, nl, times]() { |
|
|
//
|
|
|
//
|
|
|
int32_t dpos = 0; |
|
|
int32_t dpos = 0; |
|
|
|
|
|
|
|
|
int32_t startpos = m_zm->getXACTUAL(); |
|
|
int32_t startpos = m_zm->getXACTUAL(); |
|
|
int32_t endpos = 0; |
|
|
int32_t endpos = 0; |
|
|
|
|
|
|
|
|
|
|
|
int32_t llfrpm = liquid_operation_runparam.zmotor_vmax; |
|
|
|
|
|
int32_t maxzpos = liquid_operation_runparam.zmotor_posmax; |
|
|
|
|
|
int32_t pumpv = liquid_operation_runparam.pump_vmax; |
|
|
|
|
|
|
|
|
if (llfrpm != 0) zm_move_to(maxzpos, llfrpm); |
|
|
if (llfrpm != 0) zm_move_to(maxzpos, llfrpm); |
|
|
|
|
|
|
|
|
DO_IN_THREAD(m_smtp2.pump_aspirate_nl(pumpv, nl)); |
|
|
DO_IN_THREAD(m_smtp2.pump_aspirate_nl(pumpv, nl)); |
|
@ -521,16 +578,8 @@ int32_t PipetteModuleV2::pipette_shake_up(int32_t llfrpm, int32_t maxzpos, int32 |
|
|
int32_t PipetteModuleV2::pipette_clear_hanging_liquid(int32_t repeat_times) { |
|
|
int32_t PipetteModuleV2::pipette_clear_hanging_liquid(int32_t repeat_times) { |
|
|
// llf_startz
|
|
|
// llf_startz
|
|
|
// llf_endz
|
|
|
// llf_endz
|
|
|
THREAD_START_WORK([this, repeat_times]() { |
|
|
|
|
|
for (int i = 0; i < repeat_times; i++) { |
|
|
|
|
|
m_smtp2.pump_move_to_nl(m_cfg.pump_vmax, 0); |
|
|
|
|
|
pump_waitfor_stop(); |
|
|
|
|
|
|
|
|
thread_start_work(__FUNCTION__, [this, repeat_times]() { |
|
|
|
|
|
|
|
|
m_smtp2.pump_move_to_nl(m_cfg.pump_vmax, 100 * 1000); |
|
|
|
|
|
pump_waitfor_stop(); |
|
|
|
|
|
} |
|
|
|
|
|
m_smtp2.pump_move_to_nl(m_cfg.pump_vmax, 0); |
|
|
|
|
|
pump_waitfor_stop(); |
|
|
|
|
|
}); |
|
|
}); |
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
@ -591,104 +640,6 @@ void PipetteModuleV2::do_pipette_zmotor_move_to_zero_point_quick() { |
|
|
throw zapp_exception(err::kstep_motor_lost_step); |
|
|
throw zapp_exception(err::kstep_motor_lost_step); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
#if 0
|
|
|
|
|
|
int32_t PipetteModuleV2::do_pipette_lld(bool recorddata, int32_t lldtype, int32_t startpos, int32_t zdpos, int32_t c_threshold, int32_t p_threshold) { |
|
|
|
|
|
// 检查泵机是否初始化过
|
|
|
|
|
|
|
|
|
|
|
|
if (lldtype < 0 || lldtype > klldtypemax) { |
|
|
|
|
|
return err::kparam_out_of_range; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
THREAD_START_WORK([this, recorddata, lldtype, startpos, zdpos, c_threshold, p_threshold]() { //
|
|
|
|
|
|
m_state.lld_prepared = 0; // 失效m_state.lld_prepared
|
|
|
|
|
|
|
|
|
|
|
|
int32_t start_capacitance = 0; // 启动时电容数值
|
|
|
|
|
|
int32_t start_pressure = 0; // 启动时压力数值
|
|
|
|
|
|
int32_t start_motor_pos = 0; // 启动时电机位置
|
|
|
|
|
|
|
|
|
|
|
|
// 准备
|
|
|
|
|
|
capturedata_num = 0; |
|
|
|
|
|
|
|
|
|
|
|
// 读取初值
|
|
|
|
|
|
DO_IN_THREAD(m_smtp2.pump_get_capacitance(&start_capacitance)); |
|
|
|
|
|
DO_IN_THREAD(m_smtp2.pump_get_pressure(&start_pressure)); |
|
|
|
|
|
start_motor_pos = m_zm->getXACTUAL(); |
|
|
|
|
|
|
|
|
|
|
|
// 先分配一点体积,消除一些误差。
|
|
|
|
|
|
ZLOGI(TAG, "start lld before distribut %d ul", m_cfg.lld_prepare_pre_distribut_ul); |
|
|
|
|
|
DO_IN_THREAD(m_smtp2.pump_aspirate(m_cfg.pump_vmax, -m_cfg.lld_prepare_pre_distribut_ul)); |
|
|
|
|
|
pump_waitfor_stop(); |
|
|
|
|
|
ZLOGI(TAG, "lld before distribut ok"); |
|
|
|
|
|
|
|
|
|
|
|
ZLOGI(TAG, "start lld"); |
|
|
|
|
|
|
|
|
|
|
|
bool moveToStartPos = false; |
|
|
|
|
|
|
|
|
|
|
|
zm_move_to(startpos, m_cfg.zm_default_velocity); |
|
|
|
|
|
osDelay(10); |
|
|
|
|
|
if (lldtype == kclld) { |
|
|
|
|
|
DO_IN_THREAD(m_smtp2.pump_clld(c_threshold)); |
|
|
|
|
|
} else if (lldtype == kplld) { |
|
|
|
|
|
DO_IN_THREAD(m_smtp2.pump_distribut_plld(m_cfg.lld_pump_vel, p_threshold)); |
|
|
|
|
|
} else if (lldtype == kmixlld) { |
|
|
|
|
|
DO_IN_THREAD(m_smtp2.pump_distribut_mlld(m_cfg.lld_pump_vel, c_threshold, p_threshold)); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
while (true) { |
|
|
|
|
|
bool motorstoped = false; |
|
|
|
|
|
int32_t motorerror = 0; |
|
|
|
|
|
|
|
|
|
|
|
int32_t motorpos = 0; |
|
|
|
|
|
int32_t capacitance = 0; |
|
|
|
|
|
int32_t pressure = 0; |
|
|
|
|
|
|
|
|
|
|
|
// 获取状态
|
|
|
|
|
|
if (recorddata) { |
|
|
|
|
|
DO_IN_THREAD(m_smtp2.pump_get_capacitance(&capacitance)); |
|
|
|
|
|
DO_IN_THREAD(m_smtp2.pump_get_pressure(&pressure)); |
|
|
|
|
|
motorpos = m_zm->getXACTUAL() - start_motor_pos; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 液面探测检测
|
|
|
|
|
|
int32_t detect_liquid = 0; |
|
|
|
|
|
if (lldtype == kclld) { |
|
|
|
|
|
DO_IN_THREAD(m_smtp2.pump_clld_get_state(&detect_liquid)); |
|
|
|
|
|
} else if (lldtype == kplld) { |
|
|
|
|
|
DO_IN_THREAD(m_smtp2.pump_distribut_plld_get_state(&detect_liquid)); |
|
|
|
|
|
} else if (lldtype == kmixlld) { |
|
|
|
|
|
DO_IN_THREAD(m_smtp2.pump_distribut_mlld_get_state(&detect_liquid)); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 探测到液面
|
|
|
|
|
|
if (detect_liquid == 1) { |
|
|
|
|
|
ZLOGI(TAG, "detect liquid"); |
|
|
|
|
|
m_state.detected_liquid = 1; |
|
|
|
|
|
if (recorddata) push_snesor_sample_data(motorpos, capacitance, pressure); |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 电机停了也没有探测到液面
|
|
|
|
|
|
if (m_zm->isStoped()) { |
|
|
|
|
|
if (!moveToStartPos) { |
|
|
|
|
|
zm_move_by(zdpos, m_cfg.lld_motor_vel_rpm); |
|
|
|
|
|
moveToStartPos = true; |
|
|
|
|
|
} else { |
|
|
|
|
|
ZLOGI(TAG, "motorstoped,but not detect liquid"); |
|
|
|
|
|
creg.module_errorcode = 0; |
|
|
|
|
|
m_state.detected_liquid = 0; |
|
|
|
|
|
if (recorddata) push_snesor_sample_data(motorpos, capacitance, pressure); |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (recorddata) push_snesor_sample_data(motorpos, capacitance, pressure); |
|
|
|
|
|
m_thread.sleep(m_cfg.lld_detect_period_ms); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
}); |
|
|
|
|
|
return 0; |
|
|
|
|
|
} |
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
int32_t PipetteModuleV2::pipette_zmotor_read_zero_point_state(int32_t *state) { |
|
|
int32_t PipetteModuleV2::pipette_zmotor_read_zero_point_state(int32_t *state) { |
|
|
*state = zm0p_is_trigger(); |
|
|
*state = zm0p_is_trigger(); |
|
|