From a43a3cadc50a1813971c910c9d1231d5cc5d8ad1 Mon Sep 17 00:00:00 2001 From: zhaohe Date: Sun, 1 Jun 2025 17:03:29 +0800 Subject: [PATCH] add action delay --- sdk/components/pipette_module/base/pipette_cfg.hpp | 11 ++++--- .../pipette_module/pipette_ctrl_module.cpp | 34 +++++++++++++++------- .../pipette_module/pipette_ctrl_module.hpp | 2 ++ .../pipette_module/pipette_ctrl_module_pm_ctrl.cpp | 8 ++--- .../pipette_module/pipette_ctrl_module_utils.cpp | 6 ++++ sdk/components/sensors/smtp2_v2/smtp2_v2.cpp | 19 ++++++++---- sdk/components/sensors/smtp2_v2/smtp2_v2.hpp | 1 + 7 files changed, 56 insertions(+), 25 deletions(-) diff --git a/sdk/components/pipette_module/base/pipette_cfg.hpp b/sdk/components/pipette_module/base/pipette_cfg.hpp index ab7e0db..913089a 100644 --- a/sdk/components/pipette_module/base/pipette_cfg.hpp +++ b/sdk/components/pipette_module/base/pipette_cfg.hpp @@ -16,20 +16,23 @@ typedef struct { int32_t pressure_record_enable; - int32_t platform_info_cpyid; // 平台信息的副本ID + int32_t platform_info_cpyid; // 平台信息的副本ID + int32_t each_action_delay_time; // 每个动作之间的延时,单位ms (动作调试使用) int32_t max; } common_cfg_t; typedef enum { kpipette_common_cfg_pressure_record_enable, - kpipette_common_cfg_platform_info_cpyid, // 平台信息的副本ID + kpipette_common_cfg_platform_info_cpyid, // 平台信息的副本ID + kpipette_common_cfg_each_action_delay_time, // 每个动作之间的延时,单位ms (动作调试使用) kpipette_common_cfg_max, } pipette_common_cfg_index_t; static inline const char *common_cfg_index_to_string(pipette_common_cfg_index_t index) { switch (index) { CASE_ENUM_TO_STRING(kpipette_common_cfg_pressure_record_enable) - CASE_ENUM_TO_STRING(kpipette_common_cfg_platform_info_cpyid) // 平台信息的副本ID + CASE_ENUM_TO_STRING(kpipette_common_cfg_platform_info_cpyid) // 平台信息的副本ID + CASE_ENUM_TO_STRING(kpipette_common_cfg_each_action_delay_time) // 每个动作之间的延时,单位ms (动作调试使用) CASE_ENUM_TO_STRING(kpipette_common_cfg_max) } return "unknown"; @@ -309,7 +312,7 @@ static inline const char *container_info_index_to_string(container_info_index_t CASE_ENUM_TO_STRING(kcontainer_info_fix_water_level_depth) CASE_ENUM_TO_STRING(kcontainer_info_llf_vconvert_coneff) CASE_ENUM_TO_STRING(kcontainer_info_pierce_depth) - CASE_ENUM_TO_STRING(kcontainer_info_lld_end_pos_margin) + CASE_ENUM_TO_STRING(kcontainer_info_lld_end_pos_margin) CASE_ENUM_TO_STRING(kcontainer_info_mark) } return "unknown"; diff --git a/sdk/components/pipette_module/pipette_ctrl_module.cpp b/sdk/components/pipette_module/pipette_ctrl_module.cpp index a11c7aa..20c2e61 100644 --- a/sdk/components/pipette_module/pipette_ctrl_module.cpp +++ b/sdk/components/pipette_module/pipette_ctrl_module.cpp @@ -26,6 +26,9 @@ void PipetteModule::initialize(int32_t id, hardward_config_t *hardwaredcfg) { / m_piette_gun_io1.initAsInput(hardwaredcfg->IO1, ZGPIO::kMode_pullup, ZGPIO::kIRQ_noIrq, hardwaredcfg->IO1Mirror); // 设置泵机压力数据流走232 + // m_smtp2.pump_reset(); + osDelay(1000); + // m_smtp2.sendcmd_direct("/1f0R\r"); m_smtp2.pump_set_pressure_data_stream_port(1); // 测试泵机连接性 test_connectivity(); @@ -38,18 +41,12 @@ void PipetteModule::initialize(int32_t id, hardward_config_t *hardwaredcfg) { / ZLOGI(TAG, "pipette gun version:%s", m_smtp2.pump_read_version()); // 上报压力流 ! 不能一直打开压力流,一直打开压力流,会导致SMTP2无法响应其他命令 - // m_smtp2.pump_init(); - // while (true) { - // int32_t isbusy = 1; - // m_smtp2.pump_get_state(&isbusy); - // if (isbusy == 0) break; - // osDelay(10); - // } - // m_smtp2.sendcmd_direct("/1f1+300A1250R\r"); - + // m_smtp2.sendcmd_direct("/1f1f0R\r"); ZASSERT(hardwaredcfg->uart232); EXHAL_UART_BindUart("pipette-uart232", hardwaredcfg->uart232); - EXHAL_UART_RegListener(hardwaredcfg->uart232, [this](UART_HandleTypeDef *huart, uint8_t *data, size_t len) { smtpPressureStreamProcesser.process_rx(data[0]); }); + EXHAL_UART_RegListener(hardwaredcfg->uart232, [this](UART_HandleTypeDef *huart, uint8_t *data, size_t len) { // + smtpPressureStreamProcesser.process_rx(data[0]); + }); EXHAL_UART_ITStartAutoReadOneByte(hardwaredcfg->uart232); } @@ -415,7 +412,7 @@ int32_t PipetteModule::pipette_pump_aspirate() { } else { m_state.water_level = acfg->container_pos + container_cfg->fix_water_level_depth; // 没有使用lld,使用固定深度 } - + action_delay(); if (acfg->volumeX100nl != 0) { //! WARNING: 这里强制设置tip类型为200ul DO_IN_THREAD(m_smtp2.pump_set_tip_type(smtp2::TS200UL)); @@ -446,10 +443,12 @@ void PipetteModule::_do_lld(int32_t container_pos, platinfo_t *platform_info, co ZLOGI(TAG, "-->empty tip before lld"); pump_move_to_x100nl_block(0, liquidinfo->empty_tip_pm_vcpyid); pump_move_to_x100nl_block(300 /*30ul*/, kpm_v_max); // 为lld清空tip,提供一定空气柱 + action_delay(); // 移动到瓶口 ZLOGI(TAG, "-->zm move to container neck pos"); zm_move_to_block(container_pos - 50 /*5mm*/, kzm_v_default, 0); + action_delay(); // 启动lld ZLOGI(TAG, "-->start lld, lld_pm_vindex %d plld_threshold %d", liquidinfo->plld_pm_vcpyid, liquidinfo->plld_threshold); @@ -595,6 +594,7 @@ void PipetteModule::_do_sapirate(platinfo_t *platform_info, container_info_t *co // 清空tip ZLOGI(TAG, "clean tip."); pump_move_to_x100nl_block(0, liquidinfo->empty_tip_pm_vcpyid); + action_delay(); // 吸入过量的空气 if (liquidinfo->blowout_air_volume > 0) { @@ -610,6 +610,7 @@ void PipetteModule::_do_sapirate(platinfo_t *platform_info, container_info_t *co ZLOGI(TAG, "--> aspirate blowout_air_volume volume=%d, pm_vcpyid=%d", blowout_air_volume); pump_move_to_x100nl_block(blowout_air_volume, liquidinfo->blowout_air_pm_vcpyid); + action_delay(); } else { ZLOGI(TAG, "--> aspirate blowout_air_volume volume=0,skip"); } @@ -622,7 +623,9 @@ void PipetteModule::_do_sapirate(platinfo_t *platform_info, container_info_t *co if (liquidinfo->over_aspirated_volume > 0) { 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); + action_delay(); pump_move_by_x100nl_block(-liquidinfo->over_aspirated_volume, liquidinfo->over_aspirated_pm_vcpyid); + action_delay(); } // 吸入前混匀 @@ -644,6 +647,7 @@ void PipetteModule::_do_sapirate(platinfo_t *platform_info, container_info_t *co pump_move_by_x100nl_block(-acfg->mix_volume, liquidinfo->mix_pm_vcpyid); if (acfg->mix_llf_enable > 0) zm_stop(); } + action_delay(); } else { ZLOGI(TAG, "--> aspirate mix_volume volume=0,skip"); } @@ -672,12 +676,14 @@ void PipetteModule::_do_sapirate(platinfo_t *platform_info, container_info_t *co // 离开液面 ZLOGI(TAG, "--> leave liquid surface"); zm_move_to_leaving_height_pos_block(-1, m_state.water_level, container_cfg, kzm_v_swap_out, 0); // 移动到液面之上 + action_delay(); // 吸入过量的空气 if (liquidinfo->transport_volume > 0) { 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); } + action_delay(); } int32_t PipetteModule::pipette_pump_distribu_all_set_param(distribu_all_paramid_t param, int32_t val) { if (param < 0 || param >= kdistribu_all_paramid_max) { @@ -770,21 +776,25 @@ int32_t PipetteModule::pipette_pump_distribu_all() { } else { ZLOGI(TAG, "-->clean transport volume,skip"); } + action_delay(); // 缓慢移动到液面之下 ZLOGI(TAG, "-->move to below the liquid surface"); zm_move_to_immersion_pos_block(container_pos, -1, container_cfg, kzm_v_swap_in, 0); // 缓慢移动到液面之下 + action_delay(); // 分液 ZLOGI(TAG, "-->distribu liquid"); int32_t distribu_volume = calibrate_liquid_volume(liquidInGuninfo, m_pump_gun_state.liquid_volume); pump_move_by_x100nl_block(-distribu_volume, liquidInGuninfo->distribu_pm_vpyid); // 分液 + action_delay(); // 移动到swap位置,快速清空tip,使用(emptyTip速度) ZLOGI(TAG, "-->move to swap position and clean tip"); zm_move_to_leaving_height_pos_block(container_pos, -1, container_cfg, kzm_v_swap_out, 0); // 移动到swap位置 pump_move_to_x100nl_block(0, liquidInGuninfo->empty_tip_pm_vcpyid); // 快速清空tip,使用(emptyTip速度) + action_delay(); } // @@ -801,12 +811,14 @@ int32_t PipetteModule::pipette_pump_distribu_all() { } zm_move_to_leaving_height_pos_block(container_pos, -1, container_cfg, kzm_v_swap_out, 0); // 离开液面 + action_delay(); } else { ZLOGI(TAG, "-->skip mixing"); } // 吸入10ul过量的空气,防挂液 pump_move_by_x100nl_block(100, liquidInGuninfo->transport_volume_pm_vcpyid); + action_delay(); // // 如果需要归零,则移动到transform_pos // diff --git a/sdk/components/pipette_module/pipette_ctrl_module.hpp b/sdk/components/pipette_module/pipette_ctrl_module.hpp index 191cca1..fa2a7f8 100644 --- a/sdk/components/pipette_module/pipette_ctrl_module.hpp +++ b/sdk/components/pipette_module/pipette_ctrl_module.hpp @@ -252,6 +252,8 @@ class PipetteModule : public ZIModule { void dump(const char *title, aspiration_param_t *param); void dump(const char *title, distribu_all_param_t *param); + void action_delay(); + private: /*********************************************************************************************************************** * STATE * diff --git a/sdk/components/pipette_module/pipette_ctrl_module_pm_ctrl.cpp b/sdk/components/pipette_module/pipette_ctrl_module_pm_ctrl.cpp index 7dfa8cf..d80a428 100644 --- a/sdk/components/pipette_module/pipette_ctrl_module_pm_ctrl.cpp +++ b/sdk/components/pipette_module/pipette_ctrl_module_pm_ctrl.cpp @@ -48,9 +48,9 @@ void PipetteModule::pump_move_to_x100nl_block(double x100nl, int32_t vcfgcpyid, int32_t diff_pos = 0; for (size_t i = 0; i < 4; i++) { int32_t vcpyid = vcfgcpyid; - if (i != 0) { - vcpyid = kpm_v_slow_lv1; - } + // if (i != 0) { + // vcpyid = kpm_v_slow_lv1; + // } _pump_move_to_x100nl(x100nl, vcpyid); pump_waitfor_stop(); @@ -59,7 +59,7 @@ void PipetteModule::pump_move_to_x100nl_block(double x100nl, int32_t vcfgcpyid, diff_pos = targetpos - after_pos; if (diff) *diff = diff_pos; ZLOGI(TAG, "pump target %d nl, now pos %d nl diff %d", targetpos, after_pos, diff_pos); - if (abs(diff_pos) > 80) { + if (abs(diff_pos) > 100) { ZLOGW(TAG, "pump move to x100nl %d failed, diff is too large retrying...", x100nl); continue; } diff --git a/sdk/components/pipette_module/pipette_ctrl_module_utils.cpp b/sdk/components/pipette_module/pipette_ctrl_module_utils.cpp index a007b86..c031c0b 100644 --- a/sdk/components/pipette_module/pipette_ctrl_module_utils.cpp +++ b/sdk/components/pipette_module/pipette_ctrl_module_utils.cpp @@ -211,3 +211,9 @@ void PipetteModule::adjust_container_pos(int32_t *container_pos, int32_t platinf int32_t diff = work_ref_pos - default_work_ref_pos; *container_pos += diff; } + +void PipetteModule::action_delay(){ + if (m_common_cfg.each_action_delay_time > 0) { + thread_delay(m_common_cfg.each_action_delay_time); + } +} diff --git a/sdk/components/sensors/smtp2_v2/smtp2_v2.cpp b/sdk/components/sensors/smtp2_v2/smtp2_v2.cpp index ba2f882..95ad444 100644 --- a/sdk/components/sensors/smtp2_v2/smtp2_v2.cpp +++ b/sdk/components/sensors/smtp2_v2/smtp2_v2.cpp @@ -11,7 +11,7 @@ using namespace smtp2; #define TAG "SMTP2" #define OVERTIME 100 -#define DUMP_HEX 0 +#define DUMP_HEX 1 #define RE_SEND_TIMES 5 #define RE_SEND_DELAY 400 @@ -38,7 +38,7 @@ bool SMTP2V2::pump_ping() { } int32_t SMTP2V2::pump_get_state(int32_t* isbusy) { size_t rxlen = 0; - int ret = readstate(false, "/1QR\r"); + int ret = readstate(true, "/1QR\r"); if (ret != 0) return ret; uint8_t errorcode = (uint8_t)m_rxbuf[2]; @@ -123,6 +123,13 @@ int32_t SMTP2V2::pump_factory_reset() { _sendcmd(true, "/1!0R\r"); // 复位指令没有回执,所以这里只能使用方法_sendcmd return 0; } +int32_t SMTP2V2::pump_reset() { + ZLOGI(TAG, "pump_reset"); + _sendcmd(true, "/1!0R\r"); + _sendcmd(true, "/1!0R\r"); + _sendcmd(true, "/1!0R\r"); + return 0; +} /*********************************************************************************************************************** * ACTION * @@ -133,7 +140,7 @@ int32_t SMTP2V2::_pump_move_to_nl(VelCfg* vcfg, int32_t nl) { ZLOGI(TAG, " vcfg acc %d dec %d vstart %d vstop %d vmax %d", vcfg->acc, vcfg->dec, vcfg->vstart, vcfg->vstop, vcfg->vmax); fix_vcfg(vcfg); if (nl < 0) nl = 0; - return runaction(true, "/1N2L%d,%dv%dc%dV%dA%dR\r", // + return runaction(true, "/1N2L%d,%dv%dc%dV%df1A%df0R\r", // vcfg->acc, vcfg->dec, vcfg->vstart * 1000, vcfg->vstop * 1000, vcfg->vmax * 1000, nl); } int32_t SMTP2V2::pump_move_to_nl(VelCfg* vcfg, int32_t nl) { @@ -252,7 +259,7 @@ int32_t SMTP2V2::pump_aspirate_plld(int32_t pressure_threshold, VelCfg* vcfg) { if (ret != 0) { return ret; } - return runaction(true, "/1N2L%d,%dv%dc%dV%dt%d,1R\r", // + return runaction(true, "/1N2L%d,%dv%dc%dV%df1t%d,1f0R\r", // vcfg->acc, vcfg->dec, vcfg->vstart * 1000, vcfg->vstop * 1000, vcfg->vmax * 1000, // pressure_threshold); } @@ -393,8 +400,8 @@ int32_t SMTP2V2::_runaction(bool dump, const char* cmd) { osDelay(RE_SEND_DELAY); } - if (!_sendcmd(dump, "/1T\r")) continue; - if (!_sendcmd(dump, "/1CR\r")) continue; + // if (!_sendcmd(dump, "/1T\r")) continue; + // if (!_sendcmd(dump, "/1CR\r")) continue; if (!_sendcmd(dump, cmd)) continue; return getAckEcode(); diff --git a/sdk/components/sensors/smtp2_v2/smtp2_v2.hpp b/sdk/components/sensors/smtp2_v2/smtp2_v2.hpp index 08e7ae5..6e90cac 100644 --- a/sdk/components/sensors/smtp2_v2/smtp2_v2.hpp +++ b/sdk/components/sensors/smtp2_v2/smtp2_v2.hpp @@ -219,6 +219,7 @@ class SMTP2V2 { int32_t pump_init(); // 泵机初始化(归零) int32_t pump_put_tip(); // 丢弃TIP int32_t pump_factory_reset(); // 泵机复位 + int32_t pump_reset(); // 泵机复位 int32_t pump_stop(); // 停止 int32_t _pump_move_to_nl(VelCfg* vcfg, int32_t nl); int32_t pump_move_to_nl(VelCfg* vcfg, int32_t nl); //