Browse Source

添加温度控制服务

master
zhaohe 2 years ago
parent
commit
6c8980f7e6
  1. 5
      .vscode/settings.json
  2. 248
      app/MDK-ARM/app.uvguix.h_zha
  3. 72
      app/MDK-ARM/app.uvoptx
  4. 25
      app/MDK-ARM/app.uvprojx
  5. 2
      dep/libiflytop_micro
  6. 1
      src/board/device_io_service.cpp
  7. 3
      src/board/device_io_service.hpp
  8. 0
      src/board/fan_state_monitor.cpp
  9. 0
      src/board/fan_state_monitor.hpp
  10. 148
      src/board/hardware.cpp
  11. 36
      src/board/hardware.hpp
  12. 35
      src/board/libtmcimpl.cpp
  13. 11
      src/board/libtmcimpl.hpp
  14. 28
      src/libtmcimpl.cpp
  15. 129
      src/lncubator_temperature_control_service.cpp
  16. 55
      src/lncubator_temperature_control_service.hpp
  17. 2
      src/project_board.hpp
  18. 182
      src/umain.cpp

5
.vscode/settings.json

@ -61,6 +61,9 @@
"cinttypes": "cpp",
"typeinfo": "cpp",
"can.h": "c",
"deque": "cpp"
"deque": "cpp",
"param.h": "c",
"stdbool.h": "c",
"check.h": "c"
}
}

248
app/MDK-ARM/app.uvguix.h_zha
File diff suppressed because it is too large
View File

72
app/MDK-ARM/app.uvoptx

@ -925,8 +925,8 @@
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\src\device_io_service.cpp</PathWithFileName>
<FilenameWithoutPath>device_io_service.cpp</FilenameWithoutPath>
<PathWithFileName>..\..\src\lncubator_temperature_control_service.cpp</PathWithFileName>
<FilenameWithoutPath>lncubator_temperature_control_service.cpp</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
@ -937,7 +937,43 @@
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\src\libtmcimpl.cpp</PathWithFileName>
<PathWithFileName>..\..\src\board\device_io_service.cpp</PathWithFileName>
<FilenameWithoutPath>device_io_service.cpp</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>6</GroupNumber>
<FileNumber>42</FileNumber>
<FileType>8</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\src\board\fan_state_monitor.cpp</PathWithFileName>
<FilenameWithoutPath>fan_state_monitor.cpp</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>6</GroupNumber>
<FileNumber>43</FileNumber>
<FileType>8</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\src\board\hardware.cpp</PathWithFileName>
<FilenameWithoutPath>hardware.cpp</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>6</GroupNumber>
<FileNumber>44</FileNumber>
<FileType>8</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\src\board\libtmcimpl.cpp</PathWithFileName>
<FilenameWithoutPath>libtmcimpl.cpp</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
@ -952,7 +988,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>42</FileNumber>
<FileNumber>45</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -964,7 +1000,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>43</FileNumber>
<FileNumber>46</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -976,7 +1012,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>44</FileNumber>
<FileNumber>47</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -988,7 +1024,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>45</FileNumber>
<FileNumber>48</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1000,7 +1036,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>46</FileNumber>
<FileNumber>49</FileNumber>
<FileType>8</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1012,7 +1048,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>47</FileNumber>
<FileNumber>50</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1024,7 +1060,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>48</FileNumber>
<FileNumber>51</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1036,7 +1072,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>49</FileNumber>
<FileNumber>52</FileNumber>
<FileType>8</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1048,7 +1084,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>50</FileNumber>
<FileNumber>53</FileNumber>
<FileType>8</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1060,7 +1096,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>51</FileNumber>
<FileNumber>54</FileNumber>
<FileType>8</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1072,7 +1108,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>52</FileNumber>
<FileNumber>55</FileNumber>
<FileType>8</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1084,13 +1120,13 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>53</FileNumber>
<FileType>8</FileType>
<FileNumber>56</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\src\fan_state_monitor.cpp</PathWithFileName>
<FilenameWithoutPath>fan_state_monitor.cpp</FilenameWithoutPath>
<PathWithFileName>..\..\dep\libiflytop_micro\stm32\component\pid\pid_ctrl.c</PathWithFileName>
<FilenameWithoutPath>pid_ctrl.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>

25
app/MDK-ARM/app.uvprojx

@ -1216,14 +1216,29 @@
<FilePath>..\..\src\umain.cpp</FilePath>
</File>
<File>
<FileName>lncubator_temperature_control_service.cpp</FileName>
<FileType>8</FileType>
<FilePath>..\..\src\lncubator_temperature_control_service.cpp</FilePath>
</File>
<File>
<FileName>device_io_service.cpp</FileName>
<FileType>8</FileType>
<FilePath>..\..\src\device_io_service.cpp</FilePath>
<FilePath>..\..\src\board\device_io_service.cpp</FilePath>
</File>
<File>
<FileName>fan_state_monitor.cpp</FileName>
<FileType>8</FileType>
<FilePath>..\..\src\board\fan_state_monitor.cpp</FilePath>
</File>
<File>
<FileName>hardware.cpp</FileName>
<FileType>8</FileType>
<FilePath>..\..\src\board\hardware.cpp</FilePath>
</File>
<File>
<FileName>libtmcimpl.cpp</FileName>
<FileType>8</FileType>
<FilePath>..\..\src\libtmcimpl.cpp</FilePath>
<FilePath>..\..\src\board\libtmcimpl.cpp</FilePath>
</File>
</Files>
</Group>
@ -1286,9 +1301,9 @@
<FilePath>..\..\dep\libiflytop_micro\stm32\basic\stm32_hal_utils.cpp</FilePath>
</File>
<File>
<FileName>fan_state_monitor.cpp</FileName>
<FileType>8</FileType>
<FilePath>..\..\src\fan_state_monitor.cpp</FilePath>
<FileName>pid_ctrl.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\dep\libiflytop_micro\stm32\component\pid\pid_ctrl.c</FilePath>
</File>
</Files>
</Group>

2
dep/libiflytop_micro

@ -1 +1 @@
Subproject commit 1be6e0ea5a7193a1eac2460413476302bd9c8dea
Subproject commit 645e10e79f235ef9a05d3026091d692b18f6b5f8

1
src/device_io_service.cpp → src/board/device_io_service.cpp

@ -12,7 +12,6 @@ int fputc(int ch, FILE *stream) {
using namespace iflytop;
namespace iflytop {
DeviceIoService deviceIoService;
}
void DeviceIoService::fanInit(int freq) {

3
src/device_io_service.hpp → src/board/device_io_service.hpp

@ -19,7 +19,7 @@ class DeviceIoService : public IflytopMicroOS {
private:
/* data */
bool m_fanState[5];
bool m_fanState[6];
public:
DeviceIoService(/* args */) {}
@ -66,5 +66,4 @@ class DeviceIoService : public IflytopMicroOS {
void tmc_motor_spi_select(int channel, bool state);
};
extern DeviceIoService deviceIoService;
} // namespace iflytop

0
src/fan_state_monitor.cpp → src/board/fan_state_monitor.cpp

0
src/fan_state_monitor.hpp → src/board/fan_state_monitor.hpp

148
src/board/hardware.cpp

@ -0,0 +1,148 @@
#include "hardware.hpp"
#include "i2c.h"
using namespace iflytop;
#define TAG "hardware"
void Hardware::hardwareinit() {
m_os = &m_deviceIoService;
/*******************************************************************************
* CANSLAVEService初始化 *
*******************************************************************************/
IflytopCanSlave::iflytop_can_slave_config_t *config = canSlaveService.createDefaultConfig(DEVICE_ID);
canSlaveService.initialize(m_os, config);
/*******************************************************************************
* *
*******************************************************************************/
m_deviceIoService.peltier_init();
/*******************************************************************************
* *
*******************************************************************************/
tmp117[0].initializate(&hi2c1, TMP117::ID0);
tmp117[1].initializate(&hi2c1, TMP117::ID1);
tmp117[2].initializate(&hi2c1, TMP117::ID2);
tmp117[3].initializate(&hi2c1, TMP117::ID3);
/*******************************************************************************
* *
*******************************************************************************/
m_deviceIoService.tmc_init();
m_deviceIoService.tmc_extern_clk_enable();
// 4361初始化
TMC4361AImpl::TMC4361AConfig_t *tmc4361aconfig = TMC4361AImpl::createDeafultTMC4361AConfig();
tmc4361aconfig->base_config.fs_per_rev = 200;
tmc4361aconfig->encoder_config.diff_enc_in_disable = false;
tmc4361aconfig->encoder_config.enc_in_res = 4000;
tmc4361aconfig->close_loop_config.enable_closed_loop = true;
tmc4361motor1.initialize(&m_deviceIoService, MOTOR_1_TMC4361A_CHANNEL, TMC4361A::IC_TMC2160, tmc4361aconfig);
tmc4361motor1.setMaximumAcceleration(300000);
tmc4361motor1.setMaximumDeceleration(300000);
// 2160初始化
tmc2160motor1.setMaximumCurrent(3);
tmc2160motor1.initialize(&m_deviceIoService, &tmc4361motor1, MOTOR_1_TMC2160_CHANNEL);
HAL_Delay(100);
// 使能电机
tmc4361motor1.enableIC(true);
tmc2160motor1.enableIC(true);
/**
* @brief Version寄存器来判断芯片是否正常
*/
int32_t ic4361Version = tmc4361motor1.readICVersion();
int32_t ic2160Version = tmc2160motor1.readICVersion();
// 期望 4361Version:2 ic2160Version:30
ZLOGI(TAG, "TMC4361Version:%x TMC2160VERSION:%x", ic4361Version, ic2160Version);
if (ic4361Version != 2 || ic2160Version != 30) {
ZLOGE(TAG, "TMC4361 or TMC2160 is not normal");
}
/*******************************************************************************
* *
*******************************************************************************/
m_deviceIoService.fanInit(1000);
/**
* @brief
*
* FAN0_FB_INT PC1
* FAN1_FB_INT PC4
* FAN2_FB_INT PC5
* FAN3_FB_INT PC6
* FAN4_FB_INT PC7
* FAN5_FB_INT PC10
*/
m_fanStateMonitor[0].initialize(m_os, GPIOC, GPIO_PIN_1, m_deviceIoService.fanGetPowerState(0));
m_fanStateMonitor[1].initialize(m_os, GPIOC, GPIO_PIN_4, m_deviceIoService.fanGetPowerState(1));
m_fanStateMonitor[2].initialize(m_os, GPIOC, GPIO_PIN_5, m_deviceIoService.fanGetPowerState(2));
m_fanStateMonitor[3].initialize(m_os, GPIOC, GPIO_PIN_6, m_deviceIoService.fanGetPowerState(3));
m_fanStateMonitor[4].initialize(m_os, GPIOC, GPIO_PIN_7, m_deviceIoService.fanGetPowerState(4));
m_fanStateMonitor[5].initialize(m_os, GPIOC, GPIO_PIN_10, m_deviceIoService.fanGetPowerState(5));
}
void Hardware::periodicJob() {
/**
* @brief
*/
for (size_t i = 0; i < ZARRAY_SIZE(m_fanStateMonitor); i++) {
m_fanStateMonitor[i].periodicJob();
}
do_debug_light_state();
}
void Hardware::do_debug_light_state() {
static uint32_t lastprocess = 0;
if (sys_haspassedms(lastprocess) > 300) {
lastprocess = HAL_GetTick();
HAL_GPIO_TogglePin(DEBUG_LIGHT_PORT, DEBUG_LIGHT_PIN);
}
}
/*******************************************************************************
* *
*******************************************************************************/
void Hardware::testTmp117() {
static uint32_t lastcall;
if (m_os->hasPassedMS(lastcall) > 1000) {
lastcall = m_os->getTicket();
for (size_t i = 0; i < 4; i++) {
float temp = tmp117[i].getTemperature();
if (tmp117[i].getLastCallStatus() == HAL_OK) {
ZLOGI(TAG, "tmp117_%d:%f", i, temp);
} else {
ZLOGI(TAG, "tmp117_%d:read fail", i);
}
}
}
}
/**
* @brief CAN的发送和接收
*/
void Hardware::testCanSlaveTxAndRx(bool canOnRxDataFlag) {
{
static uint32_t lastcall;
static uint8_t tx[8] = {1, 2, 3, 4, 5, 6, 7, 8};
if (m_os->hasPassedMS(lastcall) > 1000) {
lastcall = m_os->getTicket();
canSlaveService.translate(0x01, tx, 8, 2);
if (canSlaveService.getLastTransmitStatus() == HAL_OK) {
ZLOGI(TAG, "send ok");
} else {
ZLOGI(TAG, "send fail");
}
}
}
/**
* @brief CAN消息
*/
if (canOnRxDataFlag) {
canOnRxDataFlag = false;
static CAN_RxHeaderTypeDef packetHeader;
static uint8_t packetData[8];
while (canSlaveService.getRxMessage(&packetHeader, packetData)) {
ZLOGI(TAG, "rx packet:");
ZLOGI(TAG, "\tid:%x len:%d", packetHeader.StdId, packetHeader.DLC);
ZLOGI_HEX(TAG, packetData, packetHeader.DLC);
}
canSlaveService.activateRxIT();
}
}

36
src/board/hardware.hpp

@ -0,0 +1,36 @@
#pragma once
#include "board/device_io_service.hpp"
#include "board/fan_state_monitor.hpp"
#include "board/libtmcimpl.hpp"
#include "libiflytop_micro\stm32\component\iflytop_can_slave_v1\iflytop_can_slave.hpp"
#include "libiflytop_micro\stm32\component\tmp117\tmp117.hpp"
namespace iflytop {
class Hardware {
private:
/* data */
public:
TMC4361AImpl tmc4361motor1;
TMC2160Impl tmc2160motor1;
TMP117 tmp117[4];
FanStateMonitor m_fanStateMonitor[6];
IflytopCanSlave canSlaveService;
IflytopMicroOS* m_os;
DeviceIoService m_deviceIoService;
Hardware(/* args */){};
~Hardware(){};
void hardwareinit();
void periodicJob();
/*******************************************************************************
* *
*******************************************************************************/
void testTmp117();
void testCanSlaveTxAndRx(bool canOnRxDataFlag);
void do_debug_light_state();
};
} // namespace iflytop

35
src/board/libtmcimpl.cpp

@ -0,0 +1,35 @@
#pragma once
#include "libtmcimpl.hpp"
#include "device_io_service.hpp"
namespace iflytop {
using namespace std;
/*******************************************************************************
* TMC4361AImpl *
*******************************************************************************/
void TMC4361AImpl::setResetPinState(bool state) { m_deviceIoService->tmc_nRESET_pin_set_state(m_channel, state); };
void TMC4361AImpl::setFREEZEPinState(bool state) { m_deviceIoService->tmc_nFREEZE_pin_set_state(m_channel, state); };
void TMC4361AImpl::setENNPinState(bool state) { m_deviceIoService->tmc_ENN_pin_set_state(m_channel, state); };
bool TMC4361AImpl::getTargetReachedPinState() { return false; };
void TMC4361AImpl::sleepus(int32_t us) { m_deviceIoService->sleepus(us); };
void TMC4361AImpl::readWriteArray(uint8_t *data, size_t length) { //
m_deviceIoService->tmc_motor_spi_write_and_read(m_channel, data, length);
};
void TMC4361AImpl::initialize(DeviceIoService *deviceIoService, uint8_t channel, driver_ic_type_t driver_ic_type, TMC4361AConfig_t *config) {
m_deviceIoService = deviceIoService;
TMC4361A::initialize(channel, driver_ic_type, config);
}
/*******************************************************************************
* TMC2160Impl *
*******************************************************************************/
void TMC2160Impl::initialize(DeviceIoService *deviceIoService, TMC4361A *tmc4361, uint8_t channelId) {
m_tmc4361 = tmc4361;
m_deviceIoService = deviceIoService;
TMC2160::initialize(channelId);
}
void TMC2160Impl::setENNPinState(bool state) { m_deviceIoService->tmc_ENN_pin_set_state(m_channel, state); };
void TMC2160Impl::sleepus(int32_t us) { m_deviceIoService->sleepus(us); };
void TMC2160Impl::readWriteArray(uint8_t *data, size_t length) { m_tmc4361->readWriteCover(data, length); };
} // namespace iflytop

11
src/libtmcimpl.hpp → src/board/libtmcimpl.hpp

@ -1,5 +1,6 @@
#pragma once
#include "board/device_io_service.hpp"
#include "libiflytop_micro/stm32/basic/basic.h"
#include "libtrinamic/src/ic/tmc2160.hpp"
#include "libtrinamic\src\ic\tmc4361A.hpp"
@ -9,6 +10,8 @@ using namespace std;
* @brief TMC4361和硬件的接口
*/
class TMC4361AImpl : public TMC4361A {
DeviceIoService *m_deviceIoService;
protected:
virtual void setResetPinState(bool state);
virtual void setFREEZEPinState(bool state);
@ -16,15 +19,19 @@ class TMC4361AImpl : public TMC4361A {
virtual bool getTargetReachedPinState();
virtual void sleepus(int32_t us);
virtual void readWriteArray(uint8_t *data, size_t length);
public:
void initialize(DeviceIoService *deviceIoService, uint8_t channel, driver_ic_type_t driver_ic_type, TMC4361AConfig_t *config);
};
/**
* @brief TMC2160和硬件的接口
*/
class TMC2160Impl : public TMC2160 {
TMC4361A *m_tmc4361;
TMC4361A *m_tmc4361;
DeviceIoService *m_deviceIoService;
public:
void initialize(uint8_t channel, TMC4361A *tmc4361);
void initialize(DeviceIoService *deviceIoService, TMC4361A *tmc4361, uint8_t channelId);
protected:
virtual void setENNPinState(bool state);

28
src/libtmcimpl.cpp

@ -1,28 +0,0 @@
#pragma once
#include "libtmcimpl.hpp"
#include "device_io_service.hpp"
namespace iflytop {
using namespace std;
/*******************************************************************************
* TMC4361AImpl *
*******************************************************************************/
void TMC4361AImpl::setResetPinState(bool state) { deviceIoService.tmc_nRESET_pin_set_state(m_channel, state); };
void TMC4361AImpl::setFREEZEPinState(bool state) { deviceIoService.tmc_nFREEZE_pin_set_state(m_channel, state); };
void TMC4361AImpl::setENNPinState(bool state) { deviceIoService.tmc_ENN_pin_set_state(m_channel, state); };
bool TMC4361AImpl::getTargetReachedPinState() { return false; };
void TMC4361AImpl::sleepus(int32_t us) { deviceIoService.sleepus(us); };
void TMC4361AImpl::readWriteArray(uint8_t *data, size_t length) { //
deviceIoService.tmc_motor_spi_write_and_read(m_channel, data, length);
};
/*******************************************************************************
* TMC2160Impl *
*******************************************************************************/
void TMC2160Impl::initialize(uint8_t channel, TMC4361A *tmc4361) {
m_tmc4361 = tmc4361;
TMC2160::initialize(channel);
}
void TMC2160Impl::setENNPinState(bool state) { deviceIoService.tmc_ENN_pin_set_state(m_channel, state); };
void TMC2160Impl::sleepus(int32_t us) { deviceIoService.sleepus(us); };
void TMC2160Impl::readWriteArray(uint8_t *data, size_t length) { m_tmc4361->readWriteCover(data, length); };
} // namespace iflytop

129
src/lncubator_temperature_control_service.cpp

@ -0,0 +1,129 @@
#include "lncubator_temperature_control_service.hpp"
using namespace iflytop;
#define TAG "LTCS"
const int LncubatorTemperatureControlService::m_compute_periodms = 1000;
const float LncubatorTemperatureControlService::m_error_limit = 50;
const float LncubatorTemperatureControlService::m_kp = 30;
const float LncubatorTemperatureControlService::m_ki = 1;
const float LncubatorTemperatureControlService::m_kd = 0;
const float LncubatorTemperatureControlService::m_max_output = 100;
const float LncubatorTemperatureControlService::m_min_output = -100;
const bool LncubatorTemperatureControlService::m_dumpvalue = false;
void LncubatorTemperatureControlService::initialize(Hardware* hardware) {
#if 0
pid_ctrl_config_t m_init_config;
pid_ctrl_block_handle_t m_pidblock;
IflytopMicroOS* m_os;
float m_nowoutput = 0;
bool m_workingState;
#endif
m_init_config.init_param.kp = 30;
m_init_config.init_param.ki = 1;
m_init_config.init_param.kd = 0;
m_init_config.init_param.cal_type = PID_CAL_TYPE_POSITIONAL;
m_init_config.init_param.max_output = m_max_output;
m_init_config.init_param.min_output = m_min_output;
m_init_config.init_param.max_integral = m_error_limit;
m_init_config.init_param.min_integral = -m_error_limit;
pid_new_control_block(&m_init_config, &m_pidblock);
ZASSERT(m_pidblock != NULL);
m_hardware = hardware;
m_nowoutput = 0;
m_target_temperature = 25;
m_periodicJobLastExecuteTicket = 0;
}
void LncubatorTemperatureControlService::setTargetTemperature(int targetTemperature) { //
m_target_temperature = targetTemperature;
}
void LncubatorTemperatureControlService::setPidKp(float value) {
m_init_config.init_param.kp = value;
pid_update_parameters(m_pidblock, &m_init_config.init_param);
}
void LncubatorTemperatureControlService::setPidKi(float value) {
m_init_config.init_param.ki = value;
pid_update_parameters(m_pidblock, &m_init_config.init_param);
}
void LncubatorTemperatureControlService::setPidKd(float value) {
m_init_config.init_param.kd = value;
pid_update_parameters(m_pidblock, &m_init_config.init_param);
}
void LncubatorTemperatureControlService::setPidParameters(float kp, float ki, float kd) {
m_init_config.init_param.kp = kp;
m_init_config.init_param.ki = ki;
m_init_config.init_param.kd = kd;
pid_update_parameters(m_pidblock, &m_init_config.init_param);
}
float LncubatorTemperatureControlService::getTemperature() {
float temperature[4];
temperature[0] = m_hardware->tmp117[0].getTemperature();
temperature[1] = m_hardware->tmp117[1].getTemperature();
temperature[2] = m_hardware->tmp117[2].getTemperature();
temperature[3] = m_hardware->tmp117[3].getTemperature();
float temperature_median = 0;
// 取温度的中位数
for (int i = 0; i < 4; i++) {
for (int j = i + 1; j < 4; j++) {
if (temperature[i] > temperature[j]) {
float temp = temperature[i];
temperature[i] = temperature[j];
temperature[j] = temp;
}
}
}
temperature_median = (temperature[1] + temperature[2]) / 2;
return temperature_median;
}
void LncubatorTemperatureControlService::setPwmOutput(float output) { m_hardware->m_deviceIoService.peltier_set_pwm(output); }
void LncubatorTemperatureControlService::start() {
pid_reset(m_pidblock);
/**
* @brief
* 使20
* 便PID参数是否正确线
* PID参数了
*/
pid_set_integral_err(m_pidblock, m_error_limit);
m_workingState = true;
}
void LncubatorTemperatureControlService::stop() {}
void LncubatorTemperatureControlService::periodicJob() {
if (!m_workingState) return;
if (m_hardware->m_os->hasPassedMS(m_periodicJobLastExecuteTicket) < m_compute_periodms) {
return;
}
m_periodicJobLastExecuteTicket = m_os->getTicket();
float current_temperature = getTemperature();
float output = 0;
pid_compute(m_pidblock, m_target_temperature - current_temperature, &output);
pwmOutputFilter(output, &m_nowoutput);
if (m_dumpvalue) {
ZLOGI(TAG, "%.2f,%.2f,%.2f,%.2f", m_target_temperature, current_temperature, pid_get_integral_err(m_pidblock), m_nowoutput);
}
setPwmOutput(m_nowoutput);
}
void LncubatorTemperatureControlService::pwmOutputFilter(float now, float* output) {
/**
* @brief PWM输出最多以每次10的步进进行变化
*/
if (now > *output) {
*output += 10;
if (*output > now) {
*output = now;
}
} else if (now < *output) {
*output = now;
}
}

55
src/lncubator_temperature_control_service.hpp

@ -0,0 +1,55 @@
#pragma once
#include "board/device_io_service.hpp"
#include "board\hardware.hpp"
#include "libiflytop_micro\stm32\basic\iflytop_micro_os.hpp"
#include "libiflytop_micro\stm32\component\pid\pid_ctrl.h"
#include "libiflytop_micro\stm32\component\tmp117\tmp117.hpp"
namespace iflytop {
class LncubatorTemperatureControlService {
/*******************************************************************************
* Config *
*******************************************************************************/
static const int m_compute_periodms;
static const float m_error_limit;
static const float m_kp;
static const float m_ki;
static const float m_kd;
static const float m_max_output;
static const float m_min_output;
static const bool m_dumpvalue;
pid_ctrl_config_t m_init_config;
pid_ctrl_block_handle_t m_pidblock;
Hardware* m_hardware;
IflytopMicroOS* m_os;
float m_nowoutput;
bool m_workingState;
float m_target_temperature;
uint32_t m_periodicJobLastExecuteTicket;
public:
void initialize(Hardware* hardware);
void setPidParameters(float kp, float ki, float kd);
void setPidKp(float value);
void setPidKi(float value);
void setPidKd(float value);
void setTargetTemperature(int targetTemperature);
void start();
void stop();
/**
* @brief
*/
void periodicJob();
private:
void pwmOutputFilter(float now, float* output);
float getTemperature();
void setPwmOutput(float output);
};
} // namespace iflytop

2
src/project_board.hpp

@ -18,3 +18,5 @@
// 电机编号
#define MOTOR_1_TMC4361A_CHANNEL 1
#define MOTOR_1_TMC2160_CHANNEL 2
//

182
src/umain.cpp

@ -1,18 +1,19 @@
#include <stdbool.h>
#include <stdio.h>
#include "device_io_service.hpp"
#include "board/device_io_service.hpp"
#include "board/libtmcimpl.hpp"
#include "libiflytop_micro\stm32\basic\basic.h"
#include "libtmcimpl.hpp"
#include "libtrinamic/src/ic/tmc2160.hpp"
#include "libtrinamic\src\ic\tmc4361A.hpp"
#include "project_board.hpp"
//
#include "fan_state_monitor.hpp"
#include "board/hardware.hpp"
#include "i2c.h"
#include "libiflytop_micro\stm32\basic\zsignal.hpp"
#include "libiflytop_micro\stm32\component\iflytop_can_slave_v1\iflytop_can_slave.hpp"
#include "libiflytop_micro\stm32\component\tmp117\tmp117.hpp"
#include "lncubator_temperature_control_service.hpp"
#define TAG "main"
using namespace iflytop;
@ -21,13 +22,10 @@ class Main {
public:
signal_listener_t zsignal_listener[20];
TMC4361AImpl tmc4361motor1;
TMC2160Impl tmc2160motor1;
TMP117 tmp117[4];
IflytopCanSlave canSlaveService;
IflytopMicroOS *os;
FanStateMonitor m_fanStateMonitor[6];
LncubatorTemperatureControlService m_lncubatorTemperatureControlService;
Hardware m_hardware;
IflytopCanSlave *canSlaveService;
IflytopMicroOS *os;
bool canOnRxDataFlag;
@ -35,110 +33,18 @@ class Main {
ZSLOT0(Main, onCanRxData);
void onCanRxData() {
canOnRxDataFlag = true;
canSlaveService.deactivateRxIT();
canSlaveService->deactivateRxIT();
}
void initialize();
void main(int argc, char const *argv[]);
void do_debug_light_state() {
static uint32_t lastprocess = 0;
if (sys_haspassedms(lastprocess) > 300) {
lastprocess = HAL_GetTick();
HAL_GPIO_TogglePin(DEBUG_LIGHT_PORT, DEBUG_LIGHT_PIN);
}
}
/*******************************************************************************
* *
*******************************************************************************/
/**
* @brief CAN的发送和接收
*/
void testCanSlaveTxAndRx();
void testTmp117();
};
void Main::initialize() {
zsignal_init(zsignal_listener, ZARRAY_SIZE(zsignal_listener));
os = &deviceIoService;
/*******************************************************************************
* *
*******************************************************************************/
deviceIoService.peltier_init();
/*******************************************************************************
* *
*******************************************************************************/
tmp117[0].initializate(&hi2c1, TMP117::ID0);
tmp117[1].initializate(&hi2c1, TMP117::ID1);
tmp117[2].initializate(&hi2c1, TMP117::ID2);
tmp117[3].initializate(&hi2c1, TMP117::ID3);
/*******************************************************************************
* *
*******************************************************************************/
deviceIoService.tmc_init();
deviceIoService.tmc_extern_clk_enable();
// 4361初始化
TMC4361AImpl::TMC4361AConfig_t *tmc4361aconfig = TMC4361AImpl::createDeafultTMC4361AConfig();
tmc4361aconfig->base_config.fs_per_rev = 200;
tmc4361aconfig->encoder_config.diff_enc_in_disable = false;
tmc4361aconfig->encoder_config.enc_in_res = 4000;
tmc4361aconfig->close_loop_config.enable_closed_loop = true;
tmc4361motor1.initialize(MOTOR_1_TMC4361A_CHANNEL, TMC4361A::IC_TMC2160, tmc4361aconfig);
tmc4361motor1.setMaximumAcceleration(300000);
tmc4361motor1.setMaximumDeceleration(300000);
// 2160初始化
tmc2160motor1.setMaximumCurrent(3);
tmc2160motor1.initialize(MOTOR_1_TMC2160_CHANNEL, &tmc4361motor1);
HAL_Delay(100);
// 使能电机
tmc4361motor1.enableIC(true);
tmc2160motor1.enableIC(true);
/**
* @brief Version寄存器来判断芯片是否正常
*/
int32_t ic4361Version = tmc4361motor1.readICVersion();
int32_t ic2160Version = tmc2160motor1.readICVersion();
// 期望 4361Version:2 ic2160Version:30
ZLOGI(TAG, "TMC4361Version:%x TMC2160VERSION:%x", ic4361Version, ic2160Version);
if (ic4361Version != 2 || ic2160Version != 30) {
ZLOGE(TAG, "TMC4361 or TMC2160 is not normal");
}
/*******************************************************************************
* CANSLAVEService初始化 *
*******************************************************************************/
IflytopCanSlave::iflytop_can_slave_config_t *config = canSlaveService.createDefaultConfig(DEVICE_ID);
canSlaveService.initialize(os, config);
canSlaveService.onCanRxData.connect(this, &Main::onCanRxData);
canSlaveService.activateRxIT();
/*******************************************************************************
* *
*******************************************************************************/
deviceIoService.fanInit(1000);
/**
* @brief
*
* FAN0_FB_INT PC1
* FAN1_FB_INT PC4
* FAN2_FB_INT PC5
* FAN3_FB_INT PC6
* FAN4_FB_INT PC7
* FAN5_FB_INT PC10
*/
m_fanStateMonitor[0].initialize(os, GPIOC, GPIO_PIN_1, deviceIoService.fanGetPowerState(0));
m_fanStateMonitor[1].initialize(os, GPIOC, GPIO_PIN_4, deviceIoService.fanGetPowerState(1));
m_fanStateMonitor[2].initialize(os, GPIOC, GPIO_PIN_5, deviceIoService.fanGetPowerState(2));
m_fanStateMonitor[3].initialize(os, GPIOC, GPIO_PIN_6, deviceIoService.fanGetPowerState(3));
m_fanStateMonitor[4].initialize(os, GPIOC, GPIO_PIN_7, deviceIoService.fanGetPowerState(4));
m_fanStateMonitor[5].initialize(os, GPIOC, GPIO_PIN_10, deviceIoService.fanGetPowerState(5));
m_hardware.hardwareinit();
canSlaveService = &m_hardware.canSlaveService;
canSlaveService->onCanRxData.connect(this, &Main::onCanRxData);
canSlaveService->activateRxIT();
}
void Main::main(int argc, char const *argv[]) {
@ -147,16 +53,9 @@ void Main::main(int argc, char const *argv[]) {
// port_peltier_set_pwm(0);
initialize();
while (true) {
do_debug_light_state();
// testCanSlaveTxAndRx();
// testTmp117();
/**
* @brief
*/
for (size_t i = 0; i < ZARRAY_SIZE(m_fanStateMonitor); i++) {
m_fanStateMonitor[i].periodicJob();
}
m_hardware.periodicJob();
// m_hardware.testCanSlaveTxAndRx(canOnRxDataFlag);
// m_hardware.testTmp117();
}
}
@ -164,55 +63,6 @@ void Main::main(int argc, char const *argv[]) {
* *
*******************************************************************************/
/**
* @brief CAN的发送和接收
*/
void Main::testCanSlaveTxAndRx() {
{
static uint32_t lastcall;
static uint8_t tx[8] = {1, 2, 3, 4, 5, 6, 7, 8};
if (os->hasPassedMS(lastcall) > 1000) {
lastcall = os->getTicket();
canSlaveService.translate(0x01, tx, 8, 2);
if (canSlaveService.getLastTransmitStatus() == HAL_OK) {
ZLOGI(TAG, "send ok");
} else {
ZLOGI(TAG, "send fail");
}
}
}
/**
* @brief CAN消息
*/
if (canOnRxDataFlag) {
canOnRxDataFlag = false;
static CAN_RxHeaderTypeDef packetHeader;
static uint8_t packetData[8];
while (canSlaveService.getRxMessage(&packetHeader, packetData)) {
ZLOGI(TAG, "rx packet:");
ZLOGI(TAG, "\tid:%x len:%d", packetHeader.StdId, packetHeader.DLC);
ZLOGI_HEX(TAG, packetData, packetHeader.DLC);
}
canSlaveService.activateRxIT();
}
}
void Main::testTmp117() {
static uint32_t lastcall;
if (os->hasPassedMS(lastcall) > 1000) {
lastcall = os->getTicket();
for (size_t i = 0; i < 4; i++) {
float temp = tmp117[i].getTemperature();
if (tmp117[i].getLastCallStatus() == HAL_OK) {
ZLOGI(TAG, "tmp117_%d:%f", i, temp);
} else {
ZLOGI(TAG, "tmp117_%d:read fail", i);
}
}
}
}
static Main mainObject;
extern "C" {
int umain(int argc, char const *argv[]) {

Loading…
Cancel
Save