From b6d9daac76a9ebae7ab1d05ab6bfc62b60d1a6b7 Mon Sep 17 00:00:00 2001 From: zhaohe Date: Thu, 5 Oct 2023 17:29:05 +0800 Subject: [PATCH] update --- components/pipette_module/pipette_ctrl_module.cpp | 122 +++++------------- components/pipette_module/pipette_ctrl_module.hpp | 37 +++--- .../zcancmder_module/zcan_pipette_module.cpp | 140 +++++++++++++++++++++ .../zcancmder_module/zcan_pipette_module.hpp | 18 +++ components/zprotocols/zcancmder | 2 +- 5 files changed, 213 insertions(+), 106 deletions(-) create mode 100644 components/zcancmder_module/zcan_pipette_module.cpp create mode 100644 components/zcancmder_module/zcan_pipette_module.hpp diff --git a/components/pipette_module/pipette_ctrl_module.cpp b/components/pipette_module/pipette_ctrl_module.cpp index b245d01..992f886 100644 --- a/components/pipette_module/pipette_ctrl_module.cpp +++ b/components/pipette_module/pipette_ctrl_module.cpp @@ -49,25 +49,36 @@ int32_t PipetteModule::zero_pos_calibrate(action_cb_status_t status_cb) { m_thread.start([this, status_cb]() { // DO("move_to_zero_with_calibrate_block", m_stepMotor->move_to_zero_with_calibrate_block(0)); - m_lastexecstatus = 0; - if (status_cb) status_cb(m_lastexecstatus); + call_status_cb(status_cb, 0); return; }); return 0; } -int32_t PipetteModule::reset_device(action_cb_status_t status_cb) { + +int32_t PipetteModule::zmotor_reset(action_cb_status_t status_cb) { ZLOGI(TAG, "reset_device"); if (!m_smtp2->isOnline()) return err::kce_device_offline; m_thread.stop(); m_thread.start([this, status_cb]() { - // 移液枪复位 - DO("init_device_block", m_smtp2->init_device_block()) // Z轴复位 DO("move_to_zero_block", m_stepMotor->move_to_zero_block()); // - m_lastexecstatus = 0; - if (status_cb) status_cb(m_lastexecstatus); + + call_status_cb(status_cb, 0); + }); + return 0; +} +int32_t PipetteModule::pipette_reset(action_cb_status_t status_cb) { + ZLOGI(TAG, "reset_device"); + if (!m_smtp2->isOnline()) return err::kce_device_offline; + + m_thread.stop(); + m_thread.start([this, status_cb]() { + // 移液枪复位 + DO("init_device_block", m_smtp2->init_device_block()) + + call_status_cb(status_cb, 0); }); return 0; } @@ -100,13 +111,12 @@ int32_t PipetteModule::take_tip(s16 vel, s16 height_mm, s16 tip_hight_mm, action DO("m_smtp2->read_tip_state(hastip)", m_smtp2->read_tip_state(hastip)); if (!hastip) { ZLOGE(TAG, "pipette gun take tip fail,no tip detected"); - m_lastexecstatus = err::kSMTP2_TipLoadFail; - if (status_cb) status_cb(m_lastexecstatus); + + call_status_cb(status_cb, err::kSMTP2_TipLoadFail); return; } - m_lastexecstatus = 0; - if (status_cb) status_cb(m_lastexecstatus); + call_status_cb(status_cb, 0); }); return 0; } @@ -129,8 +139,7 @@ int32_t PipetteModule::remove_tip(s16 vel, s16 height_mm, action_cb_status_t sta ZLOGI(TAG, "move to transfer_height_mm %d", m_transfer_height_mm); DO("move_to_block", m_stepMotor->move_to_block(vel, hight_trans(m_transfer_height_mm))); - m_lastexecstatus = 0; - if (status_cb) status_cb(m_lastexecstatus); + call_status_cb(status_cb, 0); }); return 0; } @@ -141,8 +150,8 @@ int32_t PipetteModule::move_to(s16 vel, s16 height_mm, action_cb_status_t status m_thread.start([this, vel, height_mm, status_cb]() { ZLOGI(TAG, "move to transfer_height_mm %d", height_mm); DO("m_stepMotor->move_to_block(targethith)", m_stepMotor->move_to_block(vel, hight_trans(height_mm))); - m_lastexecstatus = 0; - if (status_cb) status_cb(m_lastexecstatus); + + call_status_cb(status_cb, 0); }); return 0; } @@ -168,7 +177,9 @@ int32_t PipetteModule::exec_move_to_with_lld(s16 vel, s16 lld_cap_thr, s16 lld_m if (periodcount % 100 == 0) { ZLOGI(TAG, "capacitance %d", capacitance); } + return int32_t(0); }); + } int32_t PipetteModule::move_to_with_lld( // @@ -187,8 +198,7 @@ int32_t PipetteModule::move_to_with_lld( // } DO("m_stepMotor->move_to_block(targethith)", m_stepMotor->move_to_block(vel, hight_trans(targethith))); - m_lastexecstatus = 0; - if (status_cb) status_cb(m_lastexecstatus); + call_status_cb(status_cb, 0); }); return 0; } @@ -202,8 +212,7 @@ int32_t PipetteModule::shake_volume(s16 shake_times, s16 shake_volume, action_cb } DO("m_smtp2->move_to_ul(0)", m_smtp2->move_to_ul(0)); - m_lastexecstatus = 0; - if (status_cb) status_cb(m_lastexecstatus); + call_status_cb(status_cb, 0); }); return 0; } @@ -212,80 +221,12 @@ int32_t PipetteModule::take_and_split_liquid(s16 take_volume_mm, action_cb_statu m_thread.stop(); m_thread.start([this, take_volume_mm, status_cb]() { DO("m_stepMotor->move_to_block(nowpos)", m_smtp2->move_to_ul(take_volume_mm)); - m_lastexecstatus = 0; - if (status_cb) status_cb(m_lastexecstatus); - }); - return 0; -} -#if 0 -int32_t PipetteModule::take_and_split_liquid(s16 max_deep_height_mm, // - s16 lld_rela_hight_mm, // - s16 shake_times, // - s16 shake_volume, // - s16 take_volume_mm, // - action_cb_status_t status_cb) { - ZLOGI(TAG, "take_and_split_liquid %d %d %d %d %d", max_deep_height_mm, lld_rela_hight_mm, shake_times, shake_volume, take_volume_mm); - - m_thread.stop(); - m_thread.start([this, max_deep_height_mm, lld_rela_hight_mm, shake_times, shake_volume, take_volume_mm, status_cb]() { - /** - * @brief - * 1. 移动移液枪 探测当前移液枪电容压力,当压力达到阈值后,停止移动 - * 2. 获取当前位置,移动移液枪到指定相对液面高度 - * 3. 吸吐指定体积多次 - * 4. 吸取液体 - */ - // 1. 移动移液枪,探测当前移液枪电容压力,当压力达到阈值后,停止移动 - DO("m_stepMotor->move_to(max_deep_height_mm)", // - m_stepMotor->do_motor_action_block_2( // - [this, max_deep_height_mm]() { return m_stepMotor->move_to(max_deep_height_mm, nullptr); }, // - [this](bool &reachtarget, int periodcount) { - int32_t capacitance = 0; - int32_t ret = m_smtp2->read_capacitance_val(capacitance); - if (ret != 0) { - ZLOGE(TAG, "read_capacitance_val fail, ret = %d", ret); - return ret; - } - - if (capacitance > m_base_param.lld_capacitance_threshold) { - ZLOGI(TAG, "capacitance %d reach threshold %d", capacitance, m_base_param.lld_capacitance_threshold); - reachtarget = true; - } - if (periodcount % 100 == 0) { - ZLOGI(TAG, "capacitance %d", capacitance); - } - })); - - // 2. 获取当前位置,移动移液枪到指定相对液面高度 - int32_t nowpos; - DO("readpos", m_stepMotor->read_pos(nowpos)); - int32_t targethith = nowpos + lld_rela_hight_mm; - if (targethith > max_deep_height_mm) { - targethith = max_deep_height_mm; - } - - DO("m_stepMotor->move_to_block(targethith)", m_stepMotor->move_to_block(targethith)); - - // 3. 吸吐指定体积多次 - for (size_t i = 0; i < shake_times; i++) { - DO("m_smtp2->move_to_ul(0)", m_smtp2->move_to_ul(0)); - DO("m_smtp2->move_to_ul(shake_volume)", m_smtp2->move_to_ul(shake_volume)); - } - DO("m_smtp2->move_to_ul(0)", m_smtp2->move_to_ul(0)); - - // 4. 吸取液体 - DO("m_stepMotor->move_to_block(nowpos)", m_smtp2->move_to_ul(take_volume_mm)); - - // 5. 移动移液枪到移动位置 - DO("m_stepMotor->move_to_block(nowpos)", m_stepMotor->move_to_block(nowpos)); - - m_lastexecstatus = 0; - if (status_cb) status_cb(m_lastexecstatus); + call_status_cb(status_cb, 0); }); return 0; } -#endif + int32_t PipetteModule::hight_trans(s16 targethith, s16 &motormovehight) { motormovehight = targethith; @@ -325,6 +266,7 @@ int32_t PipetteModule::get_status(status_t &status) { status.has_tip = m_smtp2->read_tip_state(); status.zpos_mm = m_stepMotor->read_pos(); status.pipette_ul = m_smtp2->read_pos_ul(); + return 0; } s16 PipetteModule::hight_trans(s16 targethith) { @@ -336,3 +278,5 @@ s16 PipetteModule::hight_trans(s16 targethith) { } return realhight; } + +void PipetteModule::call_status_cb(action_cb_status_t status_cb, int32_t status) { call_status_cb(status_cb, status); } diff --git a/components/pipette_module/pipette_ctrl_module.hpp b/components/pipette_module/pipette_ctrl_module.hpp index 3cf3bc8..34d5092 100644 --- a/components/pipette_module/pipette_ctrl_module.hpp +++ b/components/pipette_module/pipette_ctrl_module.hpp @@ -2,9 +2,10 @@ // #include "sdk/os/zos.hpp" #include "sdk\components\sensors\smtp2\smtp2.hpp" -#include "sdk\components\step_motor_ctrl_module\step_motor_ctrl_module.hpp" #include "sdk\components\tmc\basic\tmc_ic_interface.hpp" #include "sdk\components\zprotocols\zcancmder\api\i_pipette_module.hpp" +#include "sdk\components\zprotocols\zcancmder\api\i_step_motor_ctrl_module.hpp" +#include "sdk\components\step_motor_ctrl_module\step_motor_ctrl_module.hpp" // #include "StepMotorCtrlModule" namespace iflytop { @@ -22,43 +23,47 @@ class PipetteModule : public I_PipetteModule { base_param_t m_base_param; int16_t m_transfer_height_mm = 0; + public: void initialize(SMTP2 *smtp2, StepMotorCtrlModule *stepMotor); /******************************************************************************* * ACTION * *******************************************************************************/ - virtual int32_t enable(u8 enable); - virtual int32_t stop(u8 stop_type); + virtual int32_t enable(u8 enable) override; + virtual int32_t stop(u8 stop_type) override; + + virtual int32_t zero_pos_calibrate(action_cb_status_t status_cb) override; - virtual int32_t zero_pos_calibrate(action_cb_status_t status_cb); - virtual int32_t reset_device(action_cb_status_t status_cb); + virtual int32_t zmotor_reset(action_cb_status_t status_cb) override; + virtual int32_t pipette_reset(action_cb_status_t status_cb) override; - virtual int32_t take_tip(s16 vel, s16 height_mm, s16 tip_hight_mm, action_cb_status_t status_cb); - virtual int32_t remove_tip(s16 vel, s16 height_mm, action_cb_status_t status_cb); + virtual int32_t take_tip(s16 vel, s16 height_mm, s16 tip_hight_mm, action_cb_status_t status_cb) override; + virtual int32_t remove_tip(s16 vel, s16 height_mm, action_cb_status_t status_cb) override; - virtual int32_t move_to(s16 vel, s16 height_mm, action_cb_status_t status_cb); - virtual int32_t move_to_with_lld(s16 vel, s16 lld_cap_thr, s16 lld_max_hight_mm, s16 lld_rela_hight_mm, action_cb_status_t status_cb); - virtual int32_t shake_volume(s16 shake_times, s16 shake_volume, action_cb_status_t status_cb); - virtual int32_t take_and_split_liquid(s16 take_volume_mm, action_cb_status_t status_cb); + virtual int32_t move_to(s16 vel, s16 height_mm, action_cb_status_t status_cb) override; + virtual int32_t move_to_with_lld(s16 vel, s16 lld_cap_thr, s16 lld_max_hight_mm, s16 lld_rela_hight_mm, action_cb_status_t status_cb) override; + virtual int32_t shake_volume(s16 shake_times, s16 shake_volume, action_cb_status_t status_cb) override; + virtual int32_t take_and_split_liquid(s16 take_volume_mm, action_cb_status_t status_cb) override; /******************************************************************************* * ReadStatus * *******************************************************************************/ - virtual int32_t get_status(status_t &status); + virtual int32_t get_status(status_t &status) override; /******************************************************************************* * SETTING * *******************************************************************************/ - virtual int32_t set_z_motor_para(const I_StepMotorCtrlModule::base_param_t &z_motor_param); - virtual int32_t get_z_motor_para(I_StepMotorCtrlModule::base_param_t &z_motor_param); - virtual int32_t set_base_param(const base_param_t &base_param); - virtual int32_t get_base_param(base_param_t &base_param); + virtual int32_t set_z_motor_para(const I_StepMotorCtrlModule::base_param_t &z_motor_param) override; + virtual int32_t get_z_motor_para(I_StepMotorCtrlModule::base_param_t &z_motor_param) override; + virtual int32_t set_base_param(const base_param_t &base_param) override; + virtual int32_t get_base_param(base_param_t &base_param) override; public: int32_t exec_move_to_with_lld(s16 vel, s16 lld_cap_thr, s16 lld_max_hight_mm); int32_t hight_trans(s16 targethith, s16 &motormovehight); s16 hight_trans(s16 targethith); + void call_status_cb(action_cb_status_t status_cb, int32_t status); }; } // namespace iflytop \ No newline at end of file diff --git a/components/zcancmder_module/zcan_pipette_module.cpp b/components/zcancmder_module/zcan_pipette_module.cpp new file mode 100644 index 0000000..73ce867 --- /dev/null +++ b/components/zcancmder_module/zcan_pipette_module.cpp @@ -0,0 +1,140 @@ +#include "zcan_pipette_module.hpp" +using namespace iflytop; + +#define TAG "ZcanPipetteModule" +#if 1 +void ZcanPipetteModule::initialize(ZCanCmder* cancmder, int id, I_PipetteModule* module) { + m_cancmder = cancmder; + m_id = id; + m_module = module; + cancmder->registerListener(this); +} +void ZcanPipetteModule::onRceivePacket(CanPacketRxBuffer* rxcmd) { + // printf("ZcanPipetteModule::onRceivePacket %d %d\n", rxcmd->get_cmdheader()->cmdid, rxcmd->get_cmdheader()->subcmdid); + +#if 0 + kcmd_pipette_module_z_motor_enable = CMDID(1016, 0), // 使能 + kcmd_pipette_module_z_motor_move_to = CMDID(1016, 1), // 移动到 + kcmd_pipette_module_z_motor_move_to_zero = CMDID(1016, 2), // 归零 + kcmd_pipette_module_z_motor_move_to_zero_with_calibrate = CMDID(1016, 3), // 归零并校准 + kcmd_pipette_module_z_motor_stop = CMDID(1016, 4), // 停止 + + kcmd_pipette_module_take_liquid = CMDID(1016, 4), // 取液体 + kcmd_pipette_module_split_liquid = CMDID(1016, 5), // 吐液体 + kcmd_pipette_module_take_tip = CMDID(1016, 6), // 取tip + kcmd_pipette_module_remove_tip = CMDID(1016, 7), // 移除tip + + kcmd_pipette_module_read_version = CMDID(1016, 50), // 读取模块型号版本信息 + kcmd_pipette_module_read_status = CMDID(1016, 51), // 读取模块精简状态信息 + kcmd_pipette_module_read_detailed_status = CMDID(1016, 52), // 读取模块详细状态信息 + + kcmd_pipette_module_set_run_param = CMDID(1016, 100), // 设置运行参数 + kcmd_pipette_module_set_warning_limit_param = CMDID(1016, 101), // 设置限制参数 + kcmd_pipette_module_set_run_to_zero_param = CMDID(1016, 102), // 设置归零参数 +#endif + + + +#if 0 + PROCESS_PACKET(kcmd_step_motor_ctrl_enable, m_id) { errorcode = m_module->enable(cmd->enable); } + END_PP(); + + PROCESS_PACKET(kcmd_step_motor_ctrl_stop, m_id) { errorcode = m_module->stop(cmd->stop_type); } + END_PP(); + + PROCESS_PACKET(kcmd_step_motor_ctrl_move_to_zero, m_id) { + errorcode = m_module->move_to_zero([this, cmdheader](int32_t status) { + osDelay(5); // 用来保证回执消息在前面 + kcmd_step_motor_ctrl_move_to_zero_report_t report = {0}; + ZLOGI(TAG, "kcmd_step_motor_ctrl_move_to_zero exec_status:%d", status); + + report.id = m_id; + report.exec_status = status; + m_cancmder->sendExecStatusReport(cmdheader, (uint8_t*)&report, sizeof(report)); + }); + } + END_PP(); + PROCESS_PACKET(kcmd_step_motor_ctrl_move_to_zero_with_calibrate, m_id) { + errorcode = m_module->move_to_zero_with_calibrate(cmd->nowx, [this, cmdheader](int32_t status) { + osDelay(5); // 用来保证回执消息在前面 + kcmd_step_motor_ctrl_move_to_zero_with_calibrate_report_t report = {0}; + ZLOGI(TAG, "kcmd_step_motor_ctrl_move_to_zero_with_calibrate exec_status:%d", status); + + report.id = m_id; + report.exec_status = status; + m_cancmder->sendExecStatusReport(cmdheader, (uint8_t*)&report, sizeof(report)); + }); + } + END_PP(); + + PROCESS_PACKET(kcmd_step_motor_ctrl_move_to, m_id) { + errorcode = m_module->move_to(cmd->x, [this, cmdheader](int32_t status) { + osDelay(5); // 用来保证回执消息在前面 + kcmd_step_motor_ctrl_move_to_report_t report = {0}; + ZLOGI(TAG, "kcmd_step_motor_ctrl_move_to exec_status:%d ", status); + + report.id = m_id; + report.exec_status = status; + m_cancmder->sendExecStatusReport(cmdheader, (uint8_t*)&report, sizeof(report)); + }); + } + END_PP(); + + PROCESS_PACKET(kcmd_step_motor_ctrl_move_by, m_id) { + errorcode = m_module->move_by(cmd->dx, [this, cmdheader](int32_t status) { + osDelay(5); // 用来保证回执消息在前面 + kcmd_step_motor_ctrl_move_by_report_t report = {0}; + // ZLOGI(TAG, "kcmd_step_motor_ctrl_move_by exec_status:%d %d", status.exec_status, status.dx); + ZLOGI(TAG, "kcmd_step_motor_ctrl_move_by exec_status:%d ", status); + + report.id = m_id; + report.exec_status = status; + m_cancmder->sendExecStatusReport(cmdheader, (uint8_t*)&report, sizeof(report)); + }); + } + END_PP(); + + PROCESS_PACKET(kcmd_step_motor_ctrl_force_change_current_pos, m_id) { errorcode = m_module->force_change_current_pos(cmd->x); } + END_PP(); + + PROCESS_PACKET(kcmd_step_motor_ctrl_rotate, m_id) { + errorcode = m_module->rotate(cmd->speed, cmd->run_time, [this, cmdheader](int32_t status) { + osDelay(5); // 用来保证回执消息在前面 + kcmd_step_motor_ctrl_rotate_report_t report = {0}; + // ZLOGI(TAG, "kcmd_step_motor_ctrl_rotate exec_status:%d %d", status.exec_status, status.lastforms); + ZLOGI(TAG, "kcmd_step_motor_ctrl_rotate exec_status:%d ", status); + + report.id = m_id; + report.exec_status = status; + m_cancmder->sendExecStatusReport(cmdheader, (uint8_t*)&report, sizeof(report)); + }); + } + END_PP(); + + PROCESS_PACKET(kcmd_step_motor_ctrl_read_version, m_id) { // + errorcode = m_module->read_version(ack->ack); + } + END_PP(); + + PROCESS_PACKET(kcmd_step_motor_ctrl_read_status, m_id) { // + errorcode = m_module->read_status(ack->ack); + } + END_PP(); + + PROCESS_PACKET(kcmd_step_motor_ctrl_read_detailed_status, m_id) { // + errorcode = m_module->read_detailed_status(ack->ack); + } + END_PP(); + + PROCESS_PACKET(kcmd_step_motor_ctrl_set_base_param, m_id) { // + errorcode = m_module->set_base_param(cmd->param); + } + END_PP(); + + PROCESS_PACKET(kcmd_step_motor_ctrl_get_base_param, m_id) { // + errorcode = m_module->get_base_param(ack->ack); + } + END_PP(); +#endif +} +#endif \ No newline at end of file diff --git a/components/zcancmder_module/zcan_pipette_module.hpp b/components/zcancmder_module/zcan_pipette_module.hpp new file mode 100644 index 0000000..575c717 --- /dev/null +++ b/components/zcancmder_module/zcan_pipette_module.hpp @@ -0,0 +1,18 @@ +#pragma once +// #include "sdk/components/zprotocols/zcancmder/api/i_step_motor_ctrl_module.hpp" +#include "sdk/components/zprotocols/zcancmder/api/i_pipette_module.hpp" +#include "sdk\components\zcancmder\zcanreceiver.hpp" +namespace iflytop { + +class ZcanPipetteModule : public ZCanCmderListener { + ZCanCmder* m_cancmder = nullptr; + int m_id = 0; + I_PipetteModule* m_module; + + uint8_t m_txbuf[128] = {0}; + + public: + void initialize(ZCanCmder* cancmder, int id, I_PipetteModule* module); + virtual void onRceivePacket(CanPacketRxBuffer* rxcmd); +}; +} // namespace iflytop diff --git a/components/zprotocols/zcancmder b/components/zprotocols/zcancmder index fc43406..eff35f5 160000 --- a/components/zprotocols/zcancmder +++ b/components/zprotocols/zcancmder @@ -1 +1 @@ -Subproject commit fc4340666e8afc748a8adb759439c561b62afa5d +Subproject commit eff35f5c915ddaa15cced3796ce2ba7c93ea5029