Browse Source

update

master
zhaohe 11 months ago
parent
commit
7a482bcf4a
  1. 4
      .settings/language.settings.xml
  2. 2
      a8000_protocol
  3. 320
      sdk/components/pipette_module/pipette_ctrl_module_v2.cpp
  4. 62
      sdk/components/pipette_module/pipette_ctrl_module_v2.hpp
  5. 6
      sdk/components/zcancmder/zcan_protocol_parser.cpp
  6. 2
      sdk/components/zcancmder/zcan_protocol_parser.hpp
  7. 55
      usrc/subboards/subboard80_cliptip/subboard80_cliptip.cpp

4
.settings/language.settings.xml

@ -5,7 +5,7 @@
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
<provider class="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" console="false" env-hash="-441403872347764375" id="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" keep-relative-paths="false" name="MCU ARM GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<provider class="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" console="false" env-hash="1585622937262680982" id="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" keep-relative-paths="false" name="MCU ARM GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
@ -16,7 +16,7 @@
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
<provider class="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" console="false" env-hash="-428669252172530895" id="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" keep-relative-paths="false" name="MCU ARM GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<provider class="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" console="false" env-hash="1598357557437914462" id="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" keep-relative-paths="false" name="MCU ARM GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>

2
a8000_protocol

@ -1 +1 @@
Subproject commit c025f34164cd3334f78d8fbcbd42b54e17987153
Subproject commit 48fe71561ae851deea3de371ef04276fa8d777f9

320
sdk/components/pipette_module/pipette_ctrl_module_v2.cpp

@ -9,6 +9,9 @@
#define TAG "PipetteModuleV2"
/***********************************************************************************************************************
* MARCO *
***********************************************************************************************************************/
#define ZSLICE(...) ZSlice slice(this, TAG, __FUNCTION__, __VA_ARGS__)
#define DO_IN_THREAD(func) \
{ \
@ -28,12 +31,18 @@
} \
}
using namespace iflytop;
// using namespace pipette_module_v3;
#define PIPETTE_PREPARE_POS 800
#define LLD_PREPARE_DISTRIBUT_POS 100
#define LLF_DPOS 1000
#define ASPIRATE_POS 0
using namespace iflytop;
// using namespace pipette_module_v3;
static int32_t assign_int32(int32_t *toval, int32_t val) {
*toval = val;
return 0;
}
void PipetteModuleV2::initialize(int32_t id, config_t *config, hardward_config_t *hardwaredcfg) { //
ZASSERT(config != nullptr);
@ -67,15 +76,14 @@ void PipetteModuleV2::create_default_cfg(config_t *defaultcfg) {
cfg.lld_prepare_pos = PIPETTE_PREPARE_POS;
cfg.lld_prepare_pre_distribut_ul = LLD_PREPARE_DISTRIBUT_POS;
cfg.motor_one_circle_pulse = 10000;
cfg.motor_one_circle_pulse_denominator = 1;
cfg.motor_ihold = 1;
cfg.motor_irun = 3;
cfg.motor_iholddelay = 100;
cfg.motor_default_velocity = 500;
cfg.motor_run_to_zero_speed = 100;
cfg.motor_look_zero_edge_speed = 100;
cfg.zm_one_circle_pulse = 10000;
cfg.zm_one_circle_pulse_denominator = 1;
cfg.zm_ihold = 1;
cfg.zm_irun = 3;
cfg.zm_iholddelay = 100;
cfg.zm_default_velocity = 500;
cfg.zm_run_to_zero_speed = 100;
cfg.zm_look_zero_edge_speed = 100;
}
int32_t PipetteModuleV2::getid(int32_t *id) {
*id = m_id;
@ -91,21 +99,21 @@ int32_t PipetteModuleV2::module_active_cfg() {
DO(m_smtp2.pump_set_vstop(m_cfg.pump_vstop));
m_zm->enable(false);
m_zm->setIHOLD_IRUN(m_cfg.motor_ihold, m_cfg.motor_irun, m_cfg.motor_iholddelay);
m_zm->setScale(m_cfg.motor_one_circle_pulse);
m_zm->setScaleDenominator(m_cfg.motor_one_circle_pulse_denominator);
m_zm->setMotorShaft(m_cfg.motor_shaft);
m_zm->setGlobalScale(m_cfg.motor_iglobalscaler);
m_zm->set_vstart(m_cfg.motor_vstart);
m_zm->set_a1(m_cfg.motor_a1);
m_zm->set_amax(m_cfg.motor_amax);
m_zm->set_v1(m_cfg.motor_v1);
m_zm->set_dmax(m_cfg.motor_dmax);
m_zm->set_d1(m_cfg.motor_d1);
m_zm->set_vstop(m_cfg.motor_vstop);
m_zm->set_tzerowait(m_cfg.motor_tzerowait);
m_zm->set_enc_resolution(m_cfg.motor_enc_resolution);
m_zm->setIHOLD_IRUN(m_cfg.zm_ihold, m_cfg.zm_irun, m_cfg.zm_iholddelay);
m_zm->setScale(m_cfg.zm_one_circle_pulse);
m_zm->setScaleDenominator(m_cfg.zm_one_circle_pulse_denominator);
m_zm->setMotorShaft(m_cfg.zm_shaft);
m_zm->setGlobalScale(m_cfg.zm_iglobalscaler);
m_zm->set_vstart(m_cfg.zm_vstart);
m_zm->set_a1(m_cfg.zm_a1);
m_zm->set_amax(m_cfg.zm_amax);
m_zm->set_v1(m_cfg.zm_v1);
m_zm->set_dmax(m_cfg.zm_dmax);
m_zm->set_d1(m_cfg.zm_d1);
m_zm->set_vstop(m_cfg.zm_vstop);
m_zm->set_tzerowait(m_cfg.zm_tzerowait);
m_zm->set_enc_resolution(m_cfg.zm_enc_resolution);
if (m_state.enable) {
m_zm->enable(true);
@ -114,8 +122,8 @@ int32_t PipetteModuleV2::module_active_cfg() {
return 0;
}
#define XXX_CFG_REG(cfgkey, cfg) \
case cfgkey: { \
#define XXX_CFG_REG(cfg) \
case kreg_pipette_##cfg: { \
if (read) { \
return REG_GET(m_cfg.cfg); \
} else { \
@ -127,52 +135,58 @@ int32_t PipetteModuleV2::module_active_cfg() {
#define XXX_STATE_REG(statekey, action) PROCESS_REG(statekey, action, ACTION_NONE)
int32_t PipetteModuleV2::_module_xxx_reg(int32_t param_id, bool read, int32_t &val) {
switch (param_id) {
// XXX_STATE_REG(kreg_pipette_pos_ul, /* */ read_pos_ul(&val));
// XXX_STATE_REG(kreg_pipette_capactitance_val, /* */ read_capactitance(&val));
// XXX_STATE_REG(kreg_pipette_tip_state, /* */ read_tip_state(&val));
// XXX_STATE_REG(kreg_step_motor_pos, getnowpos(val), ACTION_NONE);
// XXX_STATE_REG(kreg_step_motor_is_enable, REG_GET(m_state.enable), ACTION_NONE);
// XXX_STATE_REG(kreg_step_motor_has_move_zero, REG_GET(m_state.has_move_to_zero), ACTION_NONE);
// XXX_CFG_REG(kreg_step_motor_dpos, REG_GET(m_state.dpos), ACTION_NONE);
XXX_CFG_REG(kreg_pipette_limit_ul, limit_ul);
XXX_CFG_REG(kreg_pipette_pump_acc, pump_acc);
XXX_CFG_REG(kreg_pipette_pump_dec, pump_dec);
XXX_CFG_REG(kreg_pipette_pump_vstart, pump_vstart);
XXX_CFG_REG(kreg_pipette_pump_vstop, pump_vstop);
XXX_CFG_REG(kreg_pipette_pump_vmax, pump_vmax);
XXX_CFG_REG(kreg_pipette_aspirate_pump_vel, aspirate_pump_vel);
XXX_CFG_REG(kreg_pipette_lld_pump_vel, lld_pump_vel);
XXX_CFG_REG(kreg_pipette_lld_motor_vel_rpm, lld_motor_vel_rpm);
XXX_CFG_REG(kreg_pipette_lld_detect_period_ms, lld_detect_period_ms);
XXX_CFG_REG(kreg_pipette_lld_prepare_pos, lld_prepare_pos);
XXX_CFG_REG(kreg_pipette_lld_prepare_pre_distribut_ul, lld_prepare_pre_distribut_ul);
XXX_CFG_REG(kreg_step_motor_shaft, motor_shaft);
XXX_CFG_REG(kreg_step_motor_one_circle_pulse, motor_one_circle_pulse);
XXX_CFG_REG(kreg_step_motor_one_circle_pulse_denominator, motor_one_circle_pulse_denominator);
XXX_CFG_REG(kreg_step_motor_default_velocity, motor_default_velocity);
XXX_CFG_REG(kreg_step_motor_run_to_zero_speed, motor_run_to_zero_speed);
XXX_CFG_REG(kreg_step_motor_look_zero_edge_speed, motor_look_zero_edge_speed);
XXX_CFG_REG(kreg_step_motor_ihold, motor_ihold);
XXX_CFG_REG(kreg_step_motor_irun, motor_irun);
XXX_CFG_REG(kreg_step_motor_iholddelay, motor_iholddelay);
XXX_CFG_REG(kreg_step_motor_max_d, motor_max_d);
XXX_CFG_REG(kreg_step_motor_min_d, motor_min_d);
XXX_CFG_REG(kreg_step_motor_iglobalscaler, motor_iglobalscaler);
XXX_CFG_REG(kreg_step_motor_vstart, motor_vstart);
XXX_CFG_REG(kreg_step_motor_a1, motor_a1);
XXX_CFG_REG(kreg_step_motor_amax, motor_amax);
XXX_CFG_REG(kreg_step_motor_v1, motor_v1);
XXX_CFG_REG(kreg_step_motor_dmax, motor_dmax);
XXX_CFG_REG(kreg_step_motor_d1, motor_d1);
XXX_CFG_REG(kreg_step_motor_vstop, motor_vstop);
XXX_CFG_REG(kreg_step_motor_tzerowait, motor_tzerowait);
XXX_CFG_REG(kreg_step_motor_enc_resolution, motor_enc_resolution);
XXX_CFG_REG(kreg_step_motor_enable_enc, motor_enable_enc);
XXX_CFG_REG(kreg_step_motor_dzero_pos, motor_dzero);
XXX_CFG_REG(kreg_step_motor_pos_devi_tolerance, pos_devi_tolerance);
/***********************************************************************************************************************
* STATE *
***********************************************************************************************************************/
XXX_STATE_REG(kreg_pipette_pos_ul, /* */ pump_read_pos_ul(&val));
XXX_STATE_REG(kreg_pipette_capactitance_val, /* */ pump_read_capactitance(&val));
XXX_STATE_REG(kreg_pipette_tip_state, /* */ pump_read_tip_state(&val));
XXX_STATE_REG(kreg_pipette_zm_pos, assign_int32(&val, zm_get_now_pos()));
XXX_STATE_REG(kreg_pipette_zm_is_enable, REG_GET(m_state.enable));
XXX_STATE_REG(kreg_pipette_zm_dpos, REG_GET(m_state.dpos));
/***********************************************************************************************************************
* CFG *
***********************************************************************************************************************/
XXX_CFG_REG(limit_ul);
XXX_CFG_REG(pump_acc);
XXX_CFG_REG(pump_dec);
XXX_CFG_REG(pump_vstart);
XXX_CFG_REG(pump_vstop);
XXX_CFG_REG(pump_vmax);
XXX_CFG_REG(aspirate_pump_vel);
XXX_CFG_REG(lld_pump_vel);
XXX_CFG_REG(lld_motor_vel_rpm);
XXX_CFG_REG(lld_detect_period_ms);
XXX_CFG_REG(lld_prepare_pos);
XXX_CFG_REG(lld_prepare_pre_distribut_ul);
XXX_CFG_REG(zm_shaft);
XXX_CFG_REG(zm_one_circle_pulse);
XXX_CFG_REG(zm_one_circle_pulse_denominator);
XXX_CFG_REG(zm_default_velocity);
XXX_CFG_REG(zm_run_to_zero_speed);
XXX_CFG_REG(zm_look_zero_edge_speed);
XXX_CFG_REG(zm_ihold);
XXX_CFG_REG(zm_irun);
XXX_CFG_REG(zm_iholddelay);
XXX_CFG_REG(zm_max_d);
XXX_CFG_REG(zm_min_d);
XXX_CFG_REG(zm_iglobalscaler);
XXX_CFG_REG(zm_vstart);
XXX_CFG_REG(zm_a1);
XXX_CFG_REG(zm_amax);
XXX_CFG_REG(zm_v1);
XXX_CFG_REG(zm_dmax);
XXX_CFG_REG(zm_d1);
XXX_CFG_REG(zm_vstop);
XXX_CFG_REG(zm_tzerowait);
XXX_CFG_REG(zm_enc_resolution);
XXX_CFG_REG(zm_enable_enc);
XXX_CFG_REG(zm_dzero);
XXX_CFG_REG(zm_pos_devi_tolerance);
XXX_CFG_REG(zm_io_trigger_append_distance);
default:
return err::kmodule_not_find_reg;
@ -194,6 +208,17 @@ int32_t PipetteModuleV2::module_xxx_reg(int32_t param_id, bool read, int32_t &va
* EXT_API *
***********************************************************************************************************************/
int32_t PipetteModuleV2::pipette_zmotor_enable(int32_t enable) {
ZLOGI(TAG, "m%d pipette_zmotor_enable %ld", m_id, enable);
m_thread.stop();
m_zm->enable(enable);
m_state.enable = enable;
if (enable == 0 && m_cfg.zm_enable_enc == 0) {
m_state.has_move_to_zero = 0;
}
return 0;
}
/**
* @brief
*
@ -203,7 +228,8 @@ int32_t PipetteModuleV2::pipette_zmotor_move_zero() { //
thread_start_work([this]() {
do_zm_move_0p(); // 移动到零点
if (creg.module_errorcode != 0) { // 计算并更新零点坐标
zm_set_now_pos(0 + m_cfg.motor_dzero - m_cfg.io_trigger_append_distance);
zm_set_now_pos(0 + m_cfg.zm_dzero - m_cfg.zm_io_trigger_append_distance);
m_state.has_move_to_zero = 1;
}
});
return 0;
@ -220,9 +246,10 @@ int32_t PipetteModuleV2::pipette_zmotor_measure_distance() {
do_zm_move_0p(); // 移动到零点
int32_t dpos = zm_get_now_pos() - startpos;
if (creg.module_errorcode != 0) { // 计算并更新零点坐标
zm_set_now_pos(0 + m_cfg.motor_dzero - m_cfg.io_trigger_append_distance);
zm_set_now_pos(0 + m_cfg.zm_dzero - m_cfg.zm_io_trigger_append_distance);
m_state.has_move_to_zero = 1;
}
m_asynchronous_result.result0 = 0 + m_cfg.motor_dzero - m_cfg.io_trigger_append_distance - dpos;
m_asynchronous_result.result0 = 0 + m_cfg.zm_dzero - m_cfg.zm_io_trigger_append_distance - dpos;
});
return 0;
}
@ -237,7 +264,6 @@ int32_t PipetteModuleV2::pipette_zmotor_read_measure_distance_result(int32_t *re
*result0 = m_asynchronous_result.result0;
return 0;
}
/**
* @brief
*
@ -246,7 +272,7 @@ int32_t PipetteModuleV2::pipette_zmotor_read_measure_distance_result(int32_t *re
*/
int32_t PipetteModuleV2::pipette_zmotor_move_by(int32_t distance) {
thread_start_work([this, distance]() {
zm_move_by(distance, m_cfg.motor_default_velocity);
zm_move_by(distance, m_cfg.zm_default_velocity);
zm_waitfor_stop();
});
return 0;
@ -257,11 +283,16 @@ int32_t PipetteModuleV2::pipette_zmotor_move_by(int32_t distance) {
* @param position
* @return int32_t
*/
int32_t PipetteModuleV2::pipette_zmotor_move_to(int32_t position) {
thread_start_work([this, position]() {
zm_move_to(position, m_cfg.motor_default_velocity);
int32_t PipetteModuleV2::pipette_zmotor_move_to(int32_t tox) {
if (m_state.has_move_to_zero == 0) return err::kstep_motor_not_move_to_zero;
if (m_cfg.zm_min_d != 0 && tox < m_cfg.zm_min_d) tox = m_cfg.zm_min_d;
if (m_cfg.zm_max_d != 0 && tox > m_cfg.zm_max_d) tox = m_cfg.zm_max_d;
thread_start_work([this, tox]() {
zm_move_to(tox, m_cfg.zm_default_velocity);
zm_waitfor_stop();
});
return 0;
}
/**
@ -270,6 +301,7 @@ int32_t PipetteModuleV2::pipette_zmotor_move_to(int32_t position) {
* @return int32_t
*/
int32_t PipetteModuleV2::pipette_zmotor_move_to_zero_point_quick() {
if (m_state.has_move_to_zero == 0) return err::kstep_motor_not_move_to_zero;
thread_start_work([this]() { do_pipette_zmotor_move_to_zero_point_quick(); });
return 0;
}
@ -280,7 +312,6 @@ int32_t PipetteModuleV2::pipette_init_device() {
pump_waitfor_stop();
//
m_state.load_val_ul = 0;
m_state.aspirated = 0;
m_state.lld_prepared = 0;
m_state.pipette_is_inited = 1;
});
@ -293,6 +324,8 @@ int32_t PipetteModuleV2::pipette_put_tip() {
}
int32_t PipetteModuleV2::pipette_lld_prepare() {
if (m_state.pipette_is_inited == 0) return err::kpipette_error_uninited;
thread_start_work([this]() {
DO_IN_THREAD(m_smtp2.pump_move_to_ul(m_cfg.pump_vmax, m_cfg.lld_prepare_pos)); // 移动到中点
pump_waitfor_stop();
@ -301,6 +334,14 @@ int32_t PipetteModuleV2::pipette_lld_prepare() {
return 0;
}
int32_t PipetteModuleV2::pipette_lld(int32_t lldtype, int32_t zdpos, int32_t c_threshold, int32_t p_threshold) {
// 检查泵机是否初始化过
if (m_state.pipette_is_inited == 0) return err::kpipette_error_uninited;
// 检查tip头状态
int32_t tipstate = 0;
DO(m_smtp2.pump_get_tip_state(&tipstate));
if (tipstate != 0) return err::kpipette_error_tipisload_when_lld_prepare;
thread_start_work([this, lldtype, zdpos, c_threshold, p_threshold]() { //
m_state.lld_prepared = 0; // 失效m_state.lld_prepared
@ -391,12 +432,14 @@ int32_t PipetteModuleV2::pipette_lld(int32_t lldtype, int32_t zdpos, int32_t c_t
}
int32_t PipetteModuleV2::pipette_aspirate_prepare() {
if (m_state.pipette_is_inited == 0) return err::kpipette_error_uninited;
thread_start_work([this]() { //
ZLOGI(TAG, "pipette_aspirate_prepare");
m_state.aspirate_cfg_eigen_time = 0;
m_state.aspirate_cfg_p_thre = 0;
m_state.aspirate_cfg_llf_zm_rpm = 0;
DO_IN_THREAD(m_smtp2.pump_move_to_ul(m_cfg.pump_vmax, 0));
DO_IN_THREAD(m_smtp2.pump_move_to_ul(m_cfg.pump_vmax, ASPIRATE_POS));
pump_waitfor_stop();
ZLOGI(TAG, "pipette_aspirate_prepare end...");
});
@ -426,10 +469,14 @@ int32_t PipetteModuleV2::pipette_aspirate_set_operation_verifi_tolerance(int32_t
}
int32_t PipetteModuleV2::pipette_aspirate(int32_t ul) {
if (m_state.pipette_is_inited == 0) return err::kpipette_error_uninited;
thread_start_work([this, ul]() {
m_state.aspirated = 1;
m_state.lld_prepared = 0;
DO_IN_THREAD(m_smtp2.pump_move_to_ul(m_cfg.pump_vmax, ASPIRATE_POS));
pump_waitfor_stop();
if (ul > 0) {
// zmotor and pump move
if (m_state.aspirate_cfg_llf_zm_rpm != 0) zm_move_by(m_cfg.aspirate_zmotor_max_move_by, m_state.aspirate_cfg_llf_zm_rpm);
@ -450,8 +497,9 @@ int32_t PipetteModuleV2::pipette_aspirate(int32_t ul) {
return 0;
}
int32_t PipetteModuleV2::pipette_aspirate_and_verify(int32_t ul) {
if (m_state.pipette_is_inited == 0) return err::kpipette_error_uninited;
thread_start_work([this, ul]() {
m_state.aspirated = 1;
m_state.lld_prepared = 0;
// zmotor and pump move
@ -473,6 +521,8 @@ int32_t PipetteModuleV2::pipette_aspirate_and_verify(int32_t ul) {
}
int32_t PipetteModuleV2::pipette_shake_up(int32_t ul, int32_t times) {
if (m_state.pipette_is_inited == 0) return err::kpipette_error_uninited;
thread_start_work([this, ul, times]() {
//
int32_t dpos = 0;
@ -512,6 +562,8 @@ int32_t PipetteModuleV2::pipette_shake_up(int32_t ul, int32_t times) {
}
int32_t PipetteModuleV2::pipette_aspirate_infer_pressure(int32_t ul) {
if (m_state.pipette_is_inited == 0) return err::kpipette_error_uninited;
thread_start_work([this, ul]() {
//
ZLOGI(TAG, "pipette_aspirate_infer_pressure %d", ul);
@ -528,6 +580,8 @@ int32_t PipetteModuleV2::pipette_get_aspirate_infer_pressure_result(int32_t *res
return 0;
}
int32_t PipetteModuleV2::pipette_aspirate_infer_eigen_time(int32_t ul) {
if (m_state.pipette_is_inited == 0) return err::kpipette_error_uninited;
//
thread_start_work([this, ul]() {
//
@ -560,39 +614,39 @@ int32_t PipetteModuleV2::pipette_get_aspirate_infer_eigen_time_result(int32_t *r
***********************************************************************************************************************/
void PipetteModuleV2::do_zm_move_0p() {
if (!zm0p_is_trigger()) {
zm_move_to_end(-1, m_cfg.motor_run_to_zero_speed);
zm_move_to_end(-1, m_cfg.zm_run_to_zero_speed);
zm_waitfor_zm0p_trigger_and_stop_motor();
}
// leave from zero
if (zm0p_is_trigger()) {
zm_move_to_end(1, m_cfg.motor_look_zero_edge_speed);
zm_move_to_end(1, m_cfg.zm_look_zero_edge_speed);
zm_waitfor_zm0p_not_trigger_and_stop_motor();
}
// move to zero again
if (!zm0p_is_trigger()) {
zm_move_to_end(-1, m_cfg.motor_run_to_zero_speed);
zm_move_to_end(-1, m_cfg.zm_run_to_zero_speed);
zm_waitfor_zm0p_trigger_and_stop_motor();
}
// move to zero
zm_move_by(m_cfg.io_trigger_append_distance, m_cfg.motor_run_to_zero_speed);
zm_move_by(m_cfg.zm_io_trigger_append_distance, m_cfg.zm_run_to_zero_speed);
zm_waitfor_stop();
}
void PipetteModuleV2::do_pipette_zmotor_move_to_zero_point_quick() {
// 期望偏差
int32_t expectation_dpos = -m_cfg.io_trigger_append_distance + 0 + m_cfg.motor_dzero - zm_get_now_pos();
int32_t expectation_dpos = -m_cfg.zm_io_trigger_append_distance + 0 + m_cfg.zm_dzero - zm_get_now_pos();
int32_t startpos = zm_get_now_pos();
if (!zm0p_is_trigger()) {
// 快速移动到零点
// moveTo(0 + m_cfg.motor_dzero, m_cfg.motor_default_velocity);
zm_move_to(0 + m_cfg.motor_dzero, m_cfg.motor_default_velocity);
// moveTo(0 + m_cfg.zm_dzero, m_cfg.zm_default_velocity);
zm_move_to(0 + m_cfg.zm_dzero, m_cfg.zm_default_velocity);
zm_waitfor_zm0p_trigger_and_stop_motor();
} else {
// 快速移动到零点
zm_move_to(0 + m_cfg.motor_dzero, m_cfg.motor_default_velocity);
zm_move_to(0 + m_cfg.zm_dzero, m_cfg.zm_default_velocity);
zm_waitfor_zm0p_not_trigger_and_stop_motor();
}
// 移动到零点
@ -600,7 +654,7 @@ void PipetteModuleV2::do_pipette_zmotor_move_to_zero_point_quick() {
// 校验偏差
int32_t dpos = zm_get_now_pos() - startpos;
if (m_cfg.pos_devi_tolerance != 0 && (abs(expectation_dpos - dpos) > m_cfg.pos_devi_tolerance)) {
if (m_cfg.zm_pos_devi_tolerance != 0 && (abs(expectation_dpos - dpos) > m_cfg.zm_pos_devi_tolerance)) {
throw zapp_exception(err::kstep_motor_lost_step);
}
}
@ -620,7 +674,7 @@ int32_t PipetteModuleV2::pipette_zmotor_read_dev_status_cache(int32_t *devStatus
* ZM_UTILS *
***********************************************************************************************************************/
int32_t PipetteModuleV2::zm_get_now_pos() {
if (m_cfg.motor_enable_enc == 0) {
if (m_cfg.zm_enable_enc == 0) {
return m_zm->getXACTUAL();
}
return m_zm->read_enc_val();
@ -630,29 +684,29 @@ void PipetteModuleV2::zm_set_now_pos(int32_t x) {
m_zm->set_enc_val(x);
}
void PipetteModuleV2::zm_move_to(int32_t x, int32_t v) {
if (m_cfg.motor_enable_enc != 0) {
if (m_cfg.zm_enable_enc != 0) {
m_zm->setXACTUAL(m_zm->read_enc_val());
}
m_zm->moveTo(x, v);
}
void PipetteModuleV2::zm_move_by(int32_t dx, int32_t v) {
if (m_cfg.motor_enable_enc != 0) {
if (m_cfg.zm_enable_enc != 0) {
m_zm->setXACTUAL(m_zm->read_enc_val());
}
m_zm->moveBy(dx, v);
}
void PipetteModuleV2::zm_move_to_end(int32_t direction, int32_t v) {
if (m_cfg.motor_enable_enc != 0) {
if (m_cfg.zm_enable_enc != 0) {
m_zm->setXACTUAL(m_zm->read_enc_val());
}
m_zm->moveToEnd(direction, v);
}
void PipetteModuleV2::zm_update_dzero(int32_t dzero) {
int32_t nowabs = zm_get_now_pos() - m_cfg.motor_dzero;
m_cfg.motor_dzero = dzero;
zm_set_now_pos(nowabs + m_cfg.motor_dzero);
int32_t nowabs = zm_get_now_pos() - m_cfg.zm_dzero;
m_cfg.zm_dzero = dzero;
zm_set_now_pos(nowabs + m_cfg.zm_dzero);
}
bool PipetteModuleV2::zm0p_is_trigger() { return m_zm0p->getState(); }
@ -674,6 +728,21 @@ void PipetteModuleV2::pump_waitfor_stop() {
}
}
int32_t PipetteModuleV2::pump_read_pos_ul(int32_t *val) {
//
*val = m_state.load_val_ul;
return 0;
}
int32_t PipetteModuleV2::pump_read_capactitance(int32_t *val) {
m_smtp2.pump_get_capacitance(val);
return 0;
}
int32_t PipetteModuleV2::pump_read_tip_state(int32_t *val) {
*val = 0;
m_smtp2.pump_get_tip_state(val);
return 0;
}
void PipetteModuleV2::zm_waitfor_zm0p_not_trigger_and_stop_motor() {
// 等待触发
while (zm0p_is_trigger()) thread_delay(2);
@ -708,6 +777,45 @@ void PipetteModuleV2::push_snesor_sample_data(int32_t motor_pos, int32_t cap_val
*/
int32_t PipetteModuleV2::bfcall(int32_t cmdid, uint8_t *param, int32_t len) {
ZLOGI(TAG, "bfcall %s", cmdid2str(cmdid));
if (cmdid == kpipette_zmotor_move_zero) goto check;
if (cmdid == kpipette_zmotor_move_to_zero_point_quick) goto check;
if (cmdid == kpipette_zmotor_measure_distance) goto check;
if (cmdid == kpipette_zmotor_read_measure_distance_result) goto check;
if (cmdid == kpipette_zmotor_move_by) goto check;
if (cmdid == kpipette_zmotor_move_to) goto check;
if (cmdid == kpipette_init_device) goto check;
if (cmdid == kpipette_put_tip) goto check;
if (cmdid == kpipette_lld_prepare) goto check;
if (cmdid == kpipette_lld) goto check;
if (cmdid == kpipette_aspirate_prepare) goto check;
if (cmdid == kpipette_aspirate_set_llf_velocity) goto check;
if (cmdid == kpipette_aspirate_set_operation_verifi_p_thre) goto check;
if (cmdid == kpipette_aspirate_set_operation_verifi_eigen_time) goto check;
if (cmdid == kpipette_aspirate_set_operation_verifi_tolerance) goto check;
if (cmdid == kpipette_aspirate) goto check;
if (cmdid == kpipette_aspirate_and_verify) goto check;
if (cmdid == kpipette_shake_up) goto check;
if (cmdid == kpipette_aspirate_infer_pressure) goto check;
if (cmdid == kpipette_aspirate_infer_eigen_time) goto check;
check:
if (!m_state.enable) {
return err::kstep_motor_not_enable;
}
if (creg.module_errorcode == err::kstep_motor_subic_reset) {
return creg.module_errorcode;
} else if (creg.module_errorcode == err::kstep_motor_drv_err) {
return creg.module_errorcode;
} else if (creg.module_errorcode == err::kstep_motor_uv_cp) {
return creg.module_errorcode;
} else {
/**
* @brief
*/
return 0;
}
return 0;
}
void PipetteModuleV2::aftercall(int32_t val) {
@ -719,7 +827,7 @@ void PipetteModuleV2::aftercall(int32_t val) {
}
void PipetteModuleV2::runingcheck() {
// 检查是否丢步
if (m_cfg.motor_enable_enc != 0) {
if (m_cfg.zm_enable_enc != 0) {
vPortEnterCritical();
int32_t m1enc = m_zm->read_enc_val();
@ -729,8 +837,8 @@ void PipetteModuleV2::runingcheck() {
int32_t dm1 = abs(m1enc - m1pos);
if (m_cfg.pos_devi_tolerance != 0) {
if (dm1 > m_cfg.pos_devi_tolerance) {
if (m_cfg.zm_pos_devi_tolerance != 0) {
if (dm1 > m_cfg.zm_pos_devi_tolerance) {
ZLOGE(TAG, "motor pos devi %d", dm1);
creg.module_errorcode = err::kstep_motor_lost_step;
}

62
sdk/components/pipette_module/pipette_ctrl_module_v2.hpp

@ -65,37 +65,36 @@ class PipetteModuleV2 : public ZIModule {
int32_t lld_prepare_pre_distribut_ul; // lld前,预分配位置
int32_t llf_area2rpm; // 液面跟随,电机运动速度和容器截面积比例关系
int32_t motor_shaft;
int32_t motor_one_circle_pulse; //
int32_t motor_one_circle_pulse_denominator; //
int32_t motor_ihold;
int32_t motor_irun;
int32_t motor_iholddelay;
int32_t motor_iglobalscaler;
int32_t motor_default_velocity;
int32_t motor_min_d;
int32_t motor_max_d;
int32_t motor_run_to_zero_speed;
int32_t motor_look_zero_edge_speed;
int32_t motor_vstart;
int32_t motor_a1;
int32_t motor_amax;
int32_t motor_v1;
int32_t motor_dmax;
int32_t motor_d1;
int32_t motor_vstop;
int32_t motor_tzerowait;
int32_t motor_enc_resolution;
int32_t motor_enable_enc;
int32_t motor_dzero; // 零点偏移
int32_t io_trigger_append_distance;
int32_t pos_devi_tolerance;
int32_t zm_shaft;
int32_t zm_one_circle_pulse; //
int32_t zm_one_circle_pulse_denominator; //
int32_t zm_ihold;
int32_t zm_irun;
int32_t zm_iholddelay;
int32_t zm_iglobalscaler;
int32_t zm_default_velocity;
int32_t zm_min_d;
int32_t zm_max_d;
int32_t zm_run_to_zero_speed;
int32_t zm_look_zero_edge_speed;
int32_t zm_vstart;
int32_t zm_a1;
int32_t zm_amax;
int32_t zm_v1;
int32_t zm_dmax;
int32_t zm_d1;
int32_t zm_vstop;
int32_t zm_tzerowait;
int32_t zm_enc_resolution;
int32_t zm_enable_enc;
int32_t zm_dzero; // 零点偏移
int32_t zm_io_trigger_append_distance;
int32_t zm_pos_devi_tolerance;
} config_t;
typedef struct {
int32_t enable; // 电机使能
int32_t load_val_ul; // 已装载量
int32_t aspirated; // 已经吸入过液体
int32_t lld_prepared; // 已经准备液面探测
int32_t pipette_is_inited; // 泵机是否初始化
int32_t dul; // 吸吐变化量
@ -107,6 +106,8 @@ class PipetteModuleV2 : public ZIModule {
int32_t aspirate_cfg_eigen_time; // 吸液操作验证,特征时间,用来检测气泡,吸空检测
int32_t aspirate_cfg_tolerance; // 容差
int32_t zmax_move_by; // 吸液Z轴最大移动距离
int32_t has_move_to_zero;
} state_t;
struct {
@ -156,12 +157,14 @@ class PipetteModuleV2 : public ZIModule {
/***********************************************************************************************************************
* Z轴控制 *
***********************************************************************************************************************/
virtual int32_t pipette_zmotor_enable(int32_t enable);
virtual int32_t pipette_zmotor_move_zero();
virtual int32_t pipette_zmotor_move_to_zero_point_quick();
virtual int32_t pipette_zmotor_measure_distance();
virtual int32_t pipette_zmotor_read_measure_distance_result(int32_t *result0);
virtual int32_t pipette_zmotor_move_by(int32_t distance);
virtual int32_t pipette_zmotor_move_to(int32_t position);
virtual int32_t pipette_init_device();
virtual int32_t pipette_put_tip();
virtual int32_t pipette_lld_prepare();
@ -211,7 +214,12 @@ class PipetteModuleV2 : public ZIModule {
void zm_waitfor_zm0p_trigger_and_stop_motor();
void zm_waitfor_zm0p_not_trigger_and_stop_motor();
void zm_waitfor_stop();
void pump_waitfor_stop();
int32_t pump_read_pos_ul(int32_t *val);
int32_t pump_read_capactitance(int32_t *val);
int32_t pump_read_tip_state(int32_t *val);
void pump_waitfor_stop();
// bool zm_wait_for_stop(int32_t checkperiod);
private:

6
sdk/components/zcancmder/zcan_protocol_parser.cpp

@ -151,6 +151,7 @@ void ZCanProtocolParser::initialize(IZCanReceiver* cancmder) {
REGFN(plate_code_scaner_open_laser);
REGFN(plate_code_scaner_close_laser);
REGFN(pipette_zmotor_enable);
REGFN(pipette_zmotor_move_zero);
REGFN(pipette_zmotor_move_to_zero_point_quick);
REGFN(pipette_zmotor_measure_distance);
@ -940,7 +941,10 @@ int32_t ZCanProtocolParser::plate_code_scaner_close_laser(cmdcontxt_t* cxt) {
* PipetteModuleV2 *
***********************************************************************************************************************/
#define MODULE_CLASS PipetteModuleV2
int32_t ZCanProtocolParser::pipette_zmotor_enable(cmdcontxt_t* cxt) {
CHECK_AND_GET_MODULE(1);
return module->pipette_zmotor_enable(cxt->params[0]);
}
int32_t ZCanProtocolParser::pipette_zmotor_move_zero(cmdcontxt_t* cxt) {
CHECK_AND_GET_MODULE(0);
return module->pipette_zmotor_move_zero();

2
sdk/components/zcancmder/zcan_protocol_parser.hpp

@ -184,6 +184,8 @@ class ZCanProtocolParser : public IZCanReceiverListener {
CMDFN(plate_code_scaner_open_laser);
CMDFN(plate_code_scaner_close_laser);
//
CMDFN(pipette_zmotor_enable);
CMDFN(pipette_zmotor_move_zero);
CMDFN(pipette_zmotor_move_to_zero_point_quick);
CMDFN(pipette_zmotor_measure_distance);

55
usrc/subboards/subboard80_cliptip/subboard80_cliptip.cpp

@ -53,41 +53,41 @@ void Subboard80Cliptip::initialize() {
{
static TMC51X0 motor;
static PipetteModuleV2 module;
int subid = 1;
int subid = 2;
TMC51X0::cfg_t tmc5130cfg = {
.spi = &hspi1,
.csgpio = PA4,
.ennPin = PD0,
.csgpio = MOTOR1_CSN,
.ennPin = MOTOR1_ENN,
};
motor.initialize(&tmc5130cfg);
motor.setMotorShaft(false);
static ZGPIO input[2];
input[0].initAsInput(PD2, ZGPIO::kMode_nopull, ZGPIO::kIRQ_noIrq, true);
input[1].initAsInput(PD1, ZGPIO::kMode_nopull, ZGPIO::kIRQ_noIrq, true);
input[0].initAsInput(MOTOR1_REFL, ZGPIO::kMode_nopull, ZGPIO::kIRQ_noIrq, MOTOR1_REFL_MIRROR);
input[1].initAsInput(MOTOR1_REFR, ZGPIO::kMode_nopull, ZGPIO::kIRQ_noIrq, MOTOR1_REFR_MIRROR);
PipetteModuleV2::config_t cfg = {0};
PipetteModuleV2::create_default_cfg(&cfg);
cfg.motor_shaft = false;
cfg.motor_one_circle_pulse = 80;
cfg.motor_one_circle_pulse_denominator = 1;
cfg.motor_ihold = 1;
cfg.motor_irun = 8;
cfg.motor_iholddelay = 10;
cfg.motor_iglobalscaler = 0;
cfg.motor_default_velocity = 500;
cfg.motor_min_d = 0;
cfg.motor_max_d = 0;
cfg.motor_run_to_zero_speed = 200;
cfg.motor_look_zero_edge_speed = 100;
cfg.motor_vstart = 100;
cfg.motor_a1 = 50;
cfg.motor_amax = 300;
cfg.motor_v1 = 300;
cfg.motor_dmax = 300;
cfg.motor_d1 = 50;
cfg.motor_vstop = 100;
cfg.motor_tzerowait = 0;
cfg.motor_enc_resolution = 0;
cfg.motor_enable_enc = 0;
cfg.motor_shaft = MOTOR1_MOTOR_SHAFT;
cfg.motor_one_circle_pulse = MOTOR1_MOTOR_ONE_CIRCLE_PULSE;
cfg.motor_one_circle_pulse_denominator = MOTOR1_MOTOR_ONE_CIRCLE_PULSE_DENOMINATOR;
cfg.motor_ihold = MOTOR1_STEPMOTOR_IHOLD;
cfg.motor_irun = MOTOR1_STEPMOTOR_IRUN;
cfg.motor_iholddelay = MOTOR1_STEPMOTOR_IHOLDDELAY;
cfg.motor_iglobalscaler = MOTOR1_STEPMOTOR_IGLOBALSCALER;
cfg.motor_default_velocity = MOTOR1_MOTOR_DEFAULT_VELOCITY;
cfg.motor_min_d = MOTOR1_MIN_D;
cfg.motor_max_d = MOTOR1_MAX_D;
cfg.motor_run_to_zero_speed = MOTOR1_MOTOR_RUN_TO_ZERO_SPEED;
cfg.motor_look_zero_edge_speed = MOTOR1_MOTOR_LOOK_ZERO_EDGE_SPEED;
cfg.motor_vstart = MOTOR1_MOTOR_VSTART;
cfg.motor_a1 = MOTOR1_MOTOR_A1;
cfg.motor_amax = MOTOR1_MOTOR_AMAX;
cfg.motor_v1 = MOTOR1_MOTOR_V1;
cfg.motor_dmax = MOTOR1_MOTOR_DMAX;
cfg.motor_d1 = MOTOR1_MOTOR_D1;
cfg.motor_vstop = MOTOR1_MOTOR_VSTOP;
cfg.motor_tzerowait = MOTOR1_MOTOR_TZEROWAIT;
cfg.motor_enc_resolution = MOTOR1_ENC_RESOLUTION;
cfg.motor_enable_enc = MOTOR1_ENABLE_ENC_RESOLUTION;
//
cfg.limit_ul = 30;
@ -103,7 +103,6 @@ void Subboard80Cliptip::initialize() {
module.initialize(getmoduleId(subid), &cfg, &hardwarecfg);
GService::inst()->getZCanProtocolParser()->registerModule(&module);
ZLOGI(TAG, "subboard80_cliptip pipette module initialized");
}
{

Loading…
Cancel
Save