Browse Source

add action delay

master
zhaohe 2 months ago
parent
commit
a43a3cadc5
  1. 3
      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

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

@ -17,12 +17,14 @@
typedef struct { typedef struct {
int32_t pressure_record_enable; 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; int32_t max;
} common_cfg_t; } common_cfg_t;
typedef enum { typedef enum {
kpipette_common_cfg_pressure_record_enable, 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, kpipette_common_cfg_max,
} pipette_common_cfg_index_t; } pipette_common_cfg_index_t;
@ -30,6 +32,7 @@ static inline const char *common_cfg_index_to_string(pipette_common_cfg_index_t
switch (index) { switch (index) {
CASE_ENUM_TO_STRING(kpipette_common_cfg_pressure_record_enable) 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) CASE_ENUM_TO_STRING(kpipette_common_cfg_max)
} }
return "unknown"; 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); m_piette_gun_io1.initAsInput(hardwaredcfg->IO1, ZGPIO::kMode_pullup, ZGPIO::kIRQ_noIrq, hardwaredcfg->IO1Mirror);
// 设置泵机压力数据流走232 // 设置泵机压力数据流走232
// m_smtp2.pump_reset();
osDelay(1000);
// m_smtp2.sendcmd_direct("/1f0R\r");
m_smtp2.pump_set_pressure_data_stream_port(1); m_smtp2.pump_set_pressure_data_stream_port(1);
// 测试泵机连接性 // 测试泵机连接性
test_connectivity(); 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()); ZLOGI(TAG, "pipette gun version:%s", m_smtp2.pump_read_version());
// 上报压力流 ! 不能一直打开压力流,一直打开压力流,会导致SMTP2无法响应其他命令 // 上报压力流 ! 不能一直打开压力流,一直打开压力流,会导致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); ZASSERT(hardwaredcfg->uart232);
EXHAL_UART_BindUart("pipette-uart232", 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); EXHAL_UART_ITStartAutoReadOneByte(hardwaredcfg->uart232);
} }
@ -415,7 +412,7 @@ int32_t PipetteModule::pipette_pump_aspirate() {
} else { } else {
m_state.water_level = acfg->container_pos + container_cfg->fix_water_level_depth; // 没有使用lld,使用固定深度 m_state.water_level = acfg->container_pos + container_cfg->fix_water_level_depth; // 没有使用lld,使用固定深度
} }
action_delay();
if (acfg->volumeX100nl != 0) { if (acfg->volumeX100nl != 0) {
//! WARNING: 这里强制设置tip类型为200ul //! WARNING: 这里强制设置tip类型为200ul
DO_IN_THREAD(m_smtp2.pump_set_tip_type(smtp2::TS200UL)); 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"); ZLOGI(TAG, "-->empty tip before lld");
pump_move_to_x100nl_block(0, liquidinfo->empty_tip_pm_vcpyid); pump_move_to_x100nl_block(0, liquidinfo->empty_tip_pm_vcpyid);
pump_move_to_x100nl_block(300 /*30ul*/, kpm_v_max); // 为lld清空tip,提供一定空气柱 pump_move_to_x100nl_block(300 /*30ul*/, kpm_v_max); // 为lld清空tip,提供一定空气柱
action_delay();
// 移动到瓶口 // 移动到瓶口
ZLOGI(TAG, "-->zm move to container neck pos"); ZLOGI(TAG, "-->zm move to container neck pos");
zm_move_to_block(container_pos - 50 /*5mm*/, kzm_v_default, 0); zm_move_to_block(container_pos - 50 /*5mm*/, kzm_v_default, 0);
action_delay();
// 启动lld // 启动lld
ZLOGI(TAG, "-->start lld, lld_pm_vindex %d plld_threshold %d", liquidinfo->plld_pm_vcpyid, liquidinfo->plld_threshold); 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 // 清空tip
ZLOGI(TAG, "clean tip."); ZLOGI(TAG, "clean tip.");
pump_move_to_x100nl_block(0, liquidinfo->empty_tip_pm_vcpyid); pump_move_to_x100nl_block(0, liquidinfo->empty_tip_pm_vcpyid);
action_delay();
// 吸入过量的空气 // 吸入过量的空气
if (liquidinfo->blowout_air_volume > 0) { 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); 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); pump_move_to_x100nl_block(blowout_air_volume, liquidinfo->blowout_air_pm_vcpyid);
action_delay();
} else { } else {
ZLOGI(TAG, "--> aspirate blowout_air_volume volume=0,skip"); 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) { 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); 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);
action_delay();
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);
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); 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_stop();
} }
action_delay();
} else { } else {
ZLOGI(TAG, "--> aspirate mix_volume volume=0,skip"); 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"); ZLOGI(TAG, "--> leave liquid surface");
zm_move_to_leaving_height_pos_block(-1, m_state.water_level, container_cfg, kzm_v_swap_out, 0); // 移动到液面之上 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) { if (liquidinfo->transport_volume > 0) {
ZLOGI(TAG, "--> aspirate transport_volume volume=%d, pm_vcpyid=%d", liquidinfo->transport_volume, liquidinfo->transport_volume_pm_vcpyid); 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); 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) { 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) { if (param < 0 || param >= kdistribu_all_paramid_max) {
@ -770,21 +776,25 @@ int32_t PipetteModule::pipette_pump_distribu_all() {
} else { } else {
ZLOGI(TAG, "-->clean transport volume,skip"); ZLOGI(TAG, "-->clean transport volume,skip");
} }
action_delay();
// 缓慢移动到液面之下 // 缓慢移动到液面之下
ZLOGI(TAG, "-->move to below the liquid surface"); ZLOGI(TAG, "-->move to below the liquid surface");
zm_move_to_immersion_pos_block(container_pos, -1, container_cfg, kzm_v_swap_in, 0); // 缓慢移动到液面之下 zm_move_to_immersion_pos_block(container_pos, -1, container_cfg, kzm_v_swap_in, 0); // 缓慢移动到液面之下
action_delay();
// 分液 // 分液
ZLOGI(TAG, "-->distribu liquid"); ZLOGI(TAG, "-->distribu liquid");
int32_t distribu_volume = calibrate_liquid_volume(liquidInGuninfo, m_pump_gun_state.liquid_volume); 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); // 分液 pump_move_by_x100nl_block(-distribu_volume, liquidInGuninfo->distribu_pm_vpyid); // 分液
action_delay();
// 移动到swap位置,快速清空tip,使用(emptyTip速度) // 移动到swap位置,快速清空tip,使用(emptyTip速度)
ZLOGI(TAG, "-->move to swap position and clean tip"); 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位置 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速度) 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); // 离开液面 zm_move_to_leaving_height_pos_block(container_pos, -1, container_cfg, kzm_v_swap_out, 0); // 离开液面
action_delay();
} else { } else {
ZLOGI(TAG, "-->skip mixing"); ZLOGI(TAG, "-->skip mixing");
} }
// 吸入10ul过量的空气,防挂液 // 吸入10ul过量的空气,防挂液
pump_move_by_x100nl_block(100, liquidInGuninfo->transport_volume_pm_vcpyid); pump_move_by_x100nl_block(100, liquidInGuninfo->transport_volume_pm_vcpyid);
action_delay();
// //
// 如果需要归零,则移动到transform_pos // 如果需要归零,则移动到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, aspiration_param_t *param);
void dump(const char *title, distribu_all_param_t *param); void dump(const char *title, distribu_all_param_t *param);
void action_delay();
private: private:
/*********************************************************************************************************************** /***********************************************************************************************************************
* STATE * * 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; int32_t diff_pos = 0;
for (size_t i = 0; i < 4; i++) { for (size_t i = 0; i < 4; i++) {
int32_t vcpyid = vcfgcpyid; 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_move_to_x100nl(x100nl, vcpyid);
pump_waitfor_stop(); pump_waitfor_stop();
@ -59,7 +59,7 @@ void PipetteModule::pump_move_to_x100nl_block(double x100nl, int32_t vcfgcpyid,
diff_pos = targetpos - after_pos; diff_pos = targetpos - after_pos;
if (diff) *diff = diff_pos; if (diff) *diff = diff_pos;
ZLOGI(TAG, "pump target %d nl, now pos %d nl diff %d", targetpos, after_pos, 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); ZLOGW(TAG, "pump move to x100nl %d failed, diff is too large retrying...", x100nl);
continue; 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; int32_t diff = work_ref_pos - default_work_ref_pos;
*container_pos += diff; *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 TAG "SMTP2"
#define OVERTIME 100 #define OVERTIME 100
#define DUMP_HEX 0
#define DUMP_HEX 1
#define RE_SEND_TIMES 5 #define RE_SEND_TIMES 5
#define RE_SEND_DELAY 400 #define RE_SEND_DELAY 400
@ -38,7 +38,7 @@ bool SMTP2V2::pump_ping() {
} }
int32_t SMTP2V2::pump_get_state(int32_t* isbusy) { int32_t SMTP2V2::pump_get_state(int32_t* isbusy) {
size_t rxlen = 0; size_t rxlen = 0;
int ret = readstate(false, "/1QR\r");
int ret = readstate(true, "/1QR\r");
if (ret != 0) return ret; if (ret != 0) return ret;
uint8_t errorcode = (uint8_t)m_rxbuf[2]; uint8_t errorcode = (uint8_t)m_rxbuf[2];
@ -123,6 +123,13 @@ int32_t SMTP2V2::pump_factory_reset() {
_sendcmd(true, "/1!0R\r"); // 复位指令没有回执,所以这里只能使用方法_sendcmd _sendcmd(true, "/1!0R\r"); // 复位指令没有回执,所以这里只能使用方法_sendcmd
return 0; 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 * * 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); 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); fix_vcfg(vcfg);
if (nl < 0) nl = 0; 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); 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) { 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) { if (ret != 0) {
return ret; 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, // vcfg->acc, vcfg->dec, vcfg->vstart * 1000, vcfg->vstop * 1000, vcfg->vmax * 1000, //
pressure_threshold); pressure_threshold);
} }
@ -393,8 +400,8 @@ int32_t SMTP2V2::_runaction(bool dump, const char* cmd) {
osDelay(RE_SEND_DELAY); 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; if (!_sendcmd(dump, cmd)) continue;
return getAckEcode(); return getAckEcode();

1
sdk/components/sensors/smtp2_v2/smtp2_v2.hpp

@ -219,6 +219,7 @@ class SMTP2V2 {
int32_t pump_init(); // 泵机初始化(归零) int32_t pump_init(); // 泵机初始化(归零)
int32_t pump_put_tip(); // 丢弃TIP int32_t pump_put_tip(); // 丢弃TIP
int32_t pump_factory_reset(); // 泵机复位 int32_t pump_factory_reset(); // 泵机复位
int32_t pump_reset(); // 泵机复位
int32_t pump_stop(); // 停止 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);
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