|
|
@ -24,7 +24,7 @@ using namespace iflytop; |
|
|
|
} \ |
|
|
|
} |
|
|
|
|
|
|
|
#define PIPETTE_PREPARE_POS 500
|
|
|
|
#define PIPETTE_PREPARE_POS 800
|
|
|
|
|
|
|
|
void PipetteModule::initialize(int32_t id, config_t *config, StepMotorCtrlModule *zmotor, hardward_config_t *hardwaredcfg) { //
|
|
|
|
ZASSERT(config != nullptr); |
|
|
@ -44,6 +44,8 @@ void PipetteModule::initialize(int32_t id, config_t *config, StepMotorCtrlModule |
|
|
|
m_config.lld_pump_vel = 100; // lld推荐使用速度为50->200,这里
|
|
|
|
m_config.lld_motor_vel_rpm = 50; |
|
|
|
m_config.lld_detect_period_ms = 100; // 100ms
|
|
|
|
m_config.lld_prepare_pos = PIPETTE_PREPARE_POS; |
|
|
|
m_config.lld_prepare_distribut_pos = 100; |
|
|
|
|
|
|
|
ZASSERT(zmotor); |
|
|
|
m_zmotor = zmotor; |
|
|
@ -76,6 +78,8 @@ int32_t PipetteModule::module_xxx_reg(int32_t param_id, bool read, int32_t &val) |
|
|
|
PROCESS_REG_CFG(kreg_pipette_lld_pump_vel, lld_pump_vel); |
|
|
|
PROCESS_REG_CFG(kreg_pipette_lld_motor_vel_rpm, lld_motor_vel_rpm); |
|
|
|
PROCESS_REG_CFG(kreg_pipette_lld_detect_period_ms, lld_detect_period_ms); |
|
|
|
PROCESS_REG_CFG(kreg_pipette_lld_prepare_pos, lld_prepare_pos); |
|
|
|
PROCESS_REG_CFG(kreg_pipette_lld_prepare_distribut_pos, lld_prepare_distribut_pos); |
|
|
|
|
|
|
|
default: |
|
|
|
return err::kmodule_not_find_reg; |
|
|
@ -165,11 +169,18 @@ int32_t PipetteModule::pipette_lld_is_detect_liquid(int32_t *detect_liquid) { / |
|
|
|
***********************************************************************************************************************/ |
|
|
|
int32_t PipetteModule::do_pipette_ctrl_init_device() { |
|
|
|
creg.module_status = 1; |
|
|
|
|
|
|
|
// 检查tip头状态
|
|
|
|
int32_t tipstate = 0; |
|
|
|
int32_t ret = m_smtp2.pump_get_tip_state(&tipstate); |
|
|
|
if (ret != 0) return ret; |
|
|
|
if (tipstate != 0) return err::kpipette_error_tipisload_when_lld_prepare; |
|
|
|
|
|
|
|
m_thread.stop(); |
|
|
|
m_thread.start( |
|
|
|
[this]() { //
|
|
|
|
DO_IN_THREAD(befor_run()); |
|
|
|
DO_IN_THREAD(m_smtp2.pump_init()); |
|
|
|
DO_IN_THREAD(m_smtp2.pump_init(m_config.pump_vmax)); |
|
|
|
while (true) { |
|
|
|
if (!check_when_run()) break; |
|
|
|
if (m_thread.getExitFlag()) break; |
|
|
@ -182,13 +193,15 @@ int32_t PipetteModule::do_pipette_ctrl_init_device() { |
|
|
|
} |
|
|
|
}, |
|
|
|
[this]() { // exit fn
|
|
|
|
ZLOGI(TAG, "do_pipette_ctrl_put_tip finish"); |
|
|
|
after_run(); |
|
|
|
|
|
|
|
m_state.load_val_ul = 0; |
|
|
|
m_state.aspirated = 0; |
|
|
|
m_state.lld_prepared = 0; |
|
|
|
m_state.pipette_is_inited = 1; |
|
|
|
if (creg.module_errorcode == 0) { |
|
|
|
m_state.load_val_ul = 0; |
|
|
|
m_state.aspirated = 0; |
|
|
|
m_state.lld_prepared = 0; |
|
|
|
m_state.pipette_is_inited = 1; |
|
|
|
} |
|
|
|
ZLOGI(TAG, "do_pipette_ctrl_put_tip finish,ecode:%d", creg.module_errorcode); |
|
|
|
|
|
|
|
} //
|
|
|
|
); |
|
|
@ -206,7 +219,18 @@ int32_t PipetteModule::do_pipette_ctrl_put_tip() { |
|
|
|
if (m_thread.getExitFlag()) break; |
|
|
|
|
|
|
|
int32_t isbusy = 0; |
|
|
|
DO_IN_THREAD(m_smtp2.pump_get_state(&isbusy)); |
|
|
|
|
|
|
|
int32_t ecode = m_smtp2.pump_get_state(&isbusy); |
|
|
|
if (ecode != 0) { |
|
|
|
if (ecode == err::kpipette_error_TipDrop || ecode == err::kpipette_error_TipPopError) { |
|
|
|
break; |
|
|
|
} else { |
|
|
|
ZLOGE(TAG, "do do_pipette_ctrl_put_tip fail, error %s(%d)", err::error2str(ecode), ecode); |
|
|
|
creg.module_errorcode = ecode; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (isbusy == 0) break; |
|
|
|
|
|
|
|
m_thread.sleep(10); |
|
|
@ -214,10 +238,13 @@ int32_t PipetteModule::do_pipette_ctrl_put_tip() { |
|
|
|
|
|
|
|
}, |
|
|
|
[this]() { // exit fn
|
|
|
|
ZLOGI(TAG, "do_pipette_ctrl_put_tip finish"); |
|
|
|
after_run(); |
|
|
|
m_state.load_val_ul = 0; |
|
|
|
m_state.aspirated = 0; |
|
|
|
if (creg.module_errorcode == 0) { |
|
|
|
m_state.load_val_ul = 0; |
|
|
|
m_state.aspirated = 0; |
|
|
|
} |
|
|
|
ZLOGI(TAG, "do_pipette_ctrl_put_tip finish,ecode:%d", creg.module_errorcode); |
|
|
|
|
|
|
|
} //
|
|
|
|
); |
|
|
|
return 0; |
|
|
@ -228,7 +255,7 @@ int32_t PipetteModule::do_pipette_ctrl_move_to_ul(int32_t ul) { |
|
|
|
m_thread.start( |
|
|
|
[this, ul]() { //
|
|
|
|
DO_IN_THREAD(befor_run()); |
|
|
|
DO_IN_THREAD(m_smtp2.pump_move_to_ul(ul)); |
|
|
|
DO_IN_THREAD(m_smtp2.pump_move_to_ul(m_config.pump_vmax, ul)); |
|
|
|
while (true) { |
|
|
|
if (!check_when_run()) break; |
|
|
|
if (m_thread.getExitFlag()) break; |
|
|
@ -241,8 +268,8 @@ int32_t PipetteModule::do_pipette_ctrl_move_to_ul(int32_t ul) { |
|
|
|
} |
|
|
|
}, |
|
|
|
[this]() { // exit fn
|
|
|
|
ZLOGI(TAG, "do_pipette_ctrl_move_to_ul finish"); |
|
|
|
after_run(); |
|
|
|
ZLOGI(TAG, "do_pipette_ctrl_move_to_ul finish,ecode:%d", creg.module_errorcode); |
|
|
|
} //
|
|
|
|
); |
|
|
|
return 0; |
|
|
@ -278,7 +305,7 @@ int32_t PipetteModule::do_pipette_lld_prepare() { |
|
|
|
m_thread.start( |
|
|
|
[this]() { //
|
|
|
|
DO_IN_THREAD(befor_run()); |
|
|
|
DO_IN_THREAD(m_smtp2.pump_move_to_ul(PIPETTE_PREPARE_POS)); // 移动到中点
|
|
|
|
DO_IN_THREAD(m_smtp2.pump_move_to_ul(m_config.pump_vmax, PIPETTE_PREPARE_POS)); // 移动到中点
|
|
|
|
|
|
|
|
while (true) { |
|
|
|
if (!check_when_run()) break; |
|
|
@ -292,13 +319,12 @@ int32_t PipetteModule::do_pipette_lld_prepare() { |
|
|
|
} |
|
|
|
}, |
|
|
|
[this]() { // exit fn
|
|
|
|
ZLOGI(TAG, "do_pipette_lld_prepare finish"); |
|
|
|
after_run(); |
|
|
|
if (creg.module_errorcode != 0) { |
|
|
|
m_state.pipette_is_inited = 1; |
|
|
|
m_state.load_val_ul = 0; |
|
|
|
m_state.aspirated = 0; |
|
|
|
if (creg.module_errorcode == 0) { |
|
|
|
m_state.lld_prepared = 1; |
|
|
|
} |
|
|
|
ZLOGI(TAG, "do_pipette_lld_prepare finish,ecode:%d", creg.module_errorcode); |
|
|
|
|
|
|
|
} //
|
|
|
|
); |
|
|
|
return 0; |
|
|
@ -320,6 +346,7 @@ int32_t PipetteModule::do_pipette_lld(lld_mode_t mode, int32_t zdpos, int32_t c_ |
|
|
|
*/ |
|
|
|
|
|
|
|
if (m_state.lld_prepared == 0) { |
|
|
|
ZLOGI(TAG, "do_pipette_lld fail, not prepare"); |
|
|
|
return err::kpipette_error_not_lld_prepare; |
|
|
|
} |
|
|
|
|
|
|
@ -347,6 +374,21 @@ int32_t PipetteModule::do_pipette_lld(lld_mode_t mode, int32_t zdpos, int32_t c_ |
|
|
|
DO_IN_THREAD(m_smtp2.pump_get_pressure(&start_pressure)); |
|
|
|
start_motor_pos = submotor->getXACTUAL(); |
|
|
|
|
|
|
|
ZLOGI(TAG, "start lld before distribut"); |
|
|
|
DO_IN_THREAD(m_smtp2.pump_distribut(m_config.pump_vmax, m_config.lld_prepare_distribut_pos)); |
|
|
|
while (true) { |
|
|
|
if (!check_when_run()) break; |
|
|
|
if (m_thread.getExitFlag()) break; |
|
|
|
|
|
|
|
int32_t isbusy = 0; |
|
|
|
DO_IN_THREAD(m_smtp2.pump_get_state(&isbusy)); |
|
|
|
if (isbusy == 0) break; |
|
|
|
} |
|
|
|
ZLOGI(TAG, "lld before distribut ok"); |
|
|
|
|
|
|
|
ZLOGI(TAG, "start lld"); |
|
|
|
submotor->moveBy(zdpos, m_config.lld_motor_vel_rpm); |
|
|
|
osDelay(50); |
|
|
|
if (mode == kclld) { |
|
|
|
DO_IN_THREAD(m_smtp2.pump_clld(c_threshold)); |
|
|
|
} else if (mode == kplld) { |
|
|
@ -354,8 +396,6 @@ int32_t PipetteModule::do_pipette_lld(lld_mode_t mode, int32_t zdpos, int32_t c_ |
|
|
|
} else if (mode == kmixlld) { |
|
|
|
DO_IN_THREAD(m_smtp2.pump_distribut_mlld(m_config.lld_pump_vel, c_threshold, p_threshold)); |
|
|
|
} |
|
|
|
osDelay(50); |
|
|
|
submotor->moveBy(zdpos, m_config.lld_motor_vel_rpm); |
|
|
|
|
|
|
|
while (true) { |
|
|
|
if (!check_when_run()) break; |
|
|
@ -385,6 +425,7 @@ int32_t PipetteModule::do_pipette_lld(lld_mode_t mode, int32_t zdpos, int32_t c_ |
|
|
|
|
|
|
|
// 探测到液面
|
|
|
|
if (detect_liquid == 1) { |
|
|
|
ZLOGI(TAG, "detect liquid"); |
|
|
|
m_state.detected_liquid = 1; |
|
|
|
submotor->stop(); |
|
|
|
push_snesor_sample_data(motorpos, capacitance, pressure); |
|
|
@ -396,19 +437,24 @@ int32_t PipetteModule::do_pipette_lld(lld_mode_t mode, int32_t zdpos, int32_t c_ |
|
|
|
if (motorerror != 0) { |
|
|
|
creg.module_errorcode = motorerror; |
|
|
|
ZLOGI(TAG, "motorerror %d", motorerror); |
|
|
|
break; |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// 电机停了也没有探测到液面
|
|
|
|
if (motorstoped) { |
|
|
|
ZLOGI(TAG, "motorstoped,but not detect liquid"); |
|
|
|
creg.module_errorcode = 0; |
|
|
|
m_state.detected_liquid = 0; |
|
|
|
push_snesor_sample_data(motorpos, capacitance, pressure); |
|
|
|
break; |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
push_snesor_sample_data(motorpos, capacitance, pressure); |
|
|
|
m_thread.sleep(m_config.lld_detect_period_ms); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}, |
|
|
|
[this]() { // exit fn
|
|
|
|
auto submotor = m_zmotor->getMotor(); |
|
|
@ -436,7 +482,7 @@ int32_t PipetteModule::do_pipette_aspirate(int32_t ul) { |
|
|
|
m_thread.start( |
|
|
|
[this, ul]() { //
|
|
|
|
DO_IN_THREAD(befor_run()); |
|
|
|
DO_IN_THREAD(m_smtp2.pump_aspirate(ul)); |
|
|
|
DO_IN_THREAD(m_smtp2.pump_aspirate(m_config.aspirate_distribut_pump_vel, ul)); |
|
|
|
while (true) { |
|
|
|
if (!check_when_run()) break; |
|
|
|
if (m_thread.getExitFlag()) break; |
|
|
@ -473,7 +519,7 @@ int32_t PipetteModule::do_pipette_distribut(int32_t ul) { |
|
|
|
m_thread.start( |
|
|
|
[this, ul]() { //
|
|
|
|
DO_IN_THREAD(befor_run()); |
|
|
|
DO_IN_THREAD(m_smtp2.pump_distribut(ul)); |
|
|
|
DO_IN_THREAD(m_smtp2.pump_distribut(m_config.aspirate_distribut_pump_vel, ul)); |
|
|
|
while (true) { |
|
|
|
if (!check_when_run()) break; |
|
|
|
if (m_thread.getExitFlag()) break; |
|
|
@ -498,60 +544,6 @@ int32_t PipetteModule::do_pipette_distribut(int32_t ul) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
#if 0
|
|
|
|
int32_t PipetteModule::do_pipette_clld_test(int32_t zdpos) { |
|
|
|
m_thread.stop(); |
|
|
|
creg.module_status = 1; |
|
|
|
m_thread.start( |
|
|
|
[this, zdpos]() { //
|
|
|
|
DO_IN_THREAD(befor_run()); |
|
|
|
|
|
|
|
m_zmotor->module_active_cfg(); |
|
|
|
m_zmotor->step_motor_enable(1); |
|
|
|
|
|
|
|
auto submotor = m_zmotor->getMotor(); |
|
|
|
submotor->moveBy(zdpos, m_config.lld_velocity); |
|
|
|
|
|
|
|
int32_t zmotor_start_pos = submotor->getXACTUAL(); |
|
|
|
|
|
|
|
capturedata_num = 0; |
|
|
|
|
|
|
|
while (true) { |
|
|
|
if (!check_when_run()) break; |
|
|
|
if (m_thread.getExitFlag()) break; |
|
|
|
|
|
|
|
bool motorstoped = false; |
|
|
|
int32_t motorerror = 0; |
|
|
|
int32_t motorpos = 0; |
|
|
|
int32_t capacitance = 0; |
|
|
|
|
|
|
|
m_smtp2.pump_get_capacitance(&capacitance); |
|
|
|
motorpos = submotor->getXACTUAL() - zmotor_start_pos; |
|
|
|
submotor->readMotorState(&motorstoped, &motorerror); |
|
|
|
|
|
|
|
if (motorerror != 0) { |
|
|
|
creg.module_errorcode = motorerror; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
if (motorstoped) { |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
push_snesor_sample_data(motorpos, capacitance, 0); |
|
|
|
m_thread.sleep(m_config.lld_detect_period_ms); |
|
|
|
} |
|
|
|
}, |
|
|
|
[this]() { // exit fn
|
|
|
|
ZLOGI(TAG, "do_pipette_clld_test finish"); |
|
|
|
after_run(); |
|
|
|
} //
|
|
|
|
); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
int32_t PipetteModule::do_pipette_plld_test(int32_t zdpos) { return 0; } |
|
|
|
#endif
|
|
|
|
|
|
|
|
int32_t PipetteModule::pipette_enable_zmotor(int32_t enable) { return m_zmotor->step_motor_enable(enable); } |
|
|
|
int32_t PipetteModule::pipette_get_sensor_sample_data(int32_t index, int32_t *motor_pos, int32_t *cval, int32_t *pval) { |
|
|
|
if (index > capturedata_num) return err::kparam_out_of_range; |
|
|
@ -585,6 +577,7 @@ int32_t PipetteModule::befor_run() { |
|
|
|
creg.module_errorcode = 0; |
|
|
|
DO(module_active_cfg()); |
|
|
|
DO(m_smtp2.pump_get_motor_pos_ul(&m_state.pump_before_pos_ul)); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
int32_t PipetteModule::after_run() { |
|
|
|
int32_t err = 0; |
|
|
|