From 08144f4736300ac2ef24324a4d7ccb2d3841f7ca Mon Sep 17 00:00:00 2001 From: zhaohe Date: Tue, 20 May 2025 21:31:03 +0800 Subject: [PATCH] update --- TODO.md | 6 + .../pipette_module/base/constant_cfg.hpp | 15 +- .../pipette_module/base/pipette_action_param.hpp | 20 +- sdk/components/pipette_module/base/pipette_cfg.hpp | 47 ++-- .../pipette_module/base/pipette_enum.hpp | 14 +- .../pipette_module/pipette_ctrl_module.cpp | 277 ++++++++++++++++++--- .../pipette_module/pipette_ctrl_module.hpp | 33 ++- 7 files changed, 336 insertions(+), 76 deletions(-) create mode 100644 TODO.md diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..a6ffa09 --- /dev/null +++ b/TODO.md @@ -0,0 +1,6 @@ +``` +步进电机的加速度换算是错的 + 现在的单位是:[1/60 r/s^2] + + +``` \ No newline at end of file diff --git a/sdk/components/pipette_module/base/constant_cfg.hpp b/sdk/components/pipette_module/base/constant_cfg.hpp index 01ce1c6..d47874d 100644 --- a/sdk/components/pipette_module/base/constant_cfg.hpp +++ b/sdk/components/pipette_module/base/constant_cfg.hpp @@ -6,12 +6,13 @@ * 配置份数 * ***********************************************************************************************************************/ -#define PM_BCFG_CPY_NUM 1 -#define PLATINFO_CPY_NUM 1 -#define ZM_BCFG_CPY_NUM 1 +#define PM_BCFG_CPY_NUM 1 +#define ZM_BCFG_CPY_NUM 1 -#define ZM_VCFG_CPY_NUM 20 -#define PM_VCFG_CPY_NUM 20 +#define PLATINFO_CPY_NUM 5 -#define CONTAINER_INFO_CPY_NUM 15 -#define LIQUID_INFO_CPY_NUM 10 +#define ZM_VCFG_CPY_NUM 10 +#define PM_VCFG_CPY_NUM 10 + +#define CONTAINER_INFO_CPY_NUM 15 +#define LIQUID_INFO_CPY_NUM 10 diff --git a/sdk/components/pipette_module/base/pipette_action_param.hpp b/sdk/components/pipette_module/base/pipette_action_param.hpp index f708006..6ddb92c 100644 --- a/sdk/components/pipette_module/base/pipette_action_param.hpp +++ b/sdk/components/pipette_module/base/pipette_action_param.hpp @@ -10,6 +10,7 @@ typedef struct { // // 参数索引 // + int32_t platinfo_index; // 平台配置索引 int32_t container_info_index; // 容器配置索引 int32_t liquid_cfg_index; // 液体配置索引 // @@ -43,25 +44,26 @@ typedef enum { // // 参数索引 // - kaspiration_paramid_container_info_index = 1, - kaspiration_paramid_liquid_cfg_index = 2, + kaspiration_paramid_platinfo_index = 1, + kaspiration_paramid_container_info_index = 2, + kaspiration_paramid_liquid_cfg_index = 3, // // 吸取模式 // - kaspiration_paramid_aspiration_mode = 3, + kaspiration_paramid_aspiration_mode = 4, // // lld配置 // - kaspiration_paramid_lld_type = 4, - kaspiration_paramid_lld_enable_protect = 5, + kaspiration_paramid_lld_type = 5, + kaspiration_paramid_lld_enable_protect = 6, // // llf配置 // - kaspiration_paramid_mix_llf_enable = 6, - kaspiration_paramid_llf_enable = 7, + kaspiration_paramid_mix_llf_enable = 7, + kaspiration_paramid_llf_enable = 8, // // 混匀配置 // - kaspiration_paramid_mix_volume = 8, - kaspiration_paramid_mix_times = 9, + kaspiration_paramid_mix_volume = 9, + kaspiration_paramid_mix_times = 10, } aspiration_paramid_t; \ No newline at end of file diff --git a/sdk/components/pipette_module/base/pipette_cfg.hpp b/sdk/components/pipette_module/base/pipette_cfg.hpp index a6d19c1..1c0099d 100644 --- a/sdk/components/pipette_module/base/pipette_cfg.hpp +++ b/sdk/components/pipette_module/base/pipette_cfg.hpp @@ -4,23 +4,36 @@ * 平台参数 * ***********************************************************************************************************************/ typedef struct { - int32_t zm_ref_level; // 移液枪带上tip后,参考面高度(绝对位置0.1mm),建议选择一个大部分操作都在其之上的平面 - int32_t tip_picking_pos; // 开始取tip位置(绝对位置0.1mm) - int32_t tip_picking_max_pos; // 结束取tip位置(绝对位置0.1mm) - int32_t tip_deposit_pos; // 丢tip位置(绝对位置0.1mm) - int32_t transform_pos; // 移液枪安全移动的高度(绝对位置0.1mm) - int32_t tip_type; // tip类型 - int32_t tip_length; // tip长度 + /** + * @brief 工作参考平面 + * + */ + int32_t work_ref_plane; // 移液枪带上tip后,tip刚好与平面接触时候,z轴的坐标,后续系统中非特殊情况,所有坐标参考这个坐标 + + int32_t tip_picking_pos; // 开始取tip位置(参考位0.1mm) + int32_t tip_picking_search_range; // 取tip的范围 + int32_t tip_deposit_pos; // 丢tip位置(参考位0.1mm) + // int32_t transform_pos; // 移液枪安全移动的高度(参考位0.1mm) + /** + * @brief tip类型 + * + * TS1000UL = 0, // 1000ul, max=1002.6ul + * TS200UL = 1, // 200ul, max=250ul + * TS50UL = 2, // 50ul, max=62ul + * TS20UL = 3, // 20ul, max=40ul + */ + int32_t tip_type; + int32_t tip_length; // tip长度 } platinfo_t; typedef enum { - kplatinfo_zm_ref_level = 100, - kplatinfo_tip_picking_pos = 101, - kplatinfo_tip_picking_max_pos = 102, - kplatinfo_tip_deposit_pos = 103, - kplatinfo_transform_pos = 104, - kplatinfo_tip_type = 105, - kplatinfo_tip_length = 106, + kplatinfo_work_ref_plane = 100, + kplatinfo_tip_picking_pos = 101, + kplatinfo_tip_picking_search_range = 102, + kplatinfo_tip_deposit_pos = 103, + // kplatinfo_transform_pos = 104, + kplatinfo_tip_type = 105, + kplatinfo_tip_length = 106, } platinfo_index_t; /*********************************************************************************************************************** @@ -103,11 +116,11 @@ typedef enum { * 移液枪速度配置 * ***********************************************************************************************************************/ typedef struct { - int32_t acc; // 加速度 level 1…20 default:14 1:797 nl/s^2 ... 20:797*20 nl/s^2 + int32_t acc; // 加速度 level 1…20 default:14 1:797.5 ul/s^2 ... 20:797*20 nl/s^2 int32_t dec; // 减速度 level 1…20 default:14 int32_t vstart; // 启动速度 ul/s (0...319) - int32_t vstop; // 停止速度 nl/s (0...319) - int32_t vmax; // 最大速度 nl/s (0...2552) + int32_t vstop; // 停止速度 ul/s (0...319) + int32_t vmax; // 最大速度 ul/s (0...2552) } pm_vcfg_t; typedef enum { diff --git a/sdk/components/pipette_module/base/pipette_enum.hpp b/sdk/components/pipette_module/base/pipette_enum.hpp index 499ce1f..e4f421d 100644 --- a/sdk/components/pipette_module/base/pipette_enum.hpp +++ b/sdk/components/pipette_module/base/pipette_enum.hpp @@ -3,12 +3,14 @@ * 泵机预设速度配置 * ***********************************************************************************************************************/ typedef enum { - kpm_v_default = 0, // 默认速度 - kpm_v_min = 1, // 最低速 - kpm_v_slow = 2, // 慢速 - kpm_v_mid = 3, // 中速 - kpm_v_quick = 4, // 快速 - kpm_v_max = 5, // 高速 + kpm_v_default = 0, // 默认速度 + kpm_v_slow_lv1 = 1, // 慢速 + kpm_v_slow_lv2 = 2, // 慢速 + kpm_v_slow_lv3 = 3, // 慢速 + kpm_v_mid = 4, // 中速 + kpm_v_quick = 5, // 快速 + kpm_v_max = 6, // 高速 + kpm_v_lld = 7, // 液面探测vlld } pm_vindex_t; /*********************************************************************************************************************** diff --git a/sdk/components/pipette_module/pipette_ctrl_module.cpp b/sdk/components/pipette_module/pipette_ctrl_module.cpp index ff3a55a..5f7fc7a 100644 --- a/sdk/components/pipette_module/pipette_ctrl_module.cpp +++ b/sdk/components/pipette_module/pipette_ctrl_module.cpp @@ -28,8 +28,10 @@ void PipetteModule::initialize(int32_t id, hardward_config_t *hardwaredcfg) { / m_zm->getGState(); // 读取状态,清空下复位标识 + //! TODO: 将初始化代码移动到模块外部 m_piette_gun_io1.initAsInput(PB1, ZGPIO::kMode_pullup, ZGPIO::kIRQ_noIrq, true); // lld输入高 + //! 测试IO1是否联通 m_smtp2.pump_set_io1_mode(2); // lld输入高 m_smtp2.pump_set_io1_state(0); osDelay(100); @@ -39,7 +41,8 @@ void PipetteModule::initialize(int32_t id, hardward_config_t *hardwaredcfg) { / osDelay(100); ZLOGI(TAG, "read io1 state:%d", m_piette_gun_io1.getState()); m_smtp2.pump_set_io1_mode(0); // lld输入高 - // m_smtp2.dumpparam(); + + parameter_init(); } int32_t PipetteModule::module_stop() { @@ -117,15 +120,22 @@ int32_t PipetteModule::pipette_get_pmbcfg(pm_bcfg_index_t index, int32_t *val) { } return 0; } -int32_t PipetteModule::pipette_set_platinfo(platinfo_index_t index, int32_t val) { +int32_t PipetteModule::pipette_set_platinfo(int32_t cpyid, platinfo_index_t index, int32_t val) { + if (cpyid < 0 || cpyid >= ARRARY_SIZE(m_platinfo)) { + ZLOGE(TAG, "pipette_set_platinfo cpyid %d out of range", cpyid); + return err::kparam_out_of_range; + } + + platinfo_t *platinfo = &m_platinfo[cpyid]; + switch (index) { - SET_CFG(kplatinfo_zm_ref_level, m_platform_info.zm_ref_level, val); - SET_CFG(kplatinfo_tip_picking_pos, m_platform_info.tip_picking_pos, val); - SET_CFG(kplatinfo_tip_picking_max_pos, m_platform_info.tip_picking_max_pos, val); - SET_CFG(kplatinfo_tip_deposit_pos, m_platform_info.tip_deposit_pos, val); - SET_CFG(kplatinfo_transform_pos, m_platform_info.transform_pos, val); - SET_CFG(kplatinfo_tip_type, m_platform_info.tip_type, val); - SET_CFG(kplatinfo_tip_length, m_platform_info.tip_length, val); + SET_CFG(kplatinfo_work_ref_plane, platinfo->work_ref_plane, val); + SET_CFG(kplatinfo_tip_picking_pos, platinfo->tip_picking_pos, val); + SET_CFG(kplatinfo_tip_picking_search_range, platinfo->tip_picking_search_range, val); + SET_CFG(kplatinfo_tip_deposit_pos, platinfo->tip_deposit_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); default: { ZLOGE(TAG, "pipette_set_platinfo index %d out of range", index); return err::kparam_out_of_range; @@ -133,15 +143,21 @@ int32_t PipetteModule::pipette_set_platinfo(platinfo_index_t index, int32_t val) } return 0; } -int32_t PipetteModule::pipette_get_platinfo(platinfo_index_t index, int32_t *val) { +int32_t PipetteModule::pipette_get_platinfo(int32_t cpyid, platinfo_index_t index, int32_t *val) { + if (cpyid < 0 || cpyid >= ARRARY_SIZE(m_platinfo)) { + ZLOGE(TAG, "pipette_get_platinfo cpyid %d out of range", cpyid); + return err::kparam_out_of_range; + } + + platinfo_t *platinfo = &m_platinfo[cpyid]; switch (index) { - GET_CFG(kplatinfo_zm_ref_level, m_platform_info.zm_ref_level, val); - GET_CFG(kplatinfo_tip_picking_pos, m_platform_info.tip_picking_pos, val); - GET_CFG(kplatinfo_tip_picking_max_pos, m_platform_info.tip_picking_max_pos, val); - GET_CFG(kplatinfo_tip_deposit_pos, m_platform_info.tip_deposit_pos, val); - GET_CFG(kplatinfo_transform_pos, m_platform_info.transform_pos, val); - GET_CFG(kplatinfo_tip_type, m_platform_info.tip_type, val); - GET_CFG(kplatinfo_tip_length, m_platform_info.tip_length, val); + GET_CFG(kplatinfo_work_ref_plane, platinfo->work_ref_plane, val); + GET_CFG(kplatinfo_tip_picking_pos, platinfo->tip_picking_pos, val); + GET_CFG(kplatinfo_tip_picking_search_range, platinfo->tip_picking_search_range, val); + GET_CFG(kplatinfo_tip_deposit_pos, platinfo->tip_deposit_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); default: { ZLOGE(TAG, "pipette_get_platinfo index %d out of range", index); return err::kparam_out_of_range; @@ -387,6 +403,13 @@ liquid_info_t *PipetteModule::get_liquid_info(int32_t index) { } return &m_liquid_info[index]; } +platinfo_t *PipetteModule::get_platinfo(int32_t index) { + if (index < 0 || index >= ARRARY_SIZE(m_platinfo)) { + ZLOGE(TAG, "get_platinfo index %d out of range", index); + return &m_platinfo[0]; + } + return &m_platinfo[index]; +} void PipetteModule::get_cfg_smart(int32_t index, zm_vcfg_t *cfg) { // zm_vcfg_t *cfg0 = get_zm_vcfg(0); @@ -538,8 +561,6 @@ int32_t PipetteModule::pipette_pump_init_device() { pump_apply_vcfg(kpm_v_max); // 默认配置 DO_IN_THREAD(m_smtp2.pump_init()); pump_waitfor_stop(); - DO_IN_THREAD(m_smtp2.pump_set_io1_mode(0)); // lld输入高 - DO_IN_THREAD(m_smtp2.pump_set_io2_mode(0)); // 通用输入 }); return 0; } @@ -618,12 +639,16 @@ int32_t PipetteModule::pipette_pump_aspirate() { if (pump_read_tip_state() == 0) { throw zapp_exception(err::kpipette_error_no_tip_when_lld); } + check_pipette_pump_aspirate_params(); + // 移液枪部分参数初始化 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)); // 通用输入 - platinfo_t *platform_info = &m_platform_info; aspiration_param_t *acfg = &m_aspiration_param; + platinfo_t *platform_info = get_platinfo(acfg->platinfo_index); liquid_info_t *liquidinfo = get_liquid_info(acfg->liquid_cfg_index); container_info_t *container_cfg = get_container_info(acfg->container_info_index); /*********************************************************************************************************************** @@ -633,7 +658,7 @@ int32_t PipetteModule::pipette_pump_aspirate() { if (acfg->lld_type != 0) { _do_lld(platform_info, container_cfg, liquidinfo, acfg); } else { - m_state.water_level = platform_info->zm_ref_level - container_cfg->container_neck_pos + container_cfg->fix_aspiration_depth; + m_state.water_level = platform_info->work_ref_plane - container_cfg->container_neck_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 @@ -650,12 +675,12 @@ void PipetteModule::_do_lld(platinfo_t *platform_info, container_info_t *contain ZLOGI(TAG, "start lld, lld_type %d lld_pm_vindex %d plld_threshold %d", acfg->lld_type, liquidinfo->plld_pm_vindex, liquidinfo->plld_threshold); // 移动到转移位置 - zm_move_to_block(platform_info->transform_pos, kzm_v_default, 0); + zm_move_to_block(0, kzm_v_default, 0); // 清空tip pump_move_to_x100nl_block(0, liquidinfo->empty_tip_pm_vindex); // 移动到瓶口 - zm_move_to_pr_block(platform_info, container_cfg->container_neck_pos + 50 /*5mm*/, // + zm_wp_move_to_block(platform_info, container_cfg->container_neck_pos + 50 /*5mm*/, // kzm_v_default, 0); pump_move_to_x100nl_block(0, kpm_v_default); // 回转一下,消除齿轮间隙 @@ -666,10 +691,10 @@ void PipetteModule::_do_lld(platinfo_t *platform_info, container_info_t *contain DO_IN_THREAD(m_smtp2.pump_aspirate_plld(liquidinfo->plld_threshold)); // 快速移动到瓶口 - zm_move_to_pr_block(platform_info, container_cfg->container_neck_pos + container_cfg->lld_start_search_depth, // + zm_wp_move_to_block(platform_info, container_cfg->container_neck_pos + container_cfg->lld_start_search_depth, // kzm_v_default, 0); // lld,zm移动到瓶底 - zm_move_to_pr(platform_info, container_cfg->container_neck_pos - container_cfg->container_depth, kzm_v_lld, 0); + zm_wp_move_to(platform_info, container_cfg->container_neck_pos - container_cfg->container_depth, kzm_v_lld, 0); /** * @brief 等待压力大于阈值 @@ -745,7 +770,7 @@ void PipetteModule::_do_sapirate(platinfo_t *platform_info, container_info_t *co 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_pr(platform_info, + zm_wp_move_to(platform_info, container_cfg->container_neck_pos - container_cfg->container_depth, // 瓶底 kzm_v_llf, // 基础速度配置 compute_zm_llf_vel(liquidinfo->mix_pm_vindex, container_cfg)); // 计算llf速度 @@ -771,7 +796,7 @@ void PipetteModule::_do_sapirate(platinfo_t *platform_info, container_info_t *co int32_t x100nl = acfg->x100nl * liquidinfo->volume_calibration_coefficient_k * 0.0001 + liquidinfo->volume_calibration_coefficient_b * 0.0001; if (acfg->llf_enable > 0) { - zm_move_to_pr(platform_info, // + zm_wp_move_to(platform_info, // container_cfg->container_neck_pos - container_cfg->container_depth, // 瓶底 kzm_v_llf, // compute_zm_llf_vel(aspiration_pm_index, container_cfg) // @@ -793,7 +818,7 @@ void PipetteModule::_do_sapirate(platinfo_t *platform_info, container_info_t *co } // z轴移动transform_pos - zm_move_to_block(platform_info->transform_pos, kzm_v_default, 0); + zm_move_to_block(0, kzm_v_default, 0); } int32_t PipetteModule::pipette_pump_distribu(int32_t distribu_cfg_index, int32_t n100nl /*0.1ul*/) { return 0; } @@ -865,15 +890,15 @@ void PipetteModule::zm_move_to_block(int32_t x, int32_t vbaseindex, int32_t vel) zm_move_to(x, vbaseindex, vel); zm_waitfor_stop(); } -void PipetteModule::zm_move_to_pr(platinfo_t *platform, int32_t x, int32_t vbaseindex, int32_t vel) { +void PipetteModule::zm_wp_move_to(platinfo_t *platform, int32_t x, int32_t vbaseindex, int32_t vel) { /** * @brief 以平台的参考位置为基准,向上为正向,向下为负向 */ - zm_move_to(platform->zm_ref_level - x, vbaseindex, vel); + zm_move_to(platform->work_ref_plane - x, vbaseindex, vel); } -void PipetteModule::zm_move_to_pr_block(platinfo_t *platform, int32_t x, int32_t vbaseindex, int32_t vel) { - zm_move_to_pr(platform, x, vbaseindex, vel); +void PipetteModule::zm_wp_move_to_block(platinfo_t *platform, int32_t x, int32_t vbaseindex, int32_t vel) { + zm_wp_move_to(platform, x, vbaseindex, vel); zm_waitfor_stop(); } @@ -922,6 +947,22 @@ void PipetteModule::zm_apply_vcfg(int32_t vbasecfgindex, int32_t vel) { m_zm->set_vstop(cfg.vstop); } +void PipetteModule::zm_sync_base_cfg() { + m_zm->enable(false); + m_zm->setMRES((mres_type_t)zm_base_cfg.mres); + m_zm->setIHOLD_IRUN(zm_base_cfg.ihold, zm_base_cfg.irun, zm_base_cfg.iholddelay); + m_zm->setScale(zm_base_cfg.one_circle_pulse); + m_zm->setScaleDenominator(zm_base_cfg.one_circle_pulse_denominator); + m_zm->setMotorShaft(zm_base_cfg.shaft); + m_zm->setGlobalScale(zm_base_cfg.iglobalscaler); + m_zm->set_tzerowait(zm_base_cfg.tzerowait); + m_zm->set_enc_resolution(zm_base_cfg.enc_resolution); + zm_apply_vcfg(kzm_v_default, 0); + if (m_state.enable) { + m_zm->enable(true); + } +} + void PipetteModule::zm_waitfor_zm0p_trigger_and_stop_motor() { while (!zm0p_is_trigger()) { if (m_zm->isStoped()) { @@ -1188,3 +1229,175 @@ void PipetteModule::thread_start_work(const char *fnname, function fn) { ZLOGI(TAG, "<- end work"); }); } + +void PipetteModule::check_platinfo_cpyid(int32_t cpyid) { + if (cpyid < 0 || cpyid >= ARRARY_SIZE(m_platinfo)) { + ZLOGE(TAG, "pipette_get_container_info cpyid %d out of range", cpyid); + throw zapp_exception(err::kparam_out_of_range); + } +} +void PipetteModule::check_zmvcfg_cpyid(int32_t cpyid) { + if (cpyid < 0 || cpyid >= ARRARY_SIZE(m_zm_vcfg)) { + ZLOGE(TAG, "pipette_get_zmvcfg cpyid %d out of range", cpyid); + throw zapp_exception(err::kparam_out_of_range); + } +} +void PipetteModule::check_pmvcfg_cpyid(int32_t cpyid) { + if (cpyid < 0 || cpyid >= ARRARY_SIZE(m_pm_vcfg)) { + ZLOGE(TAG, "pipette_get_pmvcfg cpyid %d out of range", cpyid); + throw zapp_exception(err::kparam_out_of_range); + } +} +void PipetteModule::check_container_info_cpyid(int32_t cpyid) { + if (cpyid < 0 || cpyid >= ARRARY_SIZE(m_container_info)) { + ZLOGE(TAG, "pipette_get_container_info cpyid %d out of range", cpyid); + throw zapp_exception(err::kparam_out_of_range); + } +} +void PipetteModule::check_liquid_info_cpyid(int32_t cpyid) { + if (cpyid < 0 || cpyid >= ARRARY_SIZE(m_liquid_info)) { + ZLOGE(TAG, "pipette_get_liquid_info cpyid %d out of range", cpyid); + throw zapp_exception(err::kparam_out_of_range); + } +} + +void PipetteModule::check_pipette_pump_aspirate_params() { + aspiration_param_t *acfg = &m_aspiration_param; + + if (acfg->x100nl < 0) { + ZLOGE(TAG, "pipette_pump_aspirate_set_param x100nl %d out of range", acfg->x100nl); + throw zapp_exception(err::kparam_out_of_range); + } + check_platinfo_cpyid(acfg->platinfo_index); + check_container_info_cpyid(acfg->container_info_index); + check_liquid_info_cpyid(acfg->liquid_cfg_index); +} + +void PipetteModule::parameter_init() { + /*********************************************************************************************************************** + * zm_base_cfg * + ***********************************************************************************************************************/ + zm_base_cfg.shaft = 0; // Z轴电机运动方向调整 + zm_base_cfg.one_circle_pulse = 80; // 电子齿轮比-分子 + zm_base_cfg.one_circle_pulse_denominator = 1; // 电子齿轮比-分母 + zm_base_cfg.ihold = 7; // + zm_base_cfg.irun = 7; // + zm_base_cfg.iholddelay = 10; // + zm_base_cfg.iglobalscaler = 0; // + zm_base_cfg.min_d = 0; // + zm_base_cfg.max_d = 0; // + zm_base_cfg.tzerowait = 0; // + zm_base_cfg.enc_resolution = 0; // + zm_base_cfg.enable_enc = 0; // + zm_base_cfg.dzero = 92; // + zm_base_cfg.io_trigger_append_distance = 20; // + zm_base_cfg.pos_devi_tolerance = 20; // + zm_base_cfg.mres = 0; // + /*********************************************************************************************************************** + * pm_base_cfg * + ***********************************************************************************************************************/ + pm_base_cfg.pad = 0; + + /*********************************************************************************************************************** + * m_platinfo * + ***********************************************************************************************************************/ + for (int32_t i = 0; i < ARRARY_SIZE(m_platinfo); i++) { + m_platinfo[i].work_ref_plane = 0; + m_platinfo[i].tip_picking_pos = 0; + m_platinfo[i].tip_picking_search_range = 0; + m_platinfo[i].tip_deposit_pos = 0; + // m_platinfo[i].transform_pos = 0; // + m_platinfo[i].tip_type = smtp2::TS200UL; + m_platinfo[i].tip_length = 500; // 50mm + } + + /*********************************************************************************************************************** + * m_zm_vcfg * + ***********************************************************************************************************************/ + for (int32_t i = 0; i < ARRARY_SIZE(m_zm_vcfg); i++) { + m_zm_vcfg[i].vstart = -1; + m_zm_vcfg[i].a1 = -1; + m_zm_vcfg[i].amax = -1; + m_zm_vcfg[i].v1 = -1; + m_zm_vcfg[i].dmax = -1; + m_zm_vcfg[i].d1 = -1; + m_zm_vcfg[i].vstop = -1; + m_zm_vcfg[i].vmax = -1; + } + + m_zm_vcfg[kzm_v_default].vstart = 100; + m_zm_vcfg[kzm_v_default].a1 = 10; + m_zm_vcfg[kzm_v_default].amax = 50; + m_zm_vcfg[kzm_v_default].v1 = 300; + m_zm_vcfg[kzm_v_default].dmax = 50; + m_zm_vcfg[kzm_v_default].d1 = 10; + m_zm_vcfg[kzm_v_default].vstop = 100; + m_zm_vcfg[kzm_v_default].vmax = 1200; + + m_zm_vcfg[kzm_v_move_to_zero].vmax = 600; + m_zm_vcfg[kzm_v_look_zero_edge].vmax = 100; + m_zm_vcfg[kzm_v_lld].vmax = 600; + m_zm_vcfg[kzm_v_swap].vmax = 300; + m_zm_vcfg[kzm_v_llf].vmax = 500; + + /*********************************************************************************************************************** + * m_pm_vcfg * + ***********************************************************************************************************************/ + + for (int32_t i = 0; i < ARRARY_SIZE(m_pm_vcfg); i++) { + m_pm_vcfg[i].acc = 1; + m_pm_vcfg[i].dec = 1; + m_pm_vcfg[i].vstart = 0; + m_pm_vcfg[i].vstop = 0; + m_pm_vcfg[i].vmax = 2500; + } + + m_pm_vcfg[kpm_v_default].vmax = 2500; + m_pm_vcfg[kpm_v_slow_lv1].vmax = 5; + m_pm_vcfg[kpm_v_slow_lv2].vmax = 10; + m_pm_vcfg[kpm_v_slow_lv3].vmax = 50; + m_pm_vcfg[kpm_v_mid].vmax = 1000; + m_pm_vcfg[kpm_v_quick].vmax = 2000; + m_pm_vcfg[kpm_v_max].vmax = 2500; + m_pm_vcfg[kpm_v_lld].vmax = 100; + + /*********************************************************************************************************************** + * m_container_info * + ***********************************************************************************************************************/ + + for (int32_t i = 0; i < ARRARY_SIZE(m_container_info); i++) { + m_container_info[i].container_type = 0; + m_container_info[i].container_neck_pos = 0; + m_container_info[i].container_depth = 0; + m_container_info[i].container_round = 0; + m_container_info[i].container_bottom_section_height = 0; + m_container_info[i].immersion_depth = 0; + m_container_info[i].leaving_height = 150; + m_container_info[i].jet_height = 0; + } + + /*********************************************************************************************************************** + * m_liquid_info * + ***********************************************************************************************************************/ + + for (int32_t i = 0; i < ARRARY_SIZE(m_liquid_info); i++) { + m_liquid_info[i].plld_pm_vindex = kpm_v_lld; + m_liquid_info[i].plld_threshold = 30; + m_liquid_info[i].empty_tip_pm_vindex = kpm_v_max; + m_liquid_info[i].blowout_air_volume = 0; + m_liquid_info[i].blowout_air_pm_vindex = kpm_v_quick; + m_liquid_info[i].over_aspirated_volume = 100; // 100(x100nl) == 10ul + m_liquid_info[i].over_aspirated_pm_vindex = kpm_v_slow_lv2; + m_liquid_info[i].aspiration_pm_vindex_low = kpm_v_slow_lv1; + m_liquid_info[i].aspiration_pm_vindex_high = kpm_v_slow_lv3; + m_liquid_info[i].aspiration_volume_break_val = 500; // 500(x100nl) == 50ul + m_liquid_info[i].volume_calibration_coefficient_b = 1.0f; + m_liquid_info[i].volume_calibration_coefficient_k = 1.0f; + m_liquid_info[i].settling_time = 1000; // ms + m_liquid_info[i].transport_volume = 50; // 50(x100nl) == 5ul + m_liquid_info[i].transport_volume_pm_vindex = kpm_v_slow_lv2; + m_liquid_info[i].mix_pm_vindex = kpm_v_max; + } + + zm_sync_base_cfg(); +} diff --git a/sdk/components/pipette_module/pipette_ctrl_module.hpp b/sdk/components/pipette_module/pipette_ctrl_module.hpp index 6e7a644..8f78f40 100644 --- a/sdk/components/pipette_module/pipette_ctrl_module.hpp +++ b/sdk/components/pipette_module/pipette_ctrl_module.hpp @@ -70,7 +70,8 @@ class PipetteModule : public ZIModule { zm_bcfg_t zm_base_cfg; pump_bcfg_t pm_base_cfg; - platinfo_t m_platform_info; + + platinfo_t m_platinfo[PLATINFO_CPY_NUM]; zm_vcfg_t m_zm_vcfg[ZM_VCFG_CPY_NUM]; pm_vcfg_t m_pm_vcfg[PM_VCFG_CPY_NUM]; @@ -103,16 +104,22 @@ class PipetteModule : public ZIModule { virtual int32_t pipette_set_zmbcfg(zm_bcfg_index_t index, int32_t val); virtual int32_t pipette_get_zmbcfg(zm_bcfg_index_t index, int32_t *val); + virtual int32_t pipette_set_pmbcfg(pm_bcfg_index_t index, int32_t val); virtual int32_t pipette_get_pmbcfg(pm_bcfg_index_t index, int32_t *val); - virtual int32_t pipette_set_platinfo(platinfo_index_t index, int32_t val); - virtual int32_t pipette_get_platinfo(platinfo_index_t index, int32_t *val); + + virtual int32_t pipette_set_platinfo(int32_t cpyid, platinfo_index_t index, int32_t val); + virtual int32_t pipette_get_platinfo(int32_t cpyid, platinfo_index_t index, int32_t *val); + virtual int32_t pipette_set_zmvcfg(int32_t cpyid, zm_vcfg_index_t index, int32_t val); virtual int32_t pipette_get_zmvcfg(int32_t cpyid, zm_vcfg_index_t index, int32_t *val); + virtual int32_t pipette_set_pmvcfg(int32_t cpyid, pm_vcfg_index_t index, int32_t val); virtual int32_t pipette_get_pmvcfg(int32_t cpyid, pm_vcfg_index_t index, int32_t *val); + virtual int32_t pipette_set_container_info(int32_t cpyid, container_info_index_t index, int32_t val); virtual int32_t pipette_get_container_info(int32_t cpyid, container_info_index_t index, int32_t *val); + virtual int32_t pipette_set_liquid_info(int32_t cpyid, liquid_info_index_t index, int32_t val); virtual int32_t pipette_get_liquid_info(int32_t cpyid, liquid_info_index_t index, int32_t *val); @@ -165,8 +172,8 @@ class PipetteModule : public ZIModule { void zm_move_to(int32_t x, int32_t vbaseindex, int32_t vel); void zm_move_to_block(int32_t x, int32_t vbaseindex, int32_t vel); - void zm_move_to_pr(platinfo_t *platform, int32_t x, int32_t vbaseindex, int32_t vel); - void zm_move_to_pr_block(platinfo_t *platform, int32_t x, int32_t vbaseindex, int32_t vel); + void zm_wp_move_to(platinfo_t *platform, int32_t x, int32_t vbaseindex, int32_t vel); + void zm_wp_move_to_block(platinfo_t *platform, int32_t x, int32_t vbaseindex, int32_t vel); void zm_move_by(int32_t dx, int32_t vindex, int32_t vel); void zm_stop(); void zm_move_to_end(int32_t direction, int32_t vindex); @@ -177,6 +184,7 @@ class PipetteModule : public ZIModule { bool zm0p_is_trigger(); void zm_apply_vcfg(int32_t vbasecfgindex, int32_t vel); + void zm_sync_base_cfg(); void zm_waitfor_zm0p_trigger_and_stop_motor(); void zm_waitfor_zm0p_not_trigger_and_stop_motor(); @@ -207,6 +215,7 @@ class PipetteModule : public ZIModule { pm_vcfg_t *get_pm_vcfg(int32_t index); container_info_t *get_container_info(int32_t index); liquid_info_t *get_liquid_info(int32_t index); + platinfo_t *get_platinfo(int32_t index); void get_cfg_smart(int32_t index, zm_vcfg_t *cfg); void get_cfg_smart(int32_t index, pm_vcfg_t *cfg); @@ -222,5 +231,19 @@ class PipetteModule : public ZIModule { void runingcheck(); void thread_delay(int32_t delayms); void thread_start_work(const char *fnname, function fn); + + /*********************************************************************************************************************** + * CHECK * + ***********************************************************************************************************************/ + + void check_platinfo_cpyid(int32_t cpyid); + void check_zmvcfg_cpyid(int32_t cpyid); + void check_pmvcfg_cpyid(int32_t cpyid); + void check_container_info_cpyid(int32_t cpyid); + void check_liquid_info_cpyid(int32_t cpyid); + + void check_pipette_pump_aspirate_params(); + + void parameter_init(); }; } // namespace iflytop