Browse Source

update

master
zhaohe 2 months ago
parent
commit
8e7bc532f9
  1. 24
      sdk/components/pipette_module/base/pipette_cfg.hpp
  2. 43
      sdk/components/pipette_module/base/pipette_enum.hpp
  3. 322
      sdk/components/pipette_module/pipette_ctrl_module.cpp
  4. 9
      sdk/components/pipette_module/pipette_ctrl_module.hpp
  5. 57
      sdk/components/sensors/smtp2_v2/smtp2_v2.cpp
  6. 8
      sdk/components/sensors/smtp2_v2/smtp2_v2.hpp
  7. 2
      sdk/components/zcan_protocol_parser/zcan_protocol_parser.cpp

24
sdk/components/pipette_module/base/pipette_cfg.hpp

@ -23,7 +23,7 @@ typedef struct {
int32_t tip_picking_append_distance; // 取tip时z轴的附加距离
int32_t tip_deposit_pos; // 丢tip位置(绝对位置0.1mm)
int32_t transform_pos; // 移液枪安全移动的高度(绝对位置0.1mm)
int32_t _transform_pos; // 移液枪安全移动的高度(绝对位置0.1mm)
/**
* @brief tip类型
*
@ -209,26 +209,26 @@ typedef struct {
//
// lld
//
int32_t plld_pm_vindex; // 液面探测时泵机速率
int32_t plld_pm_vcpyid; // 液面探测时泵机速率
int32_t plld_threshold; // 液面探测阈值
int32_t plld_zm_vel; // 液面探测时泵机速率
//
// 清空tip配置
//
int32_t empty_tip_pm_vindex; // 清空tip速度
int32_t empty_tip_pm_vcpyid; // 清空tip速度
//
// 吸入空气
//
int32_t blowout_air_volume; // 清空空气量,在吸液前吸入的空气量. 精度0.1ul (保证清空tip头)
int32_t blowout_air_pm_vindex; // 吸入空气时泵机速率
int32_t blowout_air_pm_vcpyid; // 吸入空气时泵机速率
//
// 润湿tip头配置
//
int32_t over_aspirated_volume; // 过量吸液量,先吸入后迅速排出用来润湿tip头,这个用在移液量小于10微升的情况下。精度0.1ul
int32_t over_aspirated_pm_vindex; // 过量吸液速度
int32_t over_aspirated_pm_vcpyid; // 过量吸液速度
//
// aspiration 吸液配置
@ -268,24 +268,24 @@ typedef struct {
// 转移时多吸入的量
//
int32_t transport_volume; // 转移过程中多吸入的量,精度0.1ul (放滴落)
int32_t transport_volume_pm_vindex; // 吸入过量空气时泵机速率
int32_t transport_volume_pm_vcpyid; // 吸入过量空气时泵机速率
//
// 混匀pm速率
//
int32_t mix_pm_vindex; // 混匀时泵机速率配置
int32_t mix_pm_vcpyid; // 混匀时泵机速率配置
int32_t mark; // 结构体最后一个数值,设置9973,用于保证单片机端和java端均正确更新了枚举
} liquid_info_t;
typedef enum {
kliquid_info_plld_pm_vindex,
kliquid_info_plld_pm_vcpyid,
kliquid_info_plld_threshold,
kliquid_info_plld_zm_vel,
kliquid_info_empty_tip_pm_vindex,
kliquid_info_empty_tip_pm_vcpyid,
kliquid_info_blowout_air_volume,
kliquid_info_blowout_air_pm_vindex,
kliquid_info_blowout_air_pm_vcpyid,
kliquid_info_over_aspirated_volume,
kliquid_info_over_aspirated_pm_vindex,
kliquid_info_over_aspirated_pm_vcpyid,
kliquid_info_aspiration_pm_vindex_low,
kliquid_info_aspiration_pm_vindex_high,
kliquid_info_aspiration_volume_break_val,
@ -293,7 +293,7 @@ typedef enum {
kliquid_info_volume_calibration_coefficient_k,
kliquid_info_settling_time,
kliquid_info_transport_volume,
kliquid_info_transport_volume_pm_vindex,
kliquid_info_transport_volume_pm_vcpyid,
kliquid_info_mix_pm_vindex,
kliquid_info_mark,
} liquid_info_index_t;

43
sdk/components/pipette_module/base/pipette_enum.hpp

@ -25,3 +25,46 @@ typedef enum {
kzm_v_llf = 5, // 液面基础速度配置
kzm_v_picking_tip = 6, // 取tip速度
} zm_vcpyid_t;
static inline const char *get_pm_vcpyid_name(pm_vcpyid_t id) {
static char buf[20];
#define CASE(x) \
case x: \
return #x;
switch (id) {
CASE(kpm_v_default);
CASE(kpm_v_slow_lv1);
CASE(kpm_v_slow_lv2);
CASE(kpm_v_slow_lv3);
CASE(kpm_v_mid);
CASE(kpm_v_quick);
CASE(kpm_v_max);
CASE(kpm_v_lld);
default:
break;
}
#undef CASE
snprintf(buf, sizeof(buf), "unmatch(%d)", id);
return buf;
}
static inline const char *get_zm_vcpyid_name(zm_vcpyid_t id) {
static char buf[20];
#define CASE(x) \
case x: \
return #x;
switch (id) {
CASE(kzm_v_default);
CASE(kzm_v_move_to_zero);
CASE(kzm_v_look_zero_edge);
CASE(kzm_v_lld);
CASE(kzm_v_swap);
CASE(kzm_v_llf);
CASE(kzm_v_picking_tip);
default:
break;
}
#undef CASE
snprintf(buf, sizeof(buf), "unmatch(%d)", id);
return buf;
}

322
sdk/components/pipette_module/pipette_ctrl_module.cpp

@ -150,6 +150,7 @@ int32_t PipetteModule::pipette_get_zmbcfg(zm_bcfg_index_t index, int32_t *val) {
return err::kparam_out_of_range;
}
}
return 0;
}
int32_t PipetteModule::pipette_set_pmbcfg(pm_bcfg_index_t index, int32_t val) {
@ -188,7 +189,7 @@ int32_t PipetteModule::pipette_set_platinfo(int32_t cpyid, platinfo_index_t inde
SET_CFG(kplatinfo_tip_picking_search_range, platinfo->tip_picking_search_range, val);
SET_CFG(kplatinfo_tip_picking_append_distance, platinfo->tip_picking_append_distance, val);
SET_CFG(kplatinfo_tip_deposit_pos, platinfo->tip_deposit_pos, val);
SET_CFG(kplatinfo_transform_pos, platinfo->transform_pos, val);
SET_CFG(kplatinfo_transform_pos, platinfo->_transform_pos, val);
SET_CFG(kplatinfo_tip_type, platinfo->tip_type, val);
SET_CFG(kplatinfo_tip_length, platinfo->tip_length, val);
SET_CFG(kplatinfo_mark, platinfo->mark, val);
@ -212,7 +213,7 @@ int32_t PipetteModule::pipette_get_platinfo(int32_t cpyid, platinfo_index_t inde
GET_CFG(kplatinfo_tip_picking_search_range, platinfo->tip_picking_search_range, val);
GET_CFG(kplatinfo_tip_picking_append_distance, platinfo->tip_picking_append_distance, val);
GET_CFG(kplatinfo_tip_deposit_pos, platinfo->tip_deposit_pos, val);
GET_CFG(kplatinfo_transform_pos, platinfo->transform_pos, val);
GET_CFG(kplatinfo_transform_pos, platinfo->_transform_pos, val);
GET_CFG(kplatinfo_tip_type, platinfo->tip_type, val);
GET_CFG(kplatinfo_tip_length, platinfo->tip_length, val);
GET_CFG(kplatinfo_mark, platinfo->mark, val);
@ -245,6 +246,11 @@ int32_t PipetteModule::pipette_set_zmvcfg(int32_t cpyid, zm_vcfg_index_t index,
return err::kparam_out_of_range;
}
}
if (cpyid == m_state.zm_now_vcfg_index) {
m_state.zm_now_vcfg_index = -1;
}
return 0;
}
int32_t PipetteModule::pipette_get_zmvcfg(int32_t cpyid, zm_vcfg_index_t index, int32_t *val) {
@ -289,6 +295,11 @@ int32_t PipetteModule::pipette_set_pmvcfg(int32_t cpyid, pm_vcfg_index_t index,
return err::kparam_out_of_range;
}
}
if (cpyid == m_state.pm_now_vcfg_index) {
m_state.pm_now_vcfg_index = -1;
}
return 0;
}
int32_t PipetteModule::pipette_get_pmvcfg(int32_t cpyid, pm_vcfg_index_t index, int32_t *val) {
@ -376,14 +387,14 @@ int32_t PipetteModule::pipette_set_liquid_info(int32_t cpyid, liquid_info_index_
liquid_info_t *cfg = &m_liquid_info[cpyid];
switch (index) {
SET_CFG(kliquid_info_plld_pm_vindex, cfg->plld_pm_vindex, val);
SET_CFG(kliquid_info_plld_pm_vcpyid, cfg->plld_pm_vcpyid, val);
SET_CFG(kliquid_info_plld_threshold, cfg->plld_threshold, val);
SET_CFG(kliquid_info_plld_zm_vel, cfg->plld_zm_vel, val);
SET_CFG(kliquid_info_empty_tip_pm_vindex, cfg->empty_tip_pm_vindex, val);
SET_CFG(kliquid_info_empty_tip_pm_vcpyid, cfg->empty_tip_pm_vcpyid, val);
SET_CFG(kliquid_info_blowout_air_volume, cfg->blowout_air_volume, val);
SET_CFG(kliquid_info_blowout_air_pm_vindex, cfg->blowout_air_pm_vindex, val);
SET_CFG(kliquid_info_blowout_air_pm_vcpyid, cfg->blowout_air_pm_vcpyid, val);
SET_CFG(kliquid_info_over_aspirated_volume, cfg->over_aspirated_volume, val);
SET_CFG(kliquid_info_over_aspirated_pm_vindex, cfg->over_aspirated_pm_vindex, val);
SET_CFG(kliquid_info_over_aspirated_pm_vcpyid, cfg->over_aspirated_pm_vcpyid, val);
SET_CFG(kliquid_info_aspiration_pm_vindex_low, cfg->aspiration_pm_vindex_low, val);
SET_CFG(kliquid_info_aspiration_pm_vindex_high, cfg->aspiration_pm_vindex_high, val);
SET_CFG(kliquid_info_aspiration_volume_break_val, cfg->aspiration_volume_break_val, val);
@ -391,8 +402,8 @@ int32_t PipetteModule::pipette_set_liquid_info(int32_t cpyid, liquid_info_index_
SET_CFG(kliquid_info_volume_calibration_coefficient_k, cfg->volume_calibration_coefficient_k, val);
SET_CFG(kliquid_info_settling_time, cfg->settling_time, val);
SET_CFG(kliquid_info_transport_volume, cfg->transport_volume, val);
SET_CFG(kliquid_info_transport_volume_pm_vindex, cfg->transport_volume_pm_vindex, val);
SET_CFG(kliquid_info_mix_pm_vindex, cfg->mix_pm_vindex, val);
SET_CFG(kliquid_info_transport_volume_pm_vcpyid, cfg->transport_volume_pm_vcpyid, val);
SET_CFG(kliquid_info_mix_pm_vindex, cfg->mix_pm_vcpyid, val);
SET_CFG(kliquid_info_mark, cfg->mark, val);
default: {
@ -410,14 +421,14 @@ int32_t PipetteModule::pipette_get_liquid_info(int32_t cpyid, liquid_info_index_
liquid_info_t *cfg = &m_liquid_info[cpyid];
switch (index) {
GET_CFG(kliquid_info_plld_pm_vindex, cfg->plld_pm_vindex, val);
GET_CFG(kliquid_info_plld_pm_vcpyid, cfg->plld_pm_vcpyid, val);
GET_CFG(kliquid_info_plld_threshold, cfg->plld_threshold, val);
GET_CFG(kliquid_info_plld_zm_vel, cfg->plld_zm_vel, val);
GET_CFG(kliquid_info_empty_tip_pm_vindex, cfg->empty_tip_pm_vindex, val);
GET_CFG(kliquid_info_empty_tip_pm_vcpyid, cfg->empty_tip_pm_vcpyid, val);
GET_CFG(kliquid_info_blowout_air_volume, cfg->blowout_air_volume, val);
GET_CFG(kliquid_info_blowout_air_pm_vindex, cfg->blowout_air_pm_vindex, val);
GET_CFG(kliquid_info_blowout_air_pm_vcpyid, cfg->blowout_air_pm_vcpyid, val);
GET_CFG(kliquid_info_over_aspirated_volume, cfg->over_aspirated_volume, val);
GET_CFG(kliquid_info_over_aspirated_pm_vindex, cfg->over_aspirated_pm_vindex, val);
GET_CFG(kliquid_info_over_aspirated_pm_vcpyid, cfg->over_aspirated_pm_vcpyid, val);
GET_CFG(kliquid_info_aspiration_pm_vindex_low, cfg->aspiration_pm_vindex_low, val);
GET_CFG(kliquid_info_aspiration_pm_vindex_high, cfg->aspiration_pm_vindex_high, val);
GET_CFG(kliquid_info_aspiration_volume_break_val, cfg->aspiration_volume_break_val, val);
@ -425,8 +436,8 @@ int32_t PipetteModule::pipette_get_liquid_info(int32_t cpyid, liquid_info_index_
GET_CFG(kliquid_info_volume_calibration_coefficient_k, cfg->volume_calibration_coefficient_k, val);
GET_CFG(kliquid_info_settling_time, cfg->settling_time, val);
GET_CFG(kliquid_info_transport_volume, cfg->transport_volume, val);
GET_CFG(kliquid_info_transport_volume_pm_vindex, cfg->transport_volume_pm_vindex, val);
GET_CFG(kliquid_info_mix_pm_vindex, cfg->mix_pm_vindex, val);
GET_CFG(kliquid_info_transport_volume_pm_vcpyid, cfg->transport_volume_pm_vcpyid, val);
GET_CFG(kliquid_info_mix_pm_vindex, cfg->mix_pm_vcpyid, val);
GET_CFG(kliquid_info_mark, cfg->mark, val);
default: {
ZLOGE(TAG, "pipette_get_liquid_info index %d out of range", index);
@ -666,33 +677,7 @@ int32_t PipetteModule::pipette_zmotor_move_to(int32_t tox) {
* @return int32_t
*/
int32_t PipetteModule::pipette_zmotor_move_to_zero_point_quick() {
thread_start_work(__FUNCTION__, [this]() {
// 期望偏差
int32_t expectation_dpos = -zmbcfg.io_trigger_append_distance + 0 + zmbcfg.dzero - zm_get_now_pos();
int32_t startpos = zm_get_now_pos();
if (!zm0p_is_trigger()) {
// 快速移动到零点
// moveTo(0 + zmbcfg.dzero, zmbcfg.default_velocity);
zm_move_to(0 + zmbcfg.dzero, kzm_v_default, 0);
zm_waitfor_zm0p_trigger_and_stop_motor(NULL);
} else {
// 快速移动到零点
zm_move_to(0 + zmbcfg.dzero, kzm_v_default, 0);
zm_waitfor_zm0p_not_trigger_and_stop_motor(NULL);
}
// 移动到零点
do_zm_move_0p();
// 校验偏差
int32_t dpos = zm_get_now_pos() - startpos;
// 设置零点
zm_set_now_pos(0 + zmbcfg.dzero - zmbcfg.io_trigger_append_distance);
m_state.zm_has_move_zero = 1;
if (zmbcfg.pos_devi_tolerance != 0 && (abs(expectation_dpos - dpos) > zmbcfg.pos_devi_tolerance)) {
throw zapp_exception(err::kstep_motor_lost_step);
}
});
thread_start_work(__FUNCTION__, [this]() { zm_move_to_zero_quick_block(); });
return 0;
}
@ -720,7 +705,7 @@ int32_t PipetteModule::pipette_pump_take_tip() {
* -> tip状态被触发停止移动
*/
platinfo_t *platform_info = &m_now_platinfo;
platinfo_t *platform_info = get_platinfo_smart(m_state.platinfo_cpyid, &m_now_platinfo);
zm_move_to_block(platform_info->tip_picking_pos, kzm_v_default, 0);
zm_move_by(platform_info->tip_picking_search_range, kzm_v_picking_tip, 0);
bool takeTip = false;
@ -738,7 +723,7 @@ int32_t PipetteModule::pipette_pump_take_tip() {
if (takeTip && platform_info->tip_picking_append_distance > 0) //
zm_move_by_block(platform_info->tip_picking_append_distance, kzm_v_picking_tip, 0);
zm_move_to_block(platform_info->transform_pos, kzm_v_default, 0);
zm_move_to_zero_quick_block();
ZLOGI(TAG, "pipette_pump_take_tip takeTip %s", takeTip ? "suc" : "fail");
});
return 0;
@ -752,7 +737,7 @@ int32_t PipetteModule::pipette_pump_putbak_tip() {
* -> tip
*/
platinfo_t *platform_info = &m_now_platinfo;
platinfo_t *platform_info = get_platinfo_smart(m_state.platinfo_cpyid, &m_now_platinfo);
int32_t putbakpos = platform_info->tip_picking_pos - 100;
if (putbakpos < 0) putbakpos = 0;
zm_move_to_block(putbakpos, kzm_v_default, 0);
@ -762,7 +747,7 @@ int32_t PipetteModule::pipette_pump_putbak_tip() {
DO_IN_THREAD(m_smtp2.pump_init());
pump_waitfor_stop();
zm_move_to_block(platform_info->transform_pos, kzm_v_default, 0);
zm_move_to_zero_quick_block();
});
return 0;
@ -777,15 +762,17 @@ int32_t PipetteModule::pipette_pump_deposit_tip() {
* -> tip
*/
platinfo_t *platform_info = &m_now_platinfo;
platinfo_t *platform_info = get_platinfo_smart(m_state.platinfo_cpyid, &m_now_platinfo);
zm_move_to_block(platform_info->tip_deposit_pos, kzm_v_default, 0);
pump_apply_vcfg(kpm_v_max); //
// DO_IN_THREAD(m_smtp2.pump_put_tip());
DO_IN_THREAD(m_smtp2.pump_init());
while (pump_read_tip_state() != 0) {
thread_delay(1);
}
zm_move_to_zero_quick_block();
pump_waitfor_stop();
zm_move_to_block(platform_info->transform_pos, kzm_v_default, 0);
});
return 0;
@ -795,11 +782,12 @@ int32_t PipetteModule::pipette_pump_pierce_through(int32_t container_info_index,
// check param
check_container_info_cpyid(container_info_index);
platinfo_t *platform_info = &m_now_platinfo;
platinfo_t *platform_info = get_platinfo_smart(m_state.platinfo_cpyid, &m_now_platinfo);
container_info_t *container_info = get_container_info_smart(container_info_index, &m_now_container_info);
zm_move_to_block(container_info->pierce_depth + container_pos, kzm_v_default, 0);
zm_move_to_block(platform_info->transform_pos, kzm_v_default, 0);
zm_move_to_zero_quick_block();
});
return 0;
}
@ -866,7 +854,7 @@ int32_t PipetteModule::pipette_pump_aspirate() {
thread_start_work(__FUNCTION__, [this]() {
ZLOGI(TAG, "pipette_pump_aspirate");
if (pump_read_tip_state() == 0) {
throw zapp_exception(err::kpipette_error_no_tip_when_lld);
throw zapp_exception(err::kpipette_error_TipDrop);
}
aspiration_param_t *acfg = &m_aspiration_param;
check_pipette_pump_aspirate_params();
@ -875,7 +863,11 @@ int32_t PipetteModule::pipette_pump_aspirate() {
DO_IN_THREAD(m_smtp2.pump_enable_temp_compensation(0)); // 关闭温度补偿
DO_IN_THREAD(m_smtp2.pump_set_back_clearance(0)); // 设置背隙为0
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_io2_mode(0)); // 通用输入
platinfo_t *platform_info = get_platinfo_smart(m_state.platinfo_cpyid, &m_now_platinfo);
liquid_info_t *liquidinfo = get_liquid_info_smart(acfg->liquid_cfg_index, &aspirate_run_cxt.liquid_info);
container_info_t *container_cfg = get_container_info_smart(acfg->container_info_index, &aspirate_run_cxt.container_info);
ZLOGI(TAG, "-------------------------- aspiration param --------------------------");
ZLOGI(TAG, "- x100nl :%d", acfg->volumeX100nl);
@ -892,23 +884,81 @@ int32_t PipetteModule::pipette_pump_aspirate() {
ZLOGI(TAG, "- mix_times :%d", acfg->mix_times);
ZLOGI(TAG, "-");
// aspirate_run_cxt
platinfo_t *platform_info = &m_now_platinfo;
liquid_info_t *liquidinfo = get_liquid_info_smart(acfg->liquid_cfg_index, &aspirate_run_cxt.liquid_info);
container_info_t *container_cfg = get_container_info_smart(acfg->container_info_index, &aspirate_run_cxt.container_info);
ZLOGI(TAG, "-------------------------- platform_info --------------------------");
ZLOGI(TAG, "- tip_type :%d", platform_info->tip_type);
ZLOGI(TAG, "- tip_length :%d", platform_info->tip_length);
ZLOGI(TAG, "-");
ZLOGI(TAG, "-------------------------- liquid_info --------------------------");
ZLOGI(TAG, "- plld_pm_vindex :%d", liquidinfo->plld_pm_vcpyid);
ZLOGI(TAG, "- plld_threshold :%d", liquidinfo->plld_threshold);
ZLOGI(TAG, "- plld_zm_vel :%d", liquidinfo->plld_zm_vel);
ZLOGI(TAG, "- empty_tip_pm_vindex :%d", liquidinfo->empty_tip_pm_vcpyid);
ZLOGI(TAG, "- blowout_air_volume :%d", liquidinfo->blowout_air_volume);
ZLOGI(TAG, "- blowout_air_pm_vindex :%d", liquidinfo->blowout_air_pm_vcpyid);
ZLOGI(TAG, "- over_aspirated_volume :%d", liquidinfo->over_aspirated_volume);
ZLOGI(TAG, "- over_aspirated_pm_vindex :%d", liquidinfo->over_aspirated_pm_vcpyid);
ZLOGI(TAG, "- aspiration_pm_vindex_low :%d", liquidinfo->aspiration_pm_vindex_low);
ZLOGI(TAG, "- aspiration_pm_vindex_high :%d", liquidinfo->aspiration_pm_vindex_high);
ZLOGI(TAG, "- aspiration_volume_break_val :%d", liquidinfo->aspiration_volume_break_val);
ZLOGI(TAG, "- volume_calibration_coefficient_b :%d", liquidinfo->volume_calibration_coefficient_b);
ZLOGI(TAG, "- volume_calibration_coefficient_k :%d", liquidinfo->volume_calibration_coefficient_k);
ZLOGI(TAG, "- settling_time :%d", liquidinfo->settling_time);
ZLOGI(TAG, "- transport_volume :%d", liquidinfo->transport_volume);
ZLOGI(TAG, "- transport_volume_pm_vindex :%d", liquidinfo->transport_volume_pm_vcpyid);
ZLOGI(TAG, "- mix_pm_vindex :%d", liquidinfo->mix_pm_vcpyid);
ZLOGI(TAG, "- mark :%d", liquidinfo->mark);
ZLOGI(TAG, "-");
ZLOGI(TAG, "-------------------------- container_info --------------------------");
ZLOGI(TAG, "- container_type :%d", container_cfg->container_type);
ZLOGI(TAG, "- container_neck_pos :%d", container_cfg->_container_neck_pos);
ZLOGI(TAG, "- container_depth :%d", container_cfg->container_depth);
ZLOGI(TAG, "- container_round :%d", container_cfg->container_round);
ZLOGI(TAG, "- container_bottom_section_height :%d", container_cfg->container_bottom_section_height);
ZLOGI(TAG, "- immersion_depth :%d", container_cfg->immersion_depth);
ZLOGI(TAG, "- leaving_height :%d", container_cfg->leaving_height);
ZLOGI(TAG, "- jet_height :%d", container_cfg->jet_height);
ZLOGI(TAG, "- lld_start_search_depth :%d", container_cfg->lld_start_search_depth);
ZLOGI(TAG, "- fix_aspiration_depth :%d", container_cfg->fix_aspiration_depth);
ZLOGI(TAG, "- llf_vconvert_coneff :%d", container_cfg->llf_vconvert_coneff);
ZLOGI(TAG, "- pierce_depth :%d", container_cfg->pierce_depth);
ZLOGI(TAG, "- mark :%d", container_cfg->mark);
ZLOGI(TAG, "-");
/***********************************************************************************************************************
* LLD *
***********************************************************************************************************************/
DO_IN_THREAD(m_smtp2.pump_set_tip_size((smtp2::TipSize_t)platform_info->tip_type)); // 250ul,
if (acfg->lld_enable) {
// 液面探测
_do_lld(platform_info, container_cfg, liquidinfo, acfg);
// 这里需要低速离开液面,防止携带液滴
ZLOGI(TAG, "move to swap position in v_swap");
zm_move_to_block(m_state.water_level - container_cfg->leaving_height, kzm_v_swap, 0); //
// 清空tip
ZLOGI(TAG, "clean tip.");
pump_move_to_x100nl_block(0, liquidinfo->empty_tip_pm_vcpyid);
} else {
// 没有使用lld,使用固定深度
m_state.water_level = acfg->container_pos + container_cfg->fix_aspiration_depth;
ZLOGI(TAG, "lld isn't enable,use fix depth %d", m_state.water_level);
zm_move_to_block(m_state.water_level - 150, kzm_v_default, 0); //
pump_move_to_x100nl_block(0, liquidinfo->empty_tip_pm_vindex); // 清空tip
// 由于tip原本在液面之上,这里快速移动到swap位置,
ZLOGI(TAG, "move to swap position in v_default");
zm_move_to_block(m_state.water_level - container_cfg->leaving_height, kzm_v_default, 0); //
ZLOGI(TAG, "clean tip.");
pump_move_to_x100nl_block(0, liquidinfo->empty_tip_pm_vcpyid); //
}
if (acfg->volumeX100nl != 0) {
_do_sapirate(platform_info, container_cfg, liquidinfo, acfg);
} else {
ZLOGI(TAG, "aspiration volume == 0,skip aspirate", acfg->volumeX100nl);
}
_do_sapirate(platform_info, container_cfg, liquidinfo, acfg);
// z轴移动transform_pos
zm_move_to_zero_quick_block();
});
return 0;
}
@ -916,12 +966,12 @@ int32_t PipetteModule::pipette_pump_aspirate() {
void PipetteModule::_do_lld(platinfo_t *platform_info, container_info_t *container_cfg, liquid_info_t *liquidinfo, aspiration_param_t *acfg) {
int32_t ecode = 0;
ZLOGI(TAG, "start lld, lld_type %d lld_pm_vindex %d plld_threshold %d", acfg->lld_type, liquidinfo->plld_pm_vindex, liquidinfo->plld_threshold);
ZLOGI(TAG, "start lld, lld_type %d lld_pm_vindex %d plld_threshold %d", acfg->lld_type, liquidinfo->plld_pm_vcpyid, liquidinfo->plld_threshold);
// 移动到转移位置
zm_move_to_block(0, kzm_v_default, 0);
// 清空tip
pump_move_to_x100nl_block(0, liquidinfo->empty_tip_pm_vindex);
pump_move_to_x100nl_block(0, liquidinfo->empty_tip_pm_vcpyid);
// 移动到瓶口
zm_move_to_block(acfg->container_pos + 50 /*5mm*/, //
@ -929,7 +979,7 @@ void PipetteModule::_do_lld(platinfo_t *platform_info, container_info_t *contain
pump_move_to_x100nl_block(0, kpm_v_default); // 回转一下,消除齿轮间隙
// 启动lld
pump_apply_vcfg(liquidinfo->plld_pm_vindex); // 设备lld时,泵的速率
pump_apply_vcfg(liquidinfo->plld_pm_vcpyid); // 设备lld时,泵的速率
DO_IN_THREAD(m_smtp2.pump_set_tip_size(smtp2::TS200UL)); // 250ul,保护lld不超限
DO_IN_THREAD(m_smtp2.pump_set_io1_mode(1)); // lld输入高
DO_IN_THREAD(m_smtp2.pump_aspirate_plld(liquidinfo->plld_threshold));
@ -986,57 +1036,61 @@ void PipetteModule::_do_lld(platinfo_t *platform_info, container_info_t *contain
}
m_state.detected_liquid = 1;
m_state.water_level = water_level;
// 移动到液面上15mm
zm_move_to_block(m_state.water_level - 150, kzm_v_default, 0); // ? 这里是否考虑使用低速,离开液面
// 清空tip
pump_move_to_x100nl_block(0, liquidinfo->empty_tip_pm_vindex);
}
void PipetteModule::_do_sapirate(platinfo_t *platform_info, container_info_t *container_cfg, liquid_info_t *liquidinfo, aspiration_param_t *acfg) {
DO_IN_THREAD(m_smtp2.pump_set_tip_size(smtp2::TS200UL)); // 250ul,
// 吸入过量的空气
pump_move_to_x100nl_block(liquidinfo->blowout_air_volume, liquidinfo->blowout_air_pm_vindex);
if (liquidinfo->blowout_air_volume > 0) {
ZLOGI(TAG, "--> aspirate blowout_air_volume volume=%d, pm_vcpyid=%d", liquidinfo->blowout_air_volume);
pump_move_to_x100nl_block(liquidinfo->blowout_air_volume, liquidinfo->blowout_air_pm_vcpyid);
} else {
ZLOGI(TAG, "--> aspirate blowout_air_volume volume=0,skip");
}
// Z轴移动到液面之下
ZLOGI(TAG, "--> move below the liquid surface");
zm_move_to_block(m_state.water_level + container_cfg->immersion_depth, kzm_v_swap, 0);
// 吸入润湿TIP的溶液
if (liquidinfo->over_aspirated_volume > 0) {
pump_move_by_x100nl_block(liquidinfo->over_aspirated_volume, liquidinfo->over_aspirated_pm_vindex);
pump_move_by_x100nl_block(-liquidinfo->over_aspirated_volume, liquidinfo->over_aspirated_pm_vindex);
ZLOGI(TAG, "--> aspirate over_aspirated_volume volume=%d, pm_vcpyid=%d", liquidinfo->over_aspirated_volume, liquidinfo->over_aspirated_pm_vcpyid);
pump_move_by_x100nl_block(liquidinfo->over_aspirated_volume, liquidinfo->over_aspirated_pm_vcpyid);
pump_move_by_x100nl_block(-liquidinfo->over_aspirated_volume, liquidinfo->over_aspirated_pm_vcpyid);
}
// 吸入前混匀
if (acfg->mix_volume > 0) {
ZLOGI(TAG, "--> aspirate mix_volume volume=%d, pm_vcpyid=%d", acfg->mix_volume, liquidinfo->mix_pm_vcpyid);
int32_t mix_start_pos = zm_get_now_pos();
for (size_t i = 0; i < acfg->mix_times; i++) {
if (acfg->mix_llf_enable > 0) {
zm_move_to(acfg->container_pos + container_cfg->container_depth, // 瓶底
kzm_v_llf, // 基础速度配置
compute_zm_llf_vel(liquidinfo->mix_pm_vindex, container_cfg)); // 计算llf速度
compute_zm_llf_vel(liquidinfo->mix_pm_vcpyid, container_cfg)); // 计算llf速度
}
pump_move_by_x100nl_block(acfg->mix_volume, liquidinfo->mix_pm_vindex);
pump_move_by_x100nl_block(acfg->mix_volume, liquidinfo->mix_pm_vcpyid);
if (acfg->mix_llf_enable > 0) zm_stop();
if (acfg->mix_llf_enable > 0) {
zm_move_to(mix_start_pos, kzm_v_llf, compute_zm_llf_vel(liquidinfo->mix_pm_vindex, container_cfg));
zm_move_to(mix_start_pos, kzm_v_llf, compute_zm_llf_vel(liquidinfo->mix_pm_vcpyid, container_cfg));
}
pump_move_by_x100nl_block(-acfg->mix_volume, liquidinfo->mix_pm_vindex);
pump_move_by_x100nl_block(-acfg->mix_volume, liquidinfo->mix_pm_vcpyid);
if (acfg->mix_llf_enable > 0) zm_stop();
}
} else {
ZLOGI(TAG, "--> aspirate mix_volume volume=0,skip");
}
// !吸入液体(TODO:存储吸液压力曲线)!
{
ZLOGI(TAG, "--> aspirate volume=%d", acfg->volumeX100nl);
int32_t aspiration_pm_index = liquidinfo->aspiration_pm_vindex_low;
if (acfg->volumeX100nl > liquidinfo->aspiration_volume_break_val) {
aspiration_pm_index = liquidinfo->aspiration_pm_vindex_high;
}
int32_t x100nl = acfg->volumeX100nl * liquidinfo->volume_calibration_coefficient_k * 0.0001 + liquidinfo->volume_calibration_coefficient_b * 0.0001;
int32_t x100nl = acfg->volumeX100nl * liquidinfo->volume_calibration_coefficient_k * 0.001 + //
liquidinfo->volume_calibration_coefficient_b * 0.001;
if (acfg->llf_enable > 0) {
zm_move_to( //
@ -1050,18 +1104,18 @@ void PipetteModule::_do_sapirate(platinfo_t *platform_info, container_info_t *co
}
// 等待一定时间
ZLOGI(TAG, "--> delay some time...(%d)", liquidinfo->settling_time);
thread_delay(liquidinfo->settling_time);
// 离开液面
zm_move_to_block(m_state.water_level - 150, kzm_v_swap, 0); //
ZLOGI(TAG, "--> leave liquid surface");
zm_move_to_block(m_state.water_level - container_cfg->leaving_height, kzm_v_swap, 0); //
// 吸入过量的空气
if (liquidinfo->transport_volume > 0) {
pump_move_by_x100nl_block(liquidinfo->transport_volume, liquidinfo->transport_volume_pm_vindex);
ZLOGI(TAG, "--> aspirate transport_volume volume=%d, pm_vcpyid=%d", liquidinfo->transport_volume, liquidinfo->transport_volume_pm_vcpyid);
pump_move_by_x100nl_block(liquidinfo->transport_volume, liquidinfo->transport_volume_pm_vcpyid);
}
// z轴移动transform_pos
zm_move_to_block(0, kzm_v_default, 0);
}
int32_t PipetteModule::pipette_pump_distribu() { return 0; }
@ -1105,14 +1159,14 @@ void PipetteModule::do_zm_move_0p() {
// leave from zero
if (zm0p_is_trigger()) {
ZLOGI(TAG, "leave from zero");
zm_move_by(50 /*10mm */, kzm_v_look_zero_edge, 0);
zm_move_by(500 /*50mm */, kzm_v_look_zero_edge, 0);
zm_waitfor_zm0p_not_trigger_and_stop_motor(&is_trigger);
if (!is_trigger) throw zapp_exception(err::kstep_motor_not_found_point_edge);
}
if (!zm0p_is_trigger()) {
ZLOGI(TAG, "move to zero edge again");
zm_move_by(-50 /*10mm */, kzm_v_look_zero_edge, 0);
zm_move_by(-100 /*10mm */, kzm_v_look_zero_edge, 0);
zm_waitfor_zm0p_trigger_and_stop_motor(&is_trigger);
if (!is_trigger) throw zapp_exception(err::kstep_motor_not_found_point_edge);
}
@ -1129,6 +1183,34 @@ void PipetteModule::zm_set_now_pos(int32_t x) {
m_zm->setXACTUAL(x);
m_zm->set_enc_val(x);
}
void PipetteModule::zm_move_to_zero_quick_block() {
// 期望偏差
int32_t expectation_dpos = -zmbcfg.io_trigger_append_distance + 0 + zmbcfg.dzero - zm_get_now_pos();
int32_t startpos = zm_get_now_pos();
if (!zm0p_is_trigger()) {
// 快速移动到零点
// moveTo(0 + zmbcfg.dzero, zmbcfg.default_velocity);
zm_move_to(0 + zmbcfg.dzero, kzm_v_default, 0);
zm_waitfor_zm0p_trigger_and_stop_motor(NULL);
} else {
// 快速移动到零点
zm_move_to(0 + zmbcfg.dzero, kzm_v_default, 0);
zm_waitfor_zm0p_not_trigger_and_stop_motor(NULL);
}
// 移动到零点
do_zm_move_0p();
// 校验偏差
int32_t dpos = zm_get_now_pos() - startpos;
// 设置零点
zm_set_now_pos(0 + zmbcfg.dzero - zmbcfg.io_trigger_append_distance);
m_state.zm_has_move_zero = 1;
if (zmbcfg.pos_devi_tolerance != 0 && (abs(expectation_dpos - dpos) > zmbcfg.pos_devi_tolerance)) {
throw zapp_exception(err::kstep_motor_lost_step);
}
}
void PipetteModule::zm_move_to(int32_t x, int32_t vbaseindex, int32_t vel) {
/**
* @brief
@ -1174,6 +1256,7 @@ void PipetteModule::zm_update_dzero(int32_t dzero) {
bool PipetteModule::zm0p_is_trigger() { return m_zm0p->getState(); }
void PipetteModule::zm_apply_vcfg(int32_t vbasecfgindex, int32_t vel) {
ZLOGI(TAG, "zm_apply_vcfg %s", get_zm_vcpyid_name((zm_vcpyid_t)vbasecfgindex));
/**
* @brief 使
*/
@ -1188,6 +1271,12 @@ void PipetteModule::zm_apply_vcfg(int32_t vbasecfgindex, int32_t vel) {
if (cfg.vstop > cfg.vmax) {
cfg.vstop = cfg.vmax;
}
if (cfg.vstart > cfg.vmax) {
cfg.vstart = cfg.vmax;
}
if (cfg.v1 > cfg.vmax) {
cfg.v1 = cfg.vmax;
}
m_zm->set_vstart(cfg.vstart);
m_zm->set_a1(cfg.a1);
@ -1198,14 +1287,7 @@ void PipetteModule::zm_apply_vcfg(int32_t vbasecfgindex, int32_t vel) {
m_zm->set_vstop(cfg.vstop);
m_zm->set_vmax(cfg.vmax);
ZLOGI(TAG, "set vstart %d", cfg.vstart);
ZLOGI(TAG, "set a1 %d", cfg.a1);
ZLOGI(TAG, "set amax %d", cfg.amax);
ZLOGI(TAG, "set v1 %d", cfg.v1);
ZLOGI(TAG, "set dmax %d", cfg.dmax);
ZLOGI(TAG, "set d1 %d", cfg.d1);
ZLOGI(TAG, "set vstop %d", cfg.vstop);
ZLOGI(TAG, "set vmax %d", cfg.vmax);
ZLOGI(TAG, "zm set vstart %d,a1 %d,amax %d,v1 %d,dmax %d,d1 %d,vstop %d,vmax %d", cfg.vstart, cfg.a1, cfg.amax, cfg.v1, cfg.dmax, cfg.d1, cfg.vstop, cfg.vmax);
}
void PipetteModule::zm_sync_base_cfg() {
@ -1284,42 +1366,51 @@ void PipetteModule::pump_waitfor_lld_is_ready(int32_t *zpos) {
}
}
void PipetteModule::pump_get_vcfg(int32_t vcfgindex, smtp2::VelCfg *cfg) {
pm_vcfg_t cfg2 = {0};
get_cfg_smart(vcfgindex, &cfg2);
cfg->acc = cfg2.acc;
cfg->dec = cfg2.dec;
cfg->vstart = cfg2.vstart;
cfg->vstop = cfg2.vstop;
cfg->vmax = cfg2.vmax;
}
void PipetteModule::pump_apply_vcfg(int32_t vcfgindex, bool force) {
ZLOGI(TAG, "pump_apply_vcfg %s", get_pm_vcpyid_name((pm_vcpyid_t)vcfgindex));
if (!force && m_state.pm_now_vcfg_index == vcfgindex) {
// 如果当前配置和目标配置相同,则不需要重新设置
return;
}
pm_vcfg_t cfg = {0};
smtp2::VelCfg vcfg;
get_cfg_smart(vcfgindex, &cfg);
vcfg.acc = cfg.acc;
vcfg.dec = cfg.dec;
vcfg.vstart = cfg.vstart;
vcfg.vstop = cfg.vstop;
vcfg.vmax = cfg.vmax;
pump_get_vcfg(vcfgindex, &vcfg);
DO_IN_THREAD(m_smtp2.pump_set_vcfg(&vcfg));
m_state.pm_now_vcfg_index = vcfgindex;
}
void PipetteModule::pump_move_to_x100nl(int32_t x100nl, int32_t vcfgindex) {
pump_apply_vcfg(vcfgindex);
DO_IN_THREAD(m_smtp2.pump_move_to_nl(x100nl * 100));
smtp2::VelCfg vcfg;
pump_get_vcfg(vcfgindex, &vcfg);
DO_IN_THREAD(m_smtp2.pump_move_to_nl(&vcfg, x100nl * 100));
}
void PipetteModule::pump_move_by_x100nl(int32_t x100nl, int32_t vcfgindex) {
pump_apply_vcfg(vcfgindex);
DO_IN_THREAD(m_smtp2.pump_move_to_nl(x100nl * 100));
ZLOGI(TAG, "pump_move_by_x100nl %d, in %s", x100nl, get_pm_vcpyid_name((pm_vcpyid_t)vcfgindex));
smtp2::VelCfg vcfg;
pump_get_vcfg(vcfgindex, &vcfg);
DO_IN_THREAD(m_smtp2.pump_move_by_nl(&vcfg, x100nl * 100));
}
void PipetteModule::pump_move_to_x100nl_block(int32_t x100nl, int32_t vcfgindex) {
pump_move_to_x100nl(vcfgindex, x100nl);
pump_move_to_x100nl(x100nl, vcfgindex);
pump_waitfor_stop();
ZLOGI(TAG, "pump now pos %d nl", pump_read_pos_nl());
}
void PipetteModule::pump_move_by_x100nl_block(int32_t x100nl, int32_t vcfgindex) {
pump_move_by_x100nl(vcfgindex, x100nl);
pump_move_by_x100nl(x100nl, vcfgindex);
pump_waitfor_stop();
ZLOGI(TAG, "pump now pos %d nl", pump_read_pos_nl());
}
void PipetteModule::pump_read_pos_nl(int32_t *val) {
@ -1329,6 +1420,11 @@ void PipetteModule::pump_read_pos_nl(int32_t *val) {
// pump_read_pos_nl(val);
DO_IN_THREAD(m_smtp2.pump_get_nl(val));
}
int32_t PipetteModule::pump_read_pos_nl() {
int32_t val = 0;
DO_IN_THREAD(m_smtp2.pump_get_nl(&val));
return val;
}
int32_t PipetteModule::pump_read_capactitance() {
int32_t val = 0;
DO_IN_THREAD(m_smtp2.pump_get_capacitance(&val));
@ -1685,14 +1781,14 @@ void PipetteModule::parameter_init() {
memset_int32_t((int32_t *)&m_liquid_info[0], -1, sizeof(m_liquid_info) / 4);
memset_int32_t((int32_t *)&m_liquid_info[0], 0, sizeof(m_liquid_info[0]) / 4);
m_liquid_info[0].plld_pm_vindex = kpm_v_lld;
m_liquid_info[0].plld_pm_vcpyid = kpm_v_lld;
m_liquid_info[0].plld_threshold = 30;
m_liquid_info[0].plld_zm_vel = 50;
m_liquid_info[0].empty_tip_pm_vindex = kpm_v_max;
m_liquid_info[0].empty_tip_pm_vcpyid = kpm_v_max;
m_liquid_info[0].blowout_air_volume = 0;
m_liquid_info[0].blowout_air_pm_vindex = kpm_v_quick;
m_liquid_info[0].blowout_air_pm_vcpyid = kpm_v_quick;
m_liquid_info[0].over_aspirated_volume = 100; // 100(x100nl) == 10ul
m_liquid_info[0].over_aspirated_pm_vindex = kpm_v_slow_lv2;
m_liquid_info[0].over_aspirated_pm_vcpyid = kpm_v_slow_lv2;
m_liquid_info[0].aspiration_pm_vindex_low = kpm_v_slow_lv1;
m_liquid_info[0].aspiration_pm_vindex_high = kpm_v_slow_lv3;
m_liquid_info[0].aspiration_volume_break_val = 500; // 500(x100nl) == 50ul
@ -1700,7 +1796,7 @@ void PipetteModule::parameter_init() {
m_liquid_info[0].volume_calibration_coefficient_k = 1.0f;
m_liquid_info[0].settling_time = 1000; // ms
m_liquid_info[0].transport_volume = 50; // 50(x100nl) == 5ul
m_liquid_info[0].transport_volume_pm_vindex = kpm_v_slow_lv2;
m_liquid_info[0].mix_pm_vindex = kpm_v_max;
m_liquid_info[0].transport_volume_pm_vcpyid = kpm_v_slow_lv2;
m_liquid_info[0].mix_pm_vcpyid = kpm_v_max;
m_liquid_info[0].mark = 9973;
}

9
sdk/components/pipette_module/pipette_ctrl_module.hpp

@ -81,9 +81,9 @@ class PipetteModule : public ZIModule {
/***********************************************************************************************************************
* state *
***********************************************************************************************************************/
pipette_state_t m_state = {0};
platinfo_t m_now_platinfo;
container_info_t m_now_container_info;
pipette_state_t m_state = {0};
platinfo_t m_now_platinfo;
container_info_t m_now_container_info;
aspirate_run_cxt_t aspirate_run_cxt;
distribu_run_cxt_t distribu_run_cxt;
@ -217,6 +217,7 @@ class PipetteModule : public ZIModule {
void zm_stop();
void zm_move_to_end(int32_t direction, int32_t vindex);
void zm_update_dzero(int32_t dzero);
void zm_move_to_zero_quick_block();
int32_t zm_get_now_pos();
void zm_set_now_pos(int32_t x);
@ -234,7 +235,9 @@ class PipetteModule : public ZIModule {
***********************************************************************************************************************/
void pump_apply_vcfg(int32_t vcfgindex, bool force = false);
void pump_get_vcfg(int32_t vcfgindex, smtp2::VelCfg *cfg);
void pump_read_pos_nl(int32_t *val);
int32_t pump_read_pos_nl();
int32_t pump_read_capactitance();
int32_t pump_read_tip_state();
void pump_waitfor_stop();

57
sdk/components/sensors/smtp2_v2/smtp2_v2.cpp

@ -16,6 +16,7 @@ using namespace smtp2;
#define RE_SEND_TIMES 5
#define RE_SEND_DELAY 400
#if DUMP_HEX
static const char* hex2str(const char* hex, size_t len) {
static char buf[256];
memset(buf, 0, sizeof(buf));
@ -24,6 +25,7 @@ static const char* hex2str(const char* hex, size_t len) {
}
return buf;
}
#endif
void SMTP2V2::initialize(UART_HandleTypeDef* uart, uint8_t id, DMA_HandleTypeDef* hdma_rx, DMA_HandleTypeDef* hdma_tx) {
m_uart = uart;
@ -80,17 +82,31 @@ int32_t SMTP2V2::pump_enable_temp_compensation(int32_t enable) {
ZLOGI(TAG, "pump_enable_temp_compensation %d", enable);
return setstate(true, "/1u%d,%dR\r", kcfg_auto_temp_compensation, enable);
}
int32_t SMTP2V2::pump_stop() { return setstate(true, "/1TR\r"); }
int32_t SMTP2V2::pump_set_plld_start_delay(int32_t delay_ms) { return setstate(true, "/1T%dR\r", delay_ms); }
int32_t SMTP2V2::pump_stop() {
ZLOGI(TAG, "pump_stop");
return setstate(true, "/1TR\r");
}
int32_t SMTP2V2::pump_set_plld_start_delay(int32_t delay_ms) {
ZLOGI(TAG, "pump_set_plld_start_delay %d", delay_ms);
return setstate(true, "/1T%dR\r", delay_ms);
}
int32_t SMTP2V2::pump_set_vcfg(VelCfg* vcfg) {
ZLOGI(TAG, "pump_set_vcfg %d,%d,%d,%d,%d", vcfg->acc, vcfg->dec, vcfg->vstart, vcfg->vstop, vcfg->vmax);
// L<n1>,<n2>设置加速度,和减速度 (1..20) V%d 设置最大速度 v%d 设置起始速度 c%d 设置停止速度
return setstate(true, "/1N2L%d,%dv%dc%dV%dR\r", //
vcfg->acc, vcfg->dec, vcfg->vstart * 1000, vcfg->vstop * 1000, vcfg->vmax * 1000);
}
int32_t SMTP2V2::pump_init() { return runaction(true, "/1ZR\r"); }
int32_t SMTP2V2::pump_put_tip() { return runaction(true, "/1E0R\r"); }
int32_t SMTP2V2::pump_init() {
ZLOGI(TAG, "pump_init");
return runaction(true, "/1ZR\r");
}
int32_t SMTP2V2::pump_put_tip() {
ZLOGI(TAG, "pump_put_tip");
return runaction(true, "/1E0R\r");
}
int32_t SMTP2V2::pump_reset() {
ZLOGI(TAG, "pump_reset");
_sendcmd(true, "/1!0R\r"); // 复位指令没有回执,所以这里只能使用方法_sendcmd
_sendcmd(true, "/1!0R\r"); // 复位指令没有回执,所以这里只能使用方法_sendcmd
return 0;
@ -100,11 +116,13 @@ int32_t SMTP2V2::pump_reset() {
* ACTION *
***********************************************************************************************************************/
int32_t SMTP2V2::pump_move_to_nl(int32_t nl) {
int32_t SMTP2V2::pump_move_to_nl(VelCfg* vcfg, int32_t nl) {
ZLOGI(TAG, "pump_move_to_nl %d", nl);
return runaction(true, "/1A%dR\r", nl);
ZLOGI(TAG, "vcfg acc %d dec %d vstart %d vstop %d vmax %d", vcfg->acc, vcfg->dec, vcfg->vstart, vcfg->vstop, vcfg->vmax);
return runaction(true, "/1N2L%d,%dv%dc%dV%dA%dR\r", //
vcfg->acc, vcfg->dec, vcfg->vstart * 1000, vcfg->vstop * 1000, vcfg->vmax * 1000, nl);
}
int32_t SMTP2V2::pump_move_by_nl(int32_t nl) {
int32_t SMTP2V2::pump_move_by_nl(VelCfg* vcfg, int32_t nl) {
ZLOGI(TAG, "pump_move_by_nl %d", nl);
int32_t nownl;
@ -113,22 +131,22 @@ int32_t SMTP2V2::pump_move_by_nl(int32_t nl) {
int targetnl = nownl + nl;
if (targetnl < 0) targetnl = 0;
return pump_move_to_nl(targetnl);
return pump_move_to_nl(vcfg, targetnl);
}
int32_t SMTP2V2::pump_aspirate_nl(int32_t nl) {
ZLOGI(TAG, "pump_aspirate %d", nl);
int32_t nownl;
// int32_t SMTP2V2::pump_aspirate_nl(int32_t nl) {
// ZLOGI(TAG, "pump_aspirate %d", nl);
// int32_t nownl;
int32_t ret = pump_get_state_as_int(kstate_pump_pos_nl, &nownl);
if (ret != 0) return ret;
// int32_t ret = pump_get_state_as_int(kstate_pump_pos_nl, &nownl);
// if (ret != 0) return ret;
int targetnl = nownl + nl;
if (targetnl < 0) targetnl = 0;
return pump_move_to_nl(targetnl);
}
// int targetnl = nownl + nl;
// if (targetnl < 0) targetnl = 0;
// return pump_move_to_nl(targetnl);
// }
int32_t SMTP2V2::pump_distribut_nl(int32_t nl) { return pump_aspirate_nl(-nl); }
// int32_t SMTP2V2::pump_distribut_nl(int32_t nl) { return pump_aspirate_nl(-nl); }
int32_t SMTP2V2::pump_aspirate_and_verify(int32_t nl, int32_t eigen_time, int32_t p_thre, int32_t tolerance) {
/**
@ -141,7 +159,7 @@ int32_t SMTP2V2::pump_aspirate_and_verify(int32_t nl, int32_t eigen_time, int32_
* <n2> 02047 Tip
*
*/
ZLOGI(TAG, "pump_aspirate %d", nl);
ZLOGI(TAG, "pump_aspirate_and_verify %d %d %d %d", nl, eigen_time, p_thre, tolerance);
int32_t nownl;
int32_t ret = pump_get_state_as_int(kstate_pump_pos_nl, &nownl);
@ -255,6 +273,7 @@ int32_t SMTP2V2::pump_distribut_mlld_get_state(int32_t* detected) {
}
int32_t SMTP2V2::pump_set_back_clearance(int32_t val) {
ZLOGI(TAG, "pump_set_back_clearance %d", val);
int32_t ret = 0;
for (size_t i = 0; i < 3; i++) {
ret = setstate(true, "/1K%dR\r", val);

8
sdk/components/sensors/smtp2_v2/smtp2_v2.hpp

@ -217,8 +217,8 @@ class SMTP2V2 {
int32_t pump_put_tip(); // 丢弃TIP
int32_t pump_reset(); // 泵机复位
int32_t pump_stop(); // 停止
int32_t pump_move_to_nl(int32_t nl); //
int32_t pump_move_by_nl(int32_t nl); //
int32_t pump_move_to_nl(VelCfg* vcfg, int32_t nl); //
int32_t pump_move_by_nl(VelCfg* vcfg, int32_t nl); //
int32_t pump_aspirate_plld(int32_t pressure_threshold); // plld,分配探测
int32_t pump_aspirate_plld_get_state(int32_t* detected);
@ -228,8 +228,8 @@ class SMTP2V2 {
int32_t pump_distribut_mlld(int32_t pumpv, int32_t c_threshold, int32_t pressure_threshold); //
int32_t pump_distribut_mlld_get_state(int32_t* detected);
int32_t pump_aspirate_nl(int32_t nl);
int32_t pump_distribut_nl(int32_t nl);
// int32_t pump_aspirate_nl(int32_t nl);
// int32_t pump_distribut_nl(int32_t nl);
int32_t pump_aspirate_and_verify(int32_t ul, int32_t eigen_time, int32_t p_thre, int32_t tolerance);

2
sdk/components/zcan_protocol_parser/zcan_protocol_parser.cpp

@ -962,7 +962,7 @@ int32_t ZCanProtocolParser::pipette_get_pmvcfg(cmdcontxt_t* cxt) {
}
int32_t ZCanProtocolParser::pipette_set_container_info(cmdcontxt_t* cxt) {
CHECK_AND_GET_MODULE(2);
CHECK_AND_GET_MODULE(3);
return module->pipette_set_container_info(cxt->params[0], (container_info_index_t)cxt->params[1], cxt->params[2]);
}

Loading…
Cancel
Save