Browse Source

update

master
zhaohe 1 year ago
parent
commit
e37fe84bc7
  1. 74
      components/pipette_module/pipette_ctrl_module_v2.cpp
  2. 26
      components/pipette_module/pipette_ctrl_module_v2.hpp
  3. 99
      components/sensors/smtp2_v2/smtp2_v2.cpp
  4. 167
      components/sensors/smtp2_v2/smtp2_v2.hpp
  5. 10
      components/zcancmder/zcan_protocol_parser.cpp
  6. 1
      components/zcancmder/zcan_protocol_parser.hpp

74
components/pipette_module/pipette_ctrl_module_v2.cpp

@ -19,7 +19,7 @@ void PipetteModule::initialize(int32_t id, config_t *config, hardward_config_t *
ZASSERT(hardwaredcfg != nullptr);
m_id = id;
m_config = *config;
m_smtp2.initialize(hardwaredcfg->uart, hardwaredcfg->hdma_rx, hardwaredcfg->hdma_tx);
m_smtp2.initialize(hardwaredcfg->uart, 0, hardwaredcfg->hdma_rx, hardwaredcfg->hdma_tx);
m_thread.init("pipette_ctrl", 1024);
}
@ -44,8 +44,6 @@ int32_t PipetteModule::module_break() {
return 0;
}
int32_t PipetteModule::module_xxx_reg(int32_t param_id, bool read, int32_t &val) {
switch (param_id) {
MODULE_COMMON_PROCESS_REG_CB();
@ -66,7 +64,7 @@ int32_t PipetteModule::module_get_status(int32_t *status) {
if (ecode != 0) {
creg.module_errorcode = ecode;
*status = 3;
*status = 3;
m_thread.stop();
return 0;
}
@ -84,16 +82,16 @@ int32_t PipetteModule::module_get_status(int32_t *status) {
int32_t PipetteModule::pipette_ctrl_init_device() {
ZLOGI(TAG, "pipette_ctrl_init_device");
if (!m_smtp2.isOnline()) return err::kdevice_offline;
m_thread.stop();
m_thread.start([this]() { DO("init_device_block", m_smtp2.init_device_block()); });
// if (!m_smtp2.isOnline()) return err::kdevice_offline;
// m_thread.stop();
// m_thread.start([this]() { DO("init_device_block", m_smtp2.init_device_block()); });
return 0;
};
int32_t PipetteModule::pipette_ctrl_put_tip() {
ZLOGI(TAG, "pipette_ctrl_put_tip");
if (!m_smtp2.isOnline()) return err::kdevice_offline;
m_thread.stop();
m_thread.start([this]() { DO("put_tip_block", m_smtp2.put_tip_block()); });
// if (!m_smtp2.isOnline()) return err::kdevice_offline;
// m_thread.stop();
// m_thread.start([this]() { DO("put_tip_block", m_smtp2.put_tip_block()); });
return 0;
};
int32_t PipetteModule::pipette_ctrl_move_to_ul(int32_t ul) {
@ -102,33 +100,51 @@ int32_t PipetteModule::pipette_ctrl_move_to_ul(int32_t ul) {
return err::kparam_out_of_range;
}
if (!m_smtp2.isOnline()) return err::kdevice_offline;
m_thread.stop();
m_thread.start([this, ul]() { DO("move_to_ul_block", m_smtp2.move_to_ul_block(ul)); });
// if (!m_smtp2.isOnline()) return err::kdevice_offline;
// m_thread.stop();
// m_thread.start([this, ul]() { DO("move_to_ul_block", m_smtp2.move_to_ul_block(ul)); });
return 0;
};
int32_t PipetteModule::pipette_write_cmd_direct(uint8_t *tx, int32_t len, uint8_t *rx, int32_t *rxlen) {
bool suc = m_smtp2.write_cmd((char *)tx);
if (!suc) {
return err::ksubdevice_overtime;
}
m_smtp2.getack((char *)rx, rxlen);
return 0;
}
/*******************************************************************************
* PRIVATE *
*******************************************************************************/
int32_t PipetteModule::read_pos_ul(int32_t *val) { return m_smtp2.read_pos_ul(*val); }
int32_t PipetteModule::read_capactitance(int32_t *val) { return m_smtp2.read_capacitance_val(*val); }
int32_t PipetteModule::read_pos_ul(int32_t *val) {
return 0;
// return m_smtp2.read_pos_ul(*val);
}
int32_t PipetteModule::read_capactitance(int32_t *val) {
return 0;
// return m_smtp2.read_capacitance_val(*val);
}
int32_t PipetteModule::read_tip_state(int32_t *val) {
bool tipstate = false;
int32_t ecode = m_smtp2.read_tip_state(tipstate);
*val = tipstate ? 1 : 0;
return ecode;
*val = 0;
return 0;
// bool tipstate = false;
// int32_t ecode = m_smtp2.read_tip_state(tipstate);
// *val = tipstate ? 1 : 0;
// return ecode;
}
int32_t PipetteModule::_read_error_status() {
bool isbusy = false;
err::error_t errorcode = err::ksucc;
int32_t retecode = m_smtp2.getState(isbusy, errorcode);
if (retecode != 0) {
return retecode;
}
if (errorcode != err::ksucc && errorcode != err::kSMTP2_NoError) {
return errorcode;
}
return 0;
// bool isbusy = false;
// err::error_t errorcode = err::ksucc;
// int32_t retecode = m_smtp2.getState(isbusy, errorcode);
// if (retecode != 0) {
// return retecode;
// }
// if (errorcode != err::ksucc && errorcode != err::kSMTP2_NoError) {
// return errorcode;
// }
// return 0;
}

26
components/pipette_module/pipette_ctrl_module_v2.hpp

@ -1,8 +1,8 @@
#pragma once
//
#include "sdk/os/zos.hpp"
#include "sdk\components\sensors\smtp2\smtp2.hpp"
#include "a8000_protocol\protocol.hpp"
#include "sdk/os/zos.hpp"
#include "sdk\components\sensors\smtp2_v2\smtp2_v2.hpp"
// #include "StepMotorCtrlModule"
/**
@ -14,7 +14,7 @@
namespace iflytop {
class PipetteModule : public ZIModule, public ZIPipetteCtrlModule {
ENABLE_MODULE(PipetteModule, kpipette_ctrl_module,PC_VERSION);
ENABLE_MODULE(PipetteModule, kpipette_ctrl_module, PC_VERSION);
public:
typedef struct {
@ -28,10 +28,10 @@ class PipetteModule : public ZIModule, public ZIPipetteCtrlModule {
} config_t;
private:
SMTP2 m_smtp2;
ZThread m_thread;
smtp2::SMTP2V2 m_smtp2;
ZThread m_thread;
int32_t m_id = 0;
int32_t m_id = 0;
config_t m_config;
public:
@ -43,9 +43,9 @@ class PipetteModule : public ZIModule, public ZIPipetteCtrlModule {
* Module *
*******************************************************************************/
virtual int32_t module_enable(int32_t enable) ;
virtual int32_t module_stop() ;
virtual int32_t module_break() ;
virtual int32_t module_enable(int32_t enable);
virtual int32_t module_stop();
virtual int32_t module_break();
virtual int32_t module_get_status(int32_t *status) override;
@ -56,12 +56,12 @@ class PipetteModule : public ZIModule, public ZIPipetteCtrlModule {
virtual int32_t pipette_ctrl_init_device() override;
virtual int32_t pipette_ctrl_put_tip() override;
virtual int32_t pipette_ctrl_move_to_ul(int32_t ul) override;
virtual int32_t pipette_write_cmd_direct(uint8_t *tx, int32_t len, uint8_t *rx, int32_t *rxlen) override;
private:
int32_t read_pos_ul(int32_t *val);
int32_t read_capactitance(int32_t *val);
int32_t read_tip_state(int32_t *val);
int32_t read_pos_ul(int32_t *val);
int32_t read_capactitance(int32_t *val);
int32_t read_tip_state(int32_t *val);
virtual int32_t module_xxx_reg(int32_t param_id, bool read, int32_t &val) override;
private:

99
components/sensors/smtp2_v2/smtp2_v2.cpp

@ -0,0 +1,99 @@
#include "smtp2_v2.hpp"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "a8000_protocol\protocol.hpp"
using namespace iflytop;
using namespace smtp2;
#define TAG "SMTP2"
#define OVERTIME 30
#define DUMP_HEX 1
void SMTP2V2::initialize(UART_HandleTypeDef* uart, uint8_t id, DMA_HandleTypeDef* hdma_rx, DMA_HandleTypeDef* hdma_tx) {
m_uart = uart;
m_hdma_rx = hdma_rx;
m_hdma_tx = hdma_tx;
m_id = id;
}
void SMTP2V2::pump_init_cfg() {}
void SMTP2V2::pump_ping() {}
bool SMTP2V2::write_cmd(const char* cmd) { return sendcmd(cmd); }
void SMTP2V2::getack(char* rx, int32_t* rxbufsize) {
*rxbufsize = m_rxNum;
memcpy(rx, m_rxbuf, m_rxNum);
}
/***********************************************************************************************************************
* BASIC *
***********************************************************************************************************************/
int32_t SMTP2V2::getAckEcode() {
if (m_rxNum < 3) {
return err::kdevice_is_offline;
}
uint8_t errorcode = (uint8_t)m_rxbuf[2];
if (errorcode >= '`') {
errorcode = errorcode - '`';
} else if (errorcode >= '@') {
errorcode = errorcode - '@';
}
return (err::error_t)errorcode;
}
bool SMTP2V2::sendcmd(const char* cmd) {
for (size_t i = 0; i < 5; i++) {
if (_sendcmd(cmd)) {
break;
}
m_rxNum = 0;
return false;
}
return true;
}
bool SMTP2V2::_sendcmd(const char* cmd) {
#ifdef DUMP_HEX
ZLOGI(TAG, "tx:%s", cmd);
#endif
bool ret = _sendcmd_dma(cmd);
#ifdef DUMP_HEX
ZLOGI(TAG, "rx:%s", m_rxbuf);
#endif
return ret;
}
bool SMTP2V2::_sendcmd_dma(const char* cmd) {
memset(m_rxbuf, 0, SMTP2_BUF_LEN);
uint8_t rxdata;
// clear rx buf
while (HAL_UART_Receive(m_uart, &rxdata, 1, 1) == HAL_OK) {
}
uint32_t enter_ticket = HAL_GetTick();
HAL_UARTEx_ReceiveToIdle_DMA(m_uart, (uint8_t*)m_rxbuf, SMTP2_BUF_LEN);
HAL_UART_Transmit(m_uart, (uint8_t*)cmd, strlen(cmd), 1000);
bool overtime_flag = false;
while (HAL_UART_GetState(m_uart) == HAL_UART_STATE_BUSY_RX || //
HAL_UART_GetState(m_uart) == HAL_UART_STATE_BUSY_TX_RX) {
osDelay(1);
if (zos_haspassedms(enter_ticket) > OVERTIME) {
// ZLOGW(TAG, "sendcmd_dma overtime");
overtime_flag = true;
break;
}
}
HAL_UART_DMAStop(m_uart);
if (overtime_flag) {
return false;
}
m_rxNum = SMTP2_BUF_LEN - __HAL_DMA_GET_COUNTER(m_hdma_rx);
return true;
}

167
components/sensors/smtp2_v2/smtp2_v2.hpp

@ -0,0 +1,167 @@
#pragma once
#include "a8000_protocol\protocol.hpp"
#include "sdk\os\zos.hpp"
namespace iflytop {
using namespace std;
/**
* @brief
*
* ref:https://iflytop1.feishu.cn/wiki/VNNRwUJCtiuRDHkD1uScGIA1nMf
* WARNING:
* 1,
*/
namespace smtp2 {
#define SMTP2_BUF_LEN 128
typedef enum {
kcmd_pump_init, // [Z]初始化
kcmd_pump_move_to, // A<n>
kcmd_pump_move_by_absorb, // P<n>相对吸取
kcmd_pump_move_by_distribut, // D<n>相对分配
kcmd_pump_set_acc_and_dec, // L<n1>,<n2>设置加速度,和减速度
kcmd_pump_set_start_v, // v<n>
kcmd_pump_set_max_v, // V<n>
kcmd_pump_set_stop_v, // c<n>
kcmd_pump_set_back_clearance_increment, // K<n>背隙增量
kcmd_pump_set_increment_mode, // N<n>选择增量模式 0 正常模式,1 微增量模式 2 纳升
kcmd_pump_stop, // H
kcmd_pump_clear_cmd_buf, // C 清除命令缓冲区
kcmd_pump_pop_tip, // E<n>弹出 Tip
kcmd_pump_pLLD, // t<n1>,<n2>
kcmd_pump_cLLD, // ^<n>
kcmd_pump_mixLLD, // B<n1>,<n2>
kcmd_pump_set_pressure_gain, // <p>设定压力传感器增益
kcmd_pump_verify_operation, // q<n1>,<n2>操作验证
kcmd_pump_reset, // "!0"
kcmd_pump_factory_reset, // "!22"
} cmd_t;
typedef enum {
kcfg_pump_limit_ul = 1, // 最大行程(Tip尺寸) 1...3500 default:3143
kcfg_baudrate = 2, // 0:9600 1:38400 default:1
kcfg_communication_protocol = 3,
kcfg_pressure_data_port_channel = 4, // 压力数据流端口 0=无 1=RS232 3=CAN
kcfg_can_enable = 5, // CAN总线使能
kcfg_can_baudrate = 6, // CAN总线波特率
kcfg_back_clearance_increment = 7, // 背隙增量
kcfg_moving_average_window_size = 8, // 移动平均窗口大小 default:3
kcfg_io1_mode = 9, // I/O 1 0=LLD输出高 1=LLD输出低 2=通用输出 default:0
kcfg_io2_mode = 10, // I/O 2 0=通用输入 1=紧急制动 2=Tip脱落输出高 3=Tip脱落输出低 default:0
kcfg_origin_offset = 12, // 原点偏移(往吸取方向)0...300 default:112
kcfg_motor_hold_current = 13, // 电机保持电流(单位:0.01A)0...200 default:10
kcfg_motor_run_current = 14, // 电机运行电流(单位:0.01A)0...200 default:25
kcfg_pLLD_start_delay = 15, // pLLD启动延迟(毫秒)0...2000 default:100
kcfg_nL_increment = 16, // 纳升/增量。此值用于将[N2]模式的nL 输入和输出转换为增量。 (当前系统中不使用)
kcfg_total_range = 17, // 用nL表示的总量程。当这个值被改变时,u1所设定的值也会按照这个公式自动变更:u1=u17/u16 同时,u1改变时,此值也会自动变更:u17=u1*u16 (当前系统中不使用)
kcfg_tip_size = 18, // Tip大小。对此值进行设置之后,u1和u17的值将会自动进行变更。 (当前系统中不使用)
kcfg_default_tolerance = 21, // [q] 命令默认容差
kcfg_pressure_data_stream_time = 22, // 泵运动完成后保持压力数据流输出的时间(毫秒)。请参见[+]命令。
kcfg_auto_temp_compensation = 24, // 自动使用温度补偿。
kcfg_temp_compensation_rate = 25, // 温度补偿率,单位:增量/℃/mL 注意:[*]命令覆盖此设置。
kcfg_temp_value = 26, // 环境温度*100(例如,24°C*100=2400)与温度补偿一起使用 注意:[*]命令覆盖此设置。
kcfg_enable_tip_block_check = 32, // [q]命令的“Tip堵塞”检查功能
kcfg_enable_operation_check = 33, // [q]命令的“操作量”检查功能
kcfg_enable_air_inlet_check = 34, // [q]命令的“空气进液”检查功能
kcfg_enable_bubble_foam_check = 35, // [q]命令的“气泡/泡沫”检查功能
} cfg_t;
typedef enum {
kstate_pump_pos = 0, // 泵位置
kstate_pump_pos_mm = 2, // 泵位置(毫米)
kstate_pump_pos_nl = 3, // 泵位置(纳升)
kstate_back_clearance = 4, // 背隙[K],泵位置
kstate_start_v = 6, // 启动速度[v]
kstate_max_v = 7, // 最高速度[V]
kstate_stop_v = 8, // 停止速度[c]
kstate_acc = 9, // 加速度的[L]值
kstate_dec = 10, // 减速度的[L]值
kstate_motor_irun = 11, // 泵电机运行电流,单位0.01A
kstate_motor_ihold = 12, // 泵电机保持电流,单位0.01A
kstate_total_range = 17, // 最大行程
kstate_firmware = 23, // 固件版本
kstate_cfg = 27, // [u]命令设置值
kstate_pump_status = 29, // 泵状态
kstate_io2 = 30, // I/O2输入状态
kstate_tip_state = 31, // Tip装载状态
kstate_moving_average = 38, // 压力检测值的移动平均窗口大小
kstate_power_on_times = 41, // 自出厂以来,泵上电的总次数
kstate_init_times = 42, // 自出厂以来,泵初始化总次数
kstate_init_times_cur = 43, // 本次通电后的泵初始化次数
kstate_moving_distance = 44, // 自出厂以来,泵的运动距离(单位:毫米)
kstate_piston_move_times = 45, // 自出厂以来,活塞移动次数
kstate_piston_move_times_cur = 46, // 本次通电后的活塞移动次数
kstate_pop_tip_times = 47, // 自出厂以来,弹出Tip的次数
kstate_pop_tip_times_cur = 48, // 本次通电后Tip弹出的次数
kstate_pump_temp = 53, // 当前泵体温度(摄氏度)
kstate_temp_max = 54, // 温度值最高记录
kstate_temp_min = 55, // 温度值最低记录
kstate_pressure_ad = 56, // 压力对应的AD值
kstate_q_time = 57, // 获取[q]指令执行过程中的特征时间
kstate_pressure_max = 58, // 自上次[f1]命令以来记录的最高压力值
kstate_pressure_min = 59, // 自上次[f1]命令以来记录的最低压力值
kstate_q_max_diff = 60, // 获取[q]指令执行过程中的最大差值
kstate_cmd_buf = 99, // 缓冲区中的当前命令字符串
kstate_p_cmd = 100, // 当前[p]命令设置
kstate_n_cmd = 102, // 当前[N]命令设置
kstate_io1 = 103, // I/O 1的电平状态
kstate_temp_compensation = 149, // 自活塞上次处于原点(零)以来的温度补偿增量总数
} state_t;
typedef struct {
cmd_t cmd;
char cmdchar;
int paramnum;
} cmd_info_t;
/**
* @brief
* :
* 1. 使
* 2.
* 3. 0.319ul
*/
class SMTP2V2 {
public:
private:
UART_HandleTypeDef* m_uart = nullptr;
uint8_t m_id = 0;
DMA_HandleTypeDef* m_hdma_rx;
DMA_HandleTypeDef* m_hdma_tx;
char m_rxbuf[SMTP2_BUF_LEN] = {0};
char m_txbuf[SMTP2_BUF_LEN] = {0};
int32_t m_rxNum = {0};
public:
void initialize(UART_HandleTypeDef* uart, uint8_t id, DMA_HandleTypeDef* hdma_rx, DMA_HandleTypeDef* hdma_tx);
void pump_init_cfg();
void pump_ping();
// 泵机复位(归零)
void pump_init();
void pump_reset();
//
void pump_move_to();
void pump_set_cfg(cfg_t cfgindex, int32_t val);
bool write_cmd(const char* cmd);
void getack(char* rx, int32_t* rxbufsize);
private:
bool sendcmd(const char* cmd);
bool _sendcmd(const char* cmd);
bool _sendcmd_dma(const char* cmd);
int32_t getAckEcode();
};
} // namespace smtp2
} // namespace iflytop

10
components/zcancmder/zcan_protocol_parser.cpp

@ -71,6 +71,7 @@ void ZCanProtocolParser::initialize(IZCanReceiver* cancmder) {
REGFN(pipette_ctrl_init_device);
REGFN(pipette_ctrl_put_tip);
REGFN(pipette_ctrl_move_to_ul);
REGFN(pipette_write_cmd_direct);
REGFN(temp_controler_start_hearting);
REGFN(temp_controler_stop_hearting);
@ -482,6 +483,15 @@ int32_t ZCanProtocolParser::pipette_ctrl_move_to_ul(cmdcontxt_t* cxt) {
CHECK_AND_GET_MODULE(1);
return module->pipette_ctrl_move_to_ul(cxt->params[0]);
}
int32_t ZCanProtocolParser::pipette_write_cmd_direct(cmdcontxt_t* cxt) {
GET_MODULE();
cxt->acklen = ZCANCMD_READ_BUF_MAX_SIZE;
int32_t suc = module->pipette_write_cmd_direct(cxt->paramRaw, cxt->paramlen, cxt->ackbuf, &cxt->acklen);
if (suc != 0) {
cxt->acklen = 0;
}
return suc;
}
#undef MODULE_CLASS

1
components/zcancmder/zcan_protocol_parser.hpp

@ -104,6 +104,7 @@ class ZCanProtocolParser : public IZCanReceiverListener {
static int32_t pipette_ctrl_init_device(cmdcontxt_t* cxt);
static int32_t pipette_ctrl_put_tip(cmdcontxt_t* cxt);
static int32_t pipette_ctrl_move_to_ul(cmdcontxt_t* cxt);
static int32_t pipette_write_cmd_direct(cmdcontxt_t* cxt);
static int32_t temp_controler_start_hearting(cmdcontxt_t* cxt);
static int32_t temp_controler_stop_hearting(cmdcontxt_t* cxt);

Loading…
Cancel
Save