/**
******************************************************************************
* @file Project/PWFCRobot_R1/Safety.h
* @author Jackey Jiang
* @version V1.0.0
* @date 18-April-2016
* @brief robot temperature system.
******************************************************************************
* @attention
*
*
******************************************************************************
**/
#ifndef __TEMP_CTL_h
#define __TEMP_CTL_h
#include "stm32f4xx.h"
/************************** define *****************************************/
#define LOWEST_TEMPERATURE (float)-40
#define HIGHEST_TEMPERATURE (float)120
#define TEMP_DIS (float)0.5
/************************** typedef *****************************************/
/* PRIVATE */typedef enum
{
TEMP_TOO_LOW = 0,//< (-40)
TEMP_LOWEST , //>=(-40) && <(-20)
TEMP_LOWER, //>=(-20) && <(-10)
TEMP_LOW, //>=(-10) && <(1)
TEMP_NORMAL, //>=(1) && <(20)
TEMP_HIGH, //>=(20) && <(50)
TEMP_HIGHER, //>=(50) && <(80)
TEMP_HIGHEST, //>=(80) && <(120)
TEMP_TOO_HIGH, //>=(120)
}TEMP_STATUS_ENUM;
/* PRIVATE */typedef struct
{
float cabinetTopTemperature;
float cabinetBottomTemperature;
float batteryTopTemperature;
float batteryBottomTemperature;
float cabinetTemperature;
float batteryTemperature;
}CURRENT_TEMPERATURE_INFO_STRUCT;
/* PRIVATE */typedef struct
{
CURRENT_TEMPERATURE_INFO_STRUCT CurrentTemperature;
TEMP_STATUS_ENUM BatteryTempStatus;
TEMP_STATUS_ENUM CabinetTempStatus;
}TEMP_STATUS_INFO_STRUCT;
/* PUBLIC */typedef struct
{
TEMP_STATUS_INFO_STRUCT TempStatusInfo;
int8_t (*initialize)(void);
int8_t (*tempManage)(void);
}TEMP_MANAGE_STRUCT;
/************************** extern *****************************************/
extern TEMP_MANAGE_STRUCT RoTempManage;
#endif
/**
******************************************************************************
* @file Project/PWFCRobot_R1/TempCtl.c
* @author Jackey Jiang
* @version
* @date 22-Sep-2016
* @brief robot temperature control system.
******************************************************************************
* @attention
*
*
******************************************************************************
**/
//---------------------------- Include files ----------------------------------//
#include "TempCtl.h"
#include "lm950xx.h"
#include "max31865.h"
#include "safety.h"
//---------------------------- define -----------------------------------------//
#define BAT_TEMP_DIS batTempDis
#define CAB_TEMP_DIS cabTempDis
//#define TEST_TEMPERATURE
//--------------------------declare of function -------------------------------//
static int8_t RoTempManage_initialize(void);
static int8_t RoTempManage_tempManage(void);
static int8_t RoTempManage_checkCurrrentTemperature(TEMP_STATUS_INFO_STRUCT *pTempStatusInfo);
//---------------------------variable -----------------------------------------//
TEMP_MANAGE_STRUCT RoTempManage=
{
.TempStatusInfo.CurrentTemperature.cabinetTopTemperature = (float)20.0,
.TempStatusInfo.CurrentTemperature.cabinetBottomTemperature = (float)20.0,
.TempStatusInfo.CurrentTemperature.batteryTopTemperature = (float)20.0,
.TempStatusInfo.CurrentTemperature.batteryBottomTemperature = (float)20.0,
.TempStatusInfo.CurrentTemperature.cabinetTemperature = (float)20.0,
.TempStatusInfo.CurrentTemperature.batteryTemperature = (float)20.0,
/* For PowerMag.c used calculate PowerMag_CalculateVoltageOnTemp */
.TempStatusInfo.BatteryTempStatus = TEMP_NORMAL,
.TempStatusInfo.CabinetTempStatus = TEMP_NORMAL,
.initialize = RoTempManage_initialize,
.tempManage = RoTempManage_tempManage,
};
//----------------------------Function----------------------------------------//
/*******************************************************************************
* Initialization for GPIO, ported from icore3 *
*******************************************************************************/
int8_t RoTempManage_initialize(void)
{
lm950xx.initialize();
max31865.initialize(PT100_TEMP_SENSOR_1ST);
max31865.initialize(PT100_TEMP_SENSOR_2ND);
return 0;
}
/*******************************************************************************
* Initialization for GPIO, ported from icore3 *
*******************************************************************************/
int8_t RoTempManage_checkCurrrentTemperature(TEMP_STATUS_INFO_STRUCT *pTempStatusInfo)
{
#define TEMP_STATE_KEEP_TIME 25 // 25 * 200ms = 5s
#define TEMP_MAX_DIS_VALUE 5
/* Variable */
static float s_cabinetTemperature = 0.0;
static float s_batteryTemperature = 0.0;
static TEMP_STATUS_ENUM cabinetTemperatureStatusRecord = TEMP_NORMAL;
static TEMP_STATUS_ENUM batteryTemperatureStatusRecord = TEMP_NORMAL;
static uint32_t cabinetTemperatureStatusTime = TEMP_STATE_KEEP_TIME;
static uint32_t batteryTemperatureStatusTime = TEMP_STATE_KEEP_TIME;
static float cabTempDis = 0.0;
static float batTempDis = 0.0;
/* for eclectric box temperature : judge the status*/
#ifdef TEST_TEMPERATURE
pTempStatusInfo->CurrentTemperature.cabinetTopTemperature = 20.0;
pTempStatusInfo->CurrentTemperature.cabinetBottomTemperature = 20.0;
#else
int8_t lm95071ErrFlag = 0;
static float cabinetTemperatureAverage = 0.0;
if(-1 == lm950xx.readTemperature(TEMP_SENSOR_1ST,&pTempStatusInfo->CurrentTemperature.cabinetTopTemperature)){
lm95071ErrFlag |= 0x01;
}
if(-1 == lm950xx.readTemperature(TEMP_SENSOR_2ND,&pTempStatusInfo->CurrentTemperature.cabinetBottomTemperature)){
lm95071ErrFlag |= 0x10;
}
if(lm95071ErrFlag == 0x11){
RoSafety.SafetyStatus.SafetyFlagBit.bit_CabinetTempSensor = 1;
}else if(lm95071ErrFlag == 0x01){
RoSafety.SafetyStatus.SafetyFlagBit.bit_OneCabTmpErr = 1;
RoSafety.SafetyStatus.SafetyFlagBit.bit_CabinetTempSensor = 0;
pTempStatusInfo->CurrentTemperature.cabinetTopTemperature = pTempStatusInfo->CurrentTemperature.cabinetBottomTemperature;
}else if(lm95071ErrFlag == 0x10){
RoSafety.SafetyStatus.SafetyFlagBit.bit_OneCabTmpErr = 1;
RoSafety.SafetyStatus.SafetyFlagBit.bit_CabinetTempSensor = 0;
pTempStatusInfo->CurrentTemperature.cabinetBottomTemperature = pTempStatusInfo->CurrentTemperature.cabinetTopTemperature;
}else{
RoSafety.SafetyStatus.SafetyFlagBit.bit_OneCabTmpErr = 0;
RoSafety.SafetyStatus.SafetyFlagBit.bit_CabinetTempSensor = 0;
}
/* Choose the worst temperature */
if((pTempStatusInfo->CurrentTemperature.cabinetTopTemperature * pTempStatusInfo->CurrentTemperature.cabinetBottomTemperature) > 0){
cabinetTemperatureAverage = (fabs(pTempStatusInfo->CurrentTemperature.cabinetTopTemperature) > fabs(pTempStatusInfo->CurrentTemperature.cabinetBottomTemperature))\
? pTempStatusInfo->CurrentTemperature.cabinetTopTemperature:pTempStatusInfo->CurrentTemperature.cabinetBottomTemperature;
}else{
cabinetTemperatureAverage = (pTempStatusInfo->CurrentTemperature.cabinetBottomTemperature < 0)
? pTempStatusInfo->CurrentTemperature.cabinetBottomTemperature:pTempStatusInfo->CurrentTemperature.cabinetTopTemperature;
}
pTempStatusInfo->CurrentTemperature.cabinetTemperature = (float)cabinetTemperatureAverage;
#endif
/* For protect a hurge jump */
if(fabs(s_cabinetTemperature - pTempStatusInfo->CurrentTemperature.cabinetTemperature) >= 5.0){
cabTempDis = 0;
}
s_cabinetTemperature = pTempStatusInfo->CurrentTemperature.cabinetTemperature;
/* Calulate the temperature status */
if(pTempStatusInfo->CurrentTemperature.cabinetTemperature < ((float)-40.0 -CAB_TEMP_DIS)){
cabinetTemperatureStatusRecord = TEMP_TOO_LOW; cabTempDis = TEMP_DIS;
}else if((pTempStatusInfo->CurrentTemperature.cabinetTemperature >= ((float)-40.0 +CAB_TEMP_DIS))&& (pTempStatusInfo->CurrentTemperature.cabinetTemperature < ((float)-20.0 -CAB_TEMP_DIS))){
cabinetTemperatureStatusRecord = TEMP_LOWEST; cabTempDis = TEMP_DIS;
}else if((pTempStatusInfo->CurrentTemperature.cabinetTemperature >=((float)-20.0 +CAB_TEMP_DIS))&& (pTempStatusInfo->CurrentTemperature.cabinetTemperature <((float)-10.0 -CAB_TEMP_DIS))){
cabinetTemperatureStatusRecord = TEMP_LOWER; cabTempDis = TEMP_DIS;
}else if((pTempStatusInfo->CurrentTemperature.cabinetTemperature >=((float)-10.0 +CAB_TEMP_DIS))&& (pTempStatusInfo->CurrentTemperature.cabinetTemperature <((float)1.0 -CAB_TEMP_DIS))){
cabinetTemperatureStatusRecord = TEMP_LOW; cabTempDis = TEMP_DIS;
}else if((pTempStatusInfo->CurrentTemperature.cabinetTemperature >=((float)1.0 +CAB_TEMP_DIS))&& (pTempStatusInfo->CurrentTemperature.cabinetTemperature <((float)20.0 -CAB_TEMP_DIS))){
cabinetTemperatureStatusRecord = TEMP_NORMAL; cabTempDis = TEMP_DIS;
}else if((pTempStatusInfo->CurrentTemperature.cabinetTemperature >=((float)20.0 +CAB_TEMP_DIS))&& (pTempStatusInfo->CurrentTemperature.cabinetTemperature <((float)50.0 -CAB_TEMP_DIS))){
cabinetTemperatureStatusRecord = TEMP_HIGH; cabTempDis = TEMP_DIS;
}else if((pTempStatusInfo->CurrentTemperature.cabinetTemperature >=((float)50.0 +CAB_TEMP_DIS))&& (pTempStatusInfo->CurrentTemperature.cabinetTemperature <((float)80.0 -CAB_TEMP_DIS))){
cabinetTemperatureStatusRecord = TEMP_HIGHER; cabTempDis = TEMP_DIS;
}else if((pTempStatusInfo->CurrentTemperature.cabinetTemperature >=((float)80.0 +CAB_TEMP_DIS))&& (pTempStatusInfo->CurrentTemperature.cabinetTemperature <((float)120.0 -CAB_TEMP_DIS))){
cabinetTemperatureStatusRecord = TEMP_HIGHEST; cabTempDis = TEMP_DIS;
}else if(pTempStatusInfo->CurrentTemperature.cabinetTemperature >=((float)120.0 +CAB_TEMP_DIS)){
cabinetTemperatureStatusRecord = TEMP_TOO_HIGH; cabTempDis = TEMP_DIS;
}
/* Time count incresa, status keep,avoid state on edge space */
if(pTempStatusInfo->CabinetTempStatus != cabinetTemperatureStatusRecord){
if(cabinetTemperatureStatusTime < TEMP_STATE_KEEP_TIME){
cabinetTemperatureStatusTime ++;
}else{
pTempStatusInfo->CabinetTempStatus = cabinetTemperatureStatusRecord;
}
}else{
cabinetTemperatureStatusTime = 0;
}
/* TempAbnormal check */
if((fabs(pTempStatusInfo->CurrentTemperature.cabinetTopTemperature - pTempStatusInfo->CurrentTemperature.cabinetBottomTemperature)) > TEMP_MAX_DIS_VALUE ){
RoSafety.SafetyStatus.SafetyFlagBit.bit_CabinetTempAbnormal = 1;
}else if((pTempStatusInfo->CabinetTempStatus >= TEMP_HIGHEST)||(pTempStatusInfo->CabinetTempStatus <= TEMP_TOO_LOW)){
RoSafety.SafetyStatus.SafetyFlagBit.bit_CabinetTempAbnormal = 1;
}else{
RoSafety.SafetyStatus.SafetyFlagBit.bit_CabinetTempAbnormal = 0;
}
/* for bettery: judge the status */
#ifdef TEST_TEMPERATURE
pTempStatusInfo->CurrentTemperature.batteryTopTemperature = 20.0;
pTempStatusInfo->CurrentTemperature.batteryBottomTemperature = 20.0;
#else
int8_t pt100ErrFlag = 0;
static float batteryTemperatureAverage = 0.0;
if((-2) == max31865.readTemperature(PT100_TEMP_SENSOR_1ST,&pTempStatusInfo->CurrentTemperature.batteryTopTemperature)){
pt100ErrFlag |= 0x01;
}
if((-2) == max31865.readTemperature(PT100_TEMP_SENSOR_2ND,&pTempStatusInfo->CurrentTemperature.batteryBottomTemperature)){
pt100ErrFlag |= 0x10;
}
if(pt100ErrFlag == 0x11){
RoSafety.SafetyStatus.SafetyFlagBit.bit_BatteryTempSensor = 1;
}else if(pt100ErrFlag == 0x01){
RoSafety.SafetyStatus.SafetyFlagBit.bit_OneBatTmpErr = 1;
RoSafety.SafetyStatus.SafetyFlagBit.bit_BatteryTempSensor = 0;
pTempStatusInfo->CurrentTemperature.batteryTopTemperature = pTempStatusInfo->CurrentTemperature.batteryBottomTemperature;
}else if(pt100ErrFlag == 0x10){
RoSafety.SafetyStatus.SafetyFlagBit.bit_OneBatTmpErr = 1;
RoSafety.SafetyStatus.SafetyFlagBit.bit_BatteryTempSensor = 0;
pTempStatusInfo->CurrentTemperature.batteryBottomTemperature = pTempStatusInfo->CurrentTemperature.batteryTopTemperature;
}else{
RoSafety.SafetyStatus.SafetyFlagBit.bit_OneBatTmpErr = 0;
RoSafety.SafetyStatus.SafetyFlagBit.bit_BatteryTempSensor = 0;
}
/* Choose the worst temperature */
if((pTempStatusInfo->CurrentTemperature.batteryTopTemperature * pTempStatusInfo->CurrentTemperature.batteryBottomTemperature) > 0){
batteryTemperatureAverage = (fabs(pTempStatusInfo->CurrentTemperature.batteryTopTemperature) > fabs(pTempStatusInfo->CurrentTemperature.batteryBottomTemperature))\
? pTempStatusInfo->CurrentTemperature.batteryTopTemperature:pTempStatusInfo->CurrentTemperature.batteryBottomTemperature;
}else{
batteryTemperatureAverage = (pTempStatusInfo->CurrentTemperature.batteryBottomTemperature < 0)
? pTempStatusInfo->CurrentTemperature.batteryBottomTemperature:pTempStatusInfo->CurrentTemperature.batteryTopTemperature;
}
pTempStatusInfo->CurrentTemperature.batteryTemperature = batteryTemperatureAverage;
#endif
/* For protect a large jump */
if(fabs(s_batteryTemperature - pTempStatusInfo->CurrentTemperature.batteryTemperature) >= 5.0){
batTempDis = 0.0;
}
s_batteryTemperature = pTempStatusInfo->CurrentTemperature.batteryTemperature;
/* Calulate the temperature status */
if(pTempStatusInfo->CurrentTemperature.batteryTemperature < ((float)-40.0 -BAT_TEMP_DIS)){
batteryTemperatureStatusRecord = TEMP_TOO_LOW; batTempDis = TEMP_DIS;
}else if((pTempStatusInfo->CurrentTemperature.batteryTemperature >= ((float)-40.0 +BAT_TEMP_DIS))&& (pTempStatusInfo->CurrentTemperature.batteryTemperature < ((float)-20.0 -BAT_TEMP_DIS))){
batteryTemperatureStatusRecord = TEMP_LOWEST; batTempDis = TEMP_DIS;
}else if((pTempStatusInfo->CurrentTemperature.batteryTemperature >=((float)-20.0 +BAT_TEMP_DIS))&& (pTempStatusInfo->CurrentTemperature.batteryTemperature <((float)-10.0 -BAT_TEMP_DIS))){
batteryTemperatureStatusRecord = TEMP_LOWER; batTempDis = TEMP_DIS;
}else if((pTempStatusInfo->CurrentTemperature.batteryTemperature >=((float)-10.0 +BAT_TEMP_DIS))&& (pTempStatusInfo->CurrentTemperature.batteryTemperature <((float)1.0 -BAT_TEMP_DIS))){
batteryTemperatureStatusRecord = TEMP_LOW; batTempDis = TEMP_DIS;
}else if((pTempStatusInfo->CurrentTemperature.batteryTemperature >=((float)1.0 +BAT_TEMP_DIS))&& (pTempStatusInfo->CurrentTemperature.batteryTemperature <((float)20.0 -BAT_TEMP_DIS))){
batteryTemperatureStatusRecord = TEMP_NORMAL; batTempDis = TEMP_DIS;
}else if((pTempStatusInfo->CurrentTemperature.batteryTemperature >=((float)20.0 +BAT_TEMP_DIS))&& (pTempStatusInfo->CurrentTemperature.batteryTemperature <((float)50.0 -BAT_TEMP_DIS))){
batteryTemperatureStatusRecord = TEMP_HIGH; batTempDis = TEMP_DIS;
}else if((pTempStatusInfo->CurrentTemperature.batteryTemperature >=((float)50.0 +BAT_TEMP_DIS))&& (pTempStatusInfo->CurrentTemperature.batteryTemperature <((float)80.0 -BAT_TEMP_DIS))){
batteryTemperatureStatusRecord = TEMP_HIGHER; batTempDis = TEMP_DIS;
}else if((pTempStatusInfo->CurrentTemperature.batteryTemperature >=((float)80.0 +BAT_TEMP_DIS))&& (pTempStatusInfo->CurrentTemperature.batteryTemperature <((float)120.0 -BAT_TEMP_DIS))){
batteryTemperatureStatusRecord = TEMP_HIGHEST; batTempDis = TEMP_DIS;
}else if(pTempStatusInfo->CurrentTemperature.batteryTemperature >=((float)120.0 +BAT_TEMP_DIS)){
batteryTemperatureStatusRecord = TEMP_TOO_HIGH; batTempDis = TEMP_DIS;
}
if(pTempStatusInfo->BatteryTempStatus != batteryTemperatureStatusRecord){
if(batteryTemperatureStatusTime < TEMP_STATE_KEEP_TIME){
batteryTemperatureStatusTime ++;
}else{
pTempStatusInfo->BatteryTempStatus = batteryTemperatureStatusRecord;
}
}else{
batteryTemperatureStatusTime = 0;
}
/* TempAbnormal check */
if((fabs(pTempStatusInfo->CurrentTemperature.batteryTopTemperature - pTempStatusInfo->CurrentTemperature.batteryBottomTemperature)) > TEMP_MAX_DIS_VALUE ){
RoSafety.SafetyStatus.SafetyFlagBit.bit_BatteryTempAbnormal = 1;
}else if((pTempStatusInfo->BatteryTempStatus >= TEMP_HIGHER)||(pTempStatusInfo->BatteryTempStatus <= TEMP_LOWEST)){
RoSafety.SafetyStatus.SafetyFlagBit.bit_BatteryTempAbnormal = 1;
}else{
RoSafety.SafetyStatus.SafetyFlagBit.bit_BatteryTempAbnormal = 0;
}
return 0;
}
/*******************************************************************************
* Initialization for GPIO, ported from icore3 *
*******************************************************************************/
int8_t RoTempManage_tempManage(void)
{
#define CHECK_TEMP_PER_TIME 1 // 2 * 100 mS
static int32_t s_CheckPerSec = 0;
if(s_CheckPerSec > 0){
s_CheckPerSec--;
}else{
RoTempManage_checkCurrrentTemperature(&RoTempManage.TempStatusInfo);
s_CheckPerSec = CHECK_TEMP_PER_TIME;
}
return 0;
}