This repository has been archived on 2025-02-28. You can view files and clone it, but cannot push or open issues or pull requests.
controller-hd/User/application/src/convert.c

384 lines
8.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @file convert.c
* @author xxx
* @date 2023-08-30 08:58:43
* @brief 此文件实现数据处理、转换等功能
* @copyright Copyright (c) 2023 by xxx, All Rights Reserved.
*/
#include "../inc/convert.h"
#include "../inc/params.h"
#include "board.h"
#include <math.h>
#include "eeprom_fm24.h"
#include "mode.h"
static float32 last_travel = 0; // 上次目标值
/**
* @brief 判断运行方向
* @return {*}
* @note
*/
void adjust_target_direction(void)
{
// 计算 actual_travel 和 target_travel 的误差
target_actual_diff = pid_target - pid_actual;
// 通过当前行程和目标行程来判断移动方向
if (target_actual_diff >= 0)
{
target_direction = 1;
}
else
{
target_direction = 0;
}
}
/**
* @brief 获取显示行程
* @param {float32} in - 行程百分比
* @return {float32} 显示行程
* @note
*/
float32 get_show_travel(float32 in)
{
float32 travel = in;
if (uDevice.eTravelDispMode == TRAVEL_DISPLAY_REVERSE) // 反向显示
{
travel = 100 - travel;
}
return travel;
}
/**
* @brief 获取PID控制行程
* @param {float32} in - 行程百分比
* @return {float32} PID控制行程
* @note
*/
float32 get_pid_travel(float32 in)
{
float32 travel = in;
if (uDevice.eAirAction == ATC) // 气关
{
travel = 100 - travel;
}
return travel;
}
/**
* @brief 实际行程处理
* @param {float32} in - 实际行程
* @return {*}
* @note
*/
float32 actual_travel_deal(float32 in)
{
float32 travel = in;
if (!is_manual_test())
{
// SWO输出
swo_output_deal(travel);
// PWM输出阀位占空比
pwm_output_deal(travel);
}
return travel;
}
/**
* @brief PWM输出处理
* @param {float32} in - 行程百分比
* @return {*}
* @note
*/
void pwm_output_deal(float32 in)
{
float32 travel = in;
if (uDevice.mAOutputEnable == true) // pwm输出使能
{
pwm_output_position(travel);
}
}
void swo_output_deal(float32 in)
{
float32 travel = in;
if (uDevice.eSWTriggerLogic[0] == TRIGGER_LOGIC_BELOW)
{
if (travel < uDevice.SWTriggerValue[0])
SWO1_OPEN();
else
SWO1_CLOSE();
}
else if (uDevice.eSWTriggerLogic[0] == TRIGGER_LOGIC_ABOVE)
{
if (travel > uDevice.SWTriggerValue[0])
SWO1_OPEN();
else
SWO1_CLOSE();
}
else
{
SWO1_CLOSE();
}
if (uDevice.eSWTriggerLogic[1] == TRIGGER_LOGIC_BELOW)
{
if (travel < uDevice.SWTriggerValue[1])
SWO2_OPEN();
else
SWO2_CLOSE();
}
else if (uDevice.eSWTriggerLogic[1] == TRIGGER_LOGIC_ABOVE)
{
if (travel > uDevice.SWTriggerValue[1])
SWO2_OPEN();
else
SWO2_CLOSE();
}
else
{
SWO2_CLOSE();
}
}
/**
* @brief 目标行程处理
* @param {float32} in - 行程百分比
* @return {float32} 目标行程
* @note
*/
float32 target_travel_deal(float32 in)
{
float32 travel = in;
// 小信号切除
travel = small_signal_deal(travel);
// 死区处理
travel = dead_zone_deal(travel);
// 分程处理
travel = part_travel_deal(travel);
return travel;
}
/**
* @brief 分程处理
* @param {float32} *in - 行程百分比
* @return {*}
* @note
*/
float32 part_travel_deal(float32 in)
{
float32 travel = in;
float32 min = uDevice.PartTravelMin;
float32 max = uDevice.PartTravelMax;
if (uDevice.PartTravelEnable == true) // 部分行程
{
travel = (max - min) * travel * 0.01f + min;
}
return travel;
}
/**
* @brief 死区处理
* @param {float32} in
* @return {*}
* @note
*/
float32 dead_zone_deal(float32 in)
{
float32 travel = in;
float32 target_diff = fabsf(travel - last_travel);
if (target_diff >= uDevice.TravelDead)
{
last_travel = travel;
}
return last_travel;
}
/**
* @brief 小信号切除
* @param {float32} *in - 行程百分比
* @return {*}
* @note
*/
float32 small_signal_deal(float32 in)
{
float32 travel = in;
float32 SmallSignalLower = 0;
float32 SmallSignalUpper = 0;
if (uDevice.SmallSignalCutEnable > 0) // 使能,使用设定值
{
SmallSignalLower = uDevice.SmallSignalLower;
SmallSignalUpper = uDevice.SmallSignalUpper;
}
else // 禁用,使用默认值
{
SmallSignalLower = 0;
SmallSignalUpper = 100;
}
// 最大最小需要快速的反应
if (travel >= SmallSignalUpper) // 上限
{
travel = 100.0;
}
else if (travel <= SmallSignalLower) // 下限
{
travel = 0;
}
return travel;
}
/**
* @brief 4~20mA输入电流转换成需要控制的阀门开度(不是显示的开度) %(1位小数如 0~100%, 100% = 1000)
* @param {float32} in 当前输入的电流值
* @return {float32} 阀门开度 - 百分比
*/
float32 i2psb(float32 in)
{
float32 deltI, ftmp;
float32 travel;
uint16_t index;
if (in < LOOP_CURRENT_MIN)
{
return 0;
}
else
{
// 计算相邻两个点之间的电流差值
deltI = uDevice.InputIH - uDevice.InputIL;
deltI /= 16;
// 判断输入电流在哪个范围内
ftmp = in - LOOP_CURRENT_MIN;
index = ftmp / deltI;
/* 计算百分比
(I - Iindex)
% = ------------- * (%[index+1]-%[index]) + %[index]
deltI
*/
if (index > 15)
{
ftmp = valve_characteristics_table[uDevice.eValveCharacteristics][16];
}
else
{
ftmp = in - LOOP_CURRENT_MIN;
ftmp -= deltI * index;
ftmp /= deltI;
ftmp *= (valve_characteristics_table[uDevice.eValveCharacteristics][index + 1] - valve_characteristics_table[uDevice.eValveCharacteristics][index]);
ftmp += valve_characteristics_table[uDevice.eValveCharacteristics][index];
}
}
ftmp /= 100;
/*
定位器的正作用输入信号I增大时输出的气压增大
定位器的反作用输入信号I增大时输出的气压减小
*/
if (uDevice.eAirAction == ATO)
{
// 气开
if (uDevice.eControllerAction == CONTROLLER_ACTING_NORMAL)
{
// 定位器正作用:电流增大->气压增大->弹簧压缩->开方向->%增大(正显示、反馈)
travel = ftmp;
}
else if (uDevice.eControllerAction == CONTROLLER_ACTING_REVERSE)
{
// 定位器反作用:电流增大->气压减小->弹簧释放->关方向->%减小(正显示、反馈)
travel = 100 - ftmp;
}
else
{
travel = ftmp;
}
}
else
{
// 气关
if (uDevice.eControllerAction == CONTROLLER_ACTING_NORMAL)
{
// 定位器正作用:电流增大->气压增大->弹簧压缩->关方向->%减小(正显示、反馈)
travel = 100 - ftmp;
}
else
{
// 定位器反作用:电流增大->气压减小->弹簧释放->开方向->%增大(正显示、反馈)
travel = ftmp;
}
}
if (travel < 0)
travel = 0;
else if (travel > 100)
travel = 100;
return travel;
}
/**
* @brief 温度值转换:摄氏度转华氏度
* @param {float32} celsius 摄氏度
* @return {float32} 华氏度
* @note
*/
float32 temperature_c2f(float32 celsius)
{
float32 temp = 32 + celsius * 1.8f;
return temp;
}
/**
* @brief 压力值转换kPa -> mPa psi bar kgf/cm2
* @param {float32} kpa 压力值 kPa
* @param {uint16_t} unit 要转换的单位
* @return {float32} 转换后的压力值
* @note
*/
float32 pressure_kpa2unit(float32 kpa, uint16_t unit)
{
float32 pre = 0;
switch (unit)
{
case PRESSURE_UNIT_Kpa: // kPa
pre = kpa;
break;
case PRESSURE_UNIT_Mpa: // mPa
pre = kpa * 0.001f;
break;
case PRESSURE_UNIT_Psi: // psi
pre = kpa * 0.145037743897f;
break;
case PRESSURE_UNIT_Bar: // bar
pre = kpa * 0.01f;
break;
case PRESSURE_UNIT_Kgf: // kgf/cm2
pre = kpa * 0.0101972f;
break;
default:
pre = kpa;
break;
}
return pre;
}