Browse Source

add action delay

master
zhaohe 2 months ago
parent
commit
a43a3cadc5
  1. 11
      sdk/components/pipette_module/base/pipette_cfg.hpp
  2. 34
      sdk/components/pipette_module/pipette_ctrl_module.cpp
  3. 2
      sdk/components/pipette_module/pipette_ctrl_module.hpp
  4. 8
      sdk/components/pipette_module/pipette_ctrl_module_pm_ctrl.cpp
  5. 6
      sdk/components/pipette_module/pipette_ctrl_module_utils.cpp
  6. 19
      sdk/components/sensors/smtp2_v2/smtp2_v2.cpp
  7. 1
      sdk/components/sensors/smtp2_v2/smtp2_v2.hpp

11
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";

34
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
//

2
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 *

8
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;
}

6
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);
}
}

19
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();

1
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); //

Loading…
Cancel
Save