| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422 |
- /**
- * @file ALGO_Temperature_ATY.c
- *
- * @param Project ALGO_Algorithm_ATY_LIB
- *
- * @author ATY
- *
- * @copyright
- * - Copyright 2017 - 2025 MZ-ATY
- * - This code follows:
- * - MZ-ATY Various Contents Joint Statement -
- * <a href="https://mengze.top/MZ-ATY_VCJS">
- * https://mengze.top/MZ-ATY_VCJS</a>
- * - CC 4.0 BY-NC-SA -
- * <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
- * https://creativecommons.org/licenses/by-nc-sa/4.0/</a>
- * - Your use will be deemed to have accepted the terms of this statement.
- *
- * @brief Familiar functions of NTC or others temperature calc
- *
- * @version
- * - 1_01_230107 > ATY
- * -# Preliminary version, first Release
- ********************************************************************************
- */
- #ifndef __ALGO_Temperature_ATY_C
- #define __ALGO_Temperature_ATY_C
- #include "ALGO_Temperature_ATY.h"
- /******************************* For user *************************************/
- /******************************************************************************/
- /**
- * @brief Calculate temperature from ntc resistance(Steinhart-Hart)
- * @param Rntc Current NTC resistance value
- * @param A A value of NTC
- * @param B B value of NTC
- * @param C C value of NTC
- * @return Current temperature in Celsius
- */
- double ALGO_ResToKelvinTempABC(double Rntc, double A, double B, double C)
- {
- double Tn = 0.0;
- double Cn = 0.0;
- Tn = (A + (B * ALGO_MATH_LogLn(Rntc)) + (C * ALGO_MATH_LogLn(Rntc) * ALGO_MATH_LogLn(Rntc) * ALGO_MATH_LogLn(Rntc)));
- Tn = 1.0 / Tn;
- Cn = ALGO_TEMP_TtoC(Tn);
- return Cn;
- }
- /**
- * @brief Calculate temperature from ntc resistance(Steinhart-Hart change)
- * @param Rntc Current NTC resistance value
- * @param R25 NTC standard resistance value at 25C
- * @param B B value of NTC
- * @return Current temperature in Celsius
- * @note T25: Kelvin temperature at 25C = 298.15 = ALGO_TEMP_CtoT(25)
- * R25: NTC standard resistance value at 25C like 10K,5K,100K...
- * B: B value of NTC like 3435,3950...
- * Rntc: Current NTC resistance value
- * Tn: Actual Kelvin temperature(Cn = Tn-273.15)
- * B = (lnR25 - lnRntc)/(1/T25 - 1/Tn)
- */
- #include "math.h"
- double ALGO_ResToKelvinTemp(double Rntc, double R25, double B)
- {
- if(Rntc <= 0) return 0;
- if(R25 <= 0) return 0;
- double Tn = 0.0;
- double Cn = 0.0;
- double temp_f[2];
- // temp_f[0] = (ALGO_MATH_LogLn(R25) - ALGO_MATH_LogLn(Rntc)) / B;
- temp_f[0] = (log(R25) - log(Rntc)) / B;
- temp_f[1] = (1.0 / ALGO_TEMP_CtoT(25)) - temp_f[0];
- Tn = 1.0 / temp_f[1];
- Cn = ALGO_TEMP_TtoC(Tn);
- return Cn;
- }
- /**
- * @brief Calculate temperature from ntc resistance
- * @param vADC ADC voltage in mV
- * @param vRef NTC ref voltage in mV
- * @param rRefK ref resistance in kOhm
- * @param R25 NTC standard resistance value at 25C
- * @param B B value of NTC
- * @param rRefPos ref res psition, 1 for pull up, 0 for pull down(for ntc)
- * @return Current temperature in Celsius
- * @note T25: Kelvin temperature at 25C = 298.15 = ALGO_TEMP_CtoT(25)
- * R25: NTC standard resistance value at 25C like 10K,5K,100K...
- * B: B value of NTC like 3435,3950...
- * Rntc: Current NTC resistance value
- * Tn: Actual Kelvin temperature(Cn = Tn-273.15)
- * B = (lnR25 - lnRntc)/(1/T25 - 1/Tn)
- */
- double ALGO_VolToKelvinTemp(double vADC, double vRef, double rRefK, double R25, double B, uint8_t rRefPos)
- {
- if(rRefPos == 1){
- return ALGO_ResToKelvinTemp(ALGO_VoltageToResDown(vADC, vRef, rRefK), R25, B);
- }
- else{
- return ALGO_ResToKelvinTemp(ALGO_VoltageToResUp(vADC, vRef, rRefK), R25, B);
- }
- }
- // PT100
- double ALGO_Temp_RTD_Res_Fast(double rtdRes)
- {
- return (double)((rtdRes - 100.0) / 0.385);
- }
- // #include "math.h"
- #include "ALGO_AlgorithmBase_ATY.h"
- double ALGO_Temp_RTD_Res_Above(double rtdRes)
- {
- return (double)((-(3.9083e-3)
- + ALGO_Sqrt_NewtonNumber(((3.9083e-3) * (3.9083e-3))
- // + sqrt(((3.9083e-3) * (3.9083e-3))
- - 4 * (-5.775e-7) * (1 - (rtdRes / 100.0))))
- / (2 * (-5.775e-7)));
- }
- double ALGO_Temp_RTD_Res_Below(double rtdRes)
- {
- return (double)(-242.02
- + 2.2228 * rtdRes
- + (2.5859e-3) * rtdRes * rtdRes
- - (4.826e-6) * rtdRes * rtdRes * rtdRes
- - (2.8183e-8) * rtdRes * rtdRes * rtdRes * rtdRes
- + (1.5243e-10) * rtdRes * rtdRes * rtdRes * rtdRes * rtdRes);
- }
- // PT1000
- // R(t)=R0(1+At+Bt2)
- // A=0.0038623139728
- // B=-0.00000065314932626
- #include "math.h"
- #define A 3.9083e-3
- #define B -5.775e-7
- #define C -4.183e-12
- //#define A2 3.9083e-2
- //#define B2 -5.775e-6
- //#define C2 -4.183e-11
- double ALGO_Temp_RTD_T_PT1000(double T)
- {
- if(T >= -200 && T < 0)
- {
- return 100 * (1 + A * T + B * T * T + C * (T - 100) * T * T * T);
- }
- else if(T >= 0 && T <= 850)
- {
- return 100 * (1 + A * T + B * T * T);
- }
- return 0;
- }
- /**
- * @brief ???????
- * @param[in] resist ??
- * @param[out] temp ???
- * @retval ????
- * @note ????????,????????????,?1?3??????????????:
- * 1. ???????????????:
- * t1 = (Rt / R0 - 1) / A
- *
- * ??t1???:
- * 0??????:Rt1 = R0 * (1 + A * t1 + B * t1 * t1);
- * 0??????:Rt1 = R0 * [1 + A * t1 + B * t1 * t1 + C * (t1 - 100) * t1 * t1 * t1];
- *
- * ?? |Rt1 - Rt| < 0.001,t1 ???????,???????????:
- *
- * 2. ???????????:
- * ?? Rt = R0
- * t1' = 1 / [R0 * (A + 2 * B * t1)]
- * t1'' =-2 * B * R0 * t1' * t1' * t1'
- * ?? Rt < R0
- * t1' = 1 / [R0 * (A + 2 * B * t1 - 300 * C * t1 * t1 + 4 * C * t1 * t1 * t1)]
- * t1''=- R0 * (2 * B - 600 * C * t1 + 12 * C * t1 * t1) * t1' * t1' * t1'
- *
- * 3. ?? Rt,t1,Rt1 ?????? t2:
- * t2 = t1 + t1' * (Rt - Rt1) + 0.5 * t1'' * (Rt - Rt1) * (Rt - Rt1),???? t2 ????? Rt2?
- *
- * 4. ?? |Rt2 - Rt| < 0.001,t2 ???????,??????????? t2 ??????,???????????
- */
- double ALGO_Temp_RTD_Res_PT100(double resist)
- {
- double fT, fT0;
- short i;
- /* 1. use a linear formula to get a rough temperature first */
- fT0 = (resist / 100 - 1) / A;
- /* -200C ~ 0C */
- if(resist >= 18.52 && resist < 100)
- {
- for(i = 0; i < 50; i++)
- {
- fT = fT0 + (resist - 100 * (1 + A * fT0 + B * fT0 * fT0 - 100 * C * fT0 * fT0 * fT0 + C * fT0 * fT0 * fT0 * fT0)) /
- (100 * (A + 2 * B * fT0 - 300 * C * fT0 * fT0 + 4 * C * fT0 * fT0 * fT0));
- if(fabs(fT - fT0) < 0.001) /* If | Rt1-Rt | < 0.001, t1 is the desired temperature */
- {
- return fT;
- }
- else
- {
- fT0 = fT;
- }
- }
- }
- /* 0C ~ 850C */
- else if(resist >= 100 && resist <= 390.481)
- {
- for(i = 0; i < 50; i++)
- {
- fT = fT0 + (resist - 100 * (1 + A * fT0 + B * fT0 * fT0)) / (100 * (A + 2 * B * fT0));
- if(fabs(fT - fT0) < 0.001) /* If | Rt1-Rt | < 0.001, t1 is the desired temperature */
- {
- return fT;
- }
- else
- {
- fT0 = fT;
- }
- }
- }
- return 0;
- }
- double ALGO_Temp_RTD_Res_PT1000(double resist)
- {
- return ALGO_Temp_RTD_Res_PT100(resist / 10.0);
- }
- /**
- * @brief
- *
- * @param type
- * @param Temp in Degrees Celsius
- * @return double in mV
- * @note https://srdata.nist.gov/
- */
- double ALGO_Temp_TC_TempToVol(uint8_t type, double Temp)
- {
- if(type == 'T'){
- if(Temp == 0)
- return 0;
- else if(Temp > 0){
- return (0
- + ((0.387481063640e-1) * Temp)
- + ((0.332922278800e-4) * Temp * Temp)
- + ((0.206182434040e-6) * Temp * Temp * Temp)
- + ((-0.218822568460e-8) * Temp * Temp * Temp * Temp)
- + ((0.109968809280e-10) * Temp * Temp * Temp * Temp * Temp)
- + ((-0.308157587720e-13) * Temp * Temp * Temp * Temp * Temp * Temp)
- + ((0.454791352900e-16) * Temp * Temp * Temp * Temp * Temp * Temp * Temp)
- + ((-0.275129016730e-19) * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp));
- }
- else if(Temp < 0){
- return (0
- + ((0.387481063640e-01) * Temp)
- + ((0.441944343470e-04) * Temp * Temp)
- + ((0.118443231050e-06) * Temp * Temp * Temp)
- + ((0.200329735540e-07) * Temp * Temp * Temp * Temp)
- + ((0.901380195590e-09) * Temp * Temp * Temp * Temp * Temp)
- + ((0.226511565930e-10) * Temp * Temp * Temp * Temp * Temp * Temp)
- + ((0.360711542050e-12) * Temp * Temp * Temp * Temp * Temp * Temp * Temp)
- + ((0.384939398830e-14) * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp)
- + ((0.282135219250e-16) * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp)
- + ((0.142515947790e-18) * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp)
- + ((0.487686622860e-21) * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp)
- + ((0.107955392700e-23) * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp)
- + ((0.139450270620e-26) * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp)
- + ((0.797951539270e-30) * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp));
- }
- }
- return 0;
- }
- /**
- * @brief
- *
- * @param type
- * @param voltage in mV
- * @return double in Degrees Celsius
- * @note https://srdata.nist.gov/
- */
- double ALGO_Temp_TC_VolToTemp(uint8_t type, double voltage)
- {
- if(type == 'T'){
- if(voltage == 0)
- return 0;
- else if(voltage > 0){
- return (0
- + ((2.592800e1) * voltage)
- + ((-7.602961e-1) * voltage * voltage)
- + ((4.637791e-2) * voltage * voltage * voltage)
- + ((-2.165394e-3) * voltage * voltage * voltage * voltage)
- + ((6.048144e-5) * voltage * voltage * voltage * voltage * voltage)
- + ((-7.293422e-7) * voltage * voltage * voltage * voltage * voltage * voltage));
- }
- else if(voltage < 0){
- return (0
- + ((2.5949192e1) * voltage)
- + ((-2.1316967e-1) * voltage * voltage)
- + ((7.9018692e-1) * voltage * voltage * voltage)
- + ((4.2527777e-1) * voltage * voltage * voltage * voltage)
- + ((1.3304473e-1) * voltage * voltage * voltage * voltage * voltage)
- + ((2.0241446e-2) * voltage * voltage * voltage * voltage * voltage * voltage)
- + ((1.2668171e-3) * voltage * voltage * voltage * voltage * voltage * voltage * voltage));
- }
- }
- return 0;
- }
- // resultTemp = ALGO_ResToKelvinTemp(ALGO_VoltageToResDown(resultTemp, vref_t, 10), 1, 3200);
- // T in C, R in R
- /**
- * @brief
- *
- * @param R in R, or v to Thermocouple, just follow your tableR
- * @param tableT
- * @param tableR
- * @param tableSize T/R table must be the same size
- * @return double
- */
- double ALGO_RT_Table_R2T(double R, const double* tableT, const double* tableR, uint16_t tableSize)
- {
- // negative temperature coefficient, like ntc
- if(tableR[0] > tableR[1]){
- // check border
- if(R < tableR[tableSize - 1] || R > tableR[0]) {
- return -273.15;
- }
- // cycle
- for(uint16_t i = 0; i < tableSize - 1; i++) {
- if(R == tableR[i]){
- return tableT[i];
- }
- if(R <= tableR[i] && R >= tableR[i + 1]) {
- double T1 = tableT[i];
- double T2 = tableT[i + 1];
- double R1 = tableR[i];
- double R2 = tableR[i + 1];
- return T1 + (R - R1) * (T2 - T1) / (R2 - R1);
- }
- }
- }
- // positive temperature coefficient, like rtd
- else{
- // check border
- if(R > tableR[tableSize - 1] || R < tableR[0]) {
- return -273.15;
- }
- // cycle
- for(uint16_t i = 0; i < tableSize - 1; i++) {
- if(R == tableR[i]){
- return tableT[i];
- }
- if(R >= tableR[i] && R <= tableR[i + 1]) {
- double T1 = tableT[i];
- double T2 = tableT[i + 1];
- double R1 = tableR[i];
- double R2 = tableR[i + 1];
- return T1 + (R - R1) * (T2 - T1) / (R2 - R1);
- }
- }
- }
- return -273.15;
- }
- /**
- * @brief
- *
- * @param T in C, just follow your tableT
- * @param tableT
- * @param tableR
- * @param tableSize T/R table must be the same size
- * @return double
- */
- double ALGO_RT_Table_T2R(double T, const double* tableT, const double* tableR, uint16_t tableSize)
- {
- // check border
- if(T > tableT[tableSize - 1] ||
- T < tableT[0]) {
- return -273.15;
- }
- // cycle
- for(uint16_t i = 0; i < tableSize - 1; i++) {
- if(T == tableR[i]){
- return tableT[i];
- }
- if(T <= tableR[i] && T >= tableR[i + 1]) {
- double T1 = tableT[i];
- double T2 = tableT[i + 1];
- double R1 = tableR[i];
- double R2 = tableR[i + 1];
- return R1 + (T - T1) * (R2 - R1) / (T2 - T1);
- }
- }
- return -273.15;
- }
- #endif /* __ALGO_Temperature_ATY_C */
- /******************************** End Of File *********************************/
|