ALGO_Temperature_ATY.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. /**
  2. * @file ALGO_Temperature_ATY.c
  3. *
  4. * @param Project ALGO_Algorithm_ATY_LIB
  5. *
  6. * @author ATY
  7. *
  8. * @copyright
  9. * - Copyright 2017 - 2025 MZ-ATY
  10. * - This code follows:
  11. * - MZ-ATY Various Contents Joint Statement -
  12. * <a href="https://mengze.top/MZ-ATY_VCJS">
  13. * https://mengze.top/MZ-ATY_VCJS</a>
  14. * - CC 4.0 BY-NC-SA -
  15. * <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
  16. * https://creativecommons.org/licenses/by-nc-sa/4.0/</a>
  17. * - Your use will be deemed to have accepted the terms of this statement.
  18. *
  19. * @brief Familiar functions of NTC or others temperature calc
  20. *
  21. * @version
  22. * - 1_01_230107 > ATY
  23. * -# Preliminary version, first Release
  24. ********************************************************************************
  25. */
  26. #ifndef __ALGO_Temperature_ATY_C
  27. #define __ALGO_Temperature_ATY_C
  28. #include "ALGO_Temperature_ATY.h"
  29. /******************************* For user *************************************/
  30. /******************************************************************************/
  31. /**
  32. * @brief Calculate temperature from ntc resistance(Steinhart-Hart)
  33. * @param Rntc Current NTC resistance value
  34. * @param A A value of NTC
  35. * @param B B value of NTC
  36. * @param C C value of NTC
  37. * @return Current temperature in Celsius
  38. */
  39. double ALGO_ResToKelvinTempABC(double Rntc, double A, double B, double C)
  40. {
  41. double Tn = 0.0;
  42. double Cn = 0.0;
  43. Tn = (A + (B * ALGO_MATH_LogLn(Rntc)) + (C * ALGO_MATH_LogLn(Rntc) * ALGO_MATH_LogLn(Rntc) * ALGO_MATH_LogLn(Rntc)));
  44. Tn = 1.0 / Tn;
  45. Cn = ALGO_TEMP_TtoC(Tn);
  46. return Cn;
  47. }
  48. /**
  49. * @brief Calculate temperature from ntc resistance(Steinhart-Hart change)
  50. * @param Rntc Current NTC resistance value
  51. * @param R25 NTC standard resistance value at 25C
  52. * @param B B value of NTC
  53. * @return Current temperature in Celsius
  54. * @note T25: Kelvin temperature at 25C = 298.15 = ALGO_TEMP_CtoT(25)
  55. * R25: NTC standard resistance value at 25C like 10K,5K,100K...
  56. * B: B value of NTC like 3435,3950...
  57. * Rntc: Current NTC resistance value
  58. * Tn: Actual Kelvin temperature(Cn = Tn-273.15)
  59. * B = (lnR25 - lnRntc)/(1/T25 - 1/Tn)
  60. */
  61. #include "math.h"
  62. double ALGO_ResToKelvinTemp(double Rntc, double R25, double B)
  63. {
  64. if(Rntc <= 0) return 0;
  65. if(R25 <= 0) return 0;
  66. double Tn = 0.0;
  67. double Cn = 0.0;
  68. double temp_f[2];
  69. // temp_f[0] = (ALGO_MATH_LogLn(R25) - ALGO_MATH_LogLn(Rntc)) / B;
  70. temp_f[0] = (log(R25) - log(Rntc)) / B;
  71. temp_f[1] = (1.0 / ALGO_TEMP_CtoT(25)) - temp_f[0];
  72. Tn = 1.0 / temp_f[1];
  73. Cn = ALGO_TEMP_TtoC(Tn);
  74. return Cn;
  75. }
  76. /**
  77. * @brief Calculate temperature from ntc resistance
  78. * @param vADC ADC voltage in mV
  79. * @param vRef NTC ref voltage in mV
  80. * @param rRefK ref resistance in kOhm
  81. * @param R25 NTC standard resistance value at 25C
  82. * @param B B value of NTC
  83. * @param rRefPos ref res psition, 1 for pull up, 0 for pull down(for ntc)
  84. * @return Current temperature in Celsius
  85. * @note T25: Kelvin temperature at 25C = 298.15 = ALGO_TEMP_CtoT(25)
  86. * R25: NTC standard resistance value at 25C like 10K,5K,100K...
  87. * B: B value of NTC like 3435,3950...
  88. * Rntc: Current NTC resistance value
  89. * Tn: Actual Kelvin temperature(Cn = Tn-273.15)
  90. * B = (lnR25 - lnRntc)/(1/T25 - 1/Tn)
  91. */
  92. double ALGO_VolToKelvinTemp(double vADC, double vRef, double rRefK, double R25, double B, uint8_t rRefPos)
  93. {
  94. if(rRefPos == 1){
  95. return ALGO_ResToKelvinTemp(ALGO_VoltageToResDown(vADC, vRef, rRefK), R25, B);
  96. }
  97. else{
  98. return ALGO_ResToKelvinTemp(ALGO_VoltageToResUp(vADC, vRef, rRefK), R25, B);
  99. }
  100. }
  101. // PT100
  102. double ALGO_Temp_RTD_Res_Fast(double rtdRes)
  103. {
  104. return (double)((rtdRes - 100.0) / 0.385);
  105. }
  106. // #include "math.h"
  107. #include "ALGO_AlgorithmBase_ATY.h"
  108. double ALGO_Temp_RTD_Res_Above(double rtdRes)
  109. {
  110. return (double)((-(3.9083e-3)
  111. + ALGO_Sqrt_NewtonNumber(((3.9083e-3) * (3.9083e-3))
  112. // + sqrt(((3.9083e-3) * (3.9083e-3))
  113. - 4 * (-5.775e-7) * (1 - (rtdRes / 100.0))))
  114. / (2 * (-5.775e-7)));
  115. }
  116. double ALGO_Temp_RTD_Res_Below(double rtdRes)
  117. {
  118. return (double)(-242.02
  119. + 2.2228 * rtdRes
  120. + (2.5859e-3) * rtdRes * rtdRes
  121. - (4.826e-6) * rtdRes * rtdRes * rtdRes
  122. - (2.8183e-8) * rtdRes * rtdRes * rtdRes * rtdRes
  123. + (1.5243e-10) * rtdRes * rtdRes * rtdRes * rtdRes * rtdRes);
  124. }
  125. // PT1000
  126. // R(t)=R0(1+At+Bt2)
  127. // A=0.0038623139728
  128. // B=-0.00000065314932626
  129. #include "math.h"
  130. #define A 3.9083e-3
  131. #define B -5.775e-7
  132. #define C -4.183e-12
  133. //#define A2 3.9083e-2
  134. //#define B2 -5.775e-6
  135. //#define C2 -4.183e-11
  136. double ALGO_Temp_RTD_T_PT1000(double T)
  137. {
  138. if(T >= -200 && T < 0)
  139. {
  140. return 100 * (1 + A * T + B * T * T + C * (T - 100) * T * T * T);
  141. }
  142. else if(T >= 0 && T <= 850)
  143. {
  144. return 100 * (1 + A * T + B * T * T);
  145. }
  146. return 0;
  147. }
  148. /**
  149. * @brief ???????
  150. * @param[in] resist ??
  151. * @param[out] temp ???
  152. * @retval ????
  153. * @note ????????,????????????,?1?3??????????????:
  154. * 1. ???????????????:
  155. * t1 = (Rt / R0 - 1) / A
  156. *
  157. * ??t1???:
  158. * 0??????:Rt1 = R0 * (1 + A * t1 + B * t1 * t1);
  159. * 0??????:Rt1 = R0 * [1 + A * t1 + B * t1 * t1 + C * (t1 - 100) * t1 * t1 * t1];
  160. *
  161. * ?? |Rt1 - Rt| < 0.001,t1 ???????,???????????:
  162. *
  163. * 2. ???????????:
  164. * ?? Rt = R0
  165. * t1' = 1 / [R0 * (A + 2 * B * t1)]
  166. * t1'' =-2 * B * R0 * t1' * t1' * t1'
  167. * ?? Rt < R0
  168. * t1' = 1 / [R0 * (A + 2 * B * t1 - 300 * C * t1 * t1 + 4 * C * t1 * t1 * t1)]
  169. * t1''=- R0 * (2 * B - 600 * C * t1 + 12 * C * t1 * t1) * t1' * t1' * t1'
  170. *
  171. * 3. ?? Rt,t1,Rt1 ?????? t2:
  172. * t2 = t1 + t1' * (Rt - Rt1) + 0.5 * t1'' * (Rt - Rt1) * (Rt - Rt1),???? t2 ????? Rt2?
  173. *
  174. * 4. ?? |Rt2 - Rt| < 0.001,t2 ???????,??????????? t2 ??????,???????????
  175. */
  176. double ALGO_Temp_RTD_Res_PT100(double resist)
  177. {
  178. double fT, fT0;
  179. short i;
  180. /* 1. use a linear formula to get a rough temperature first */
  181. fT0 = (resist / 100 - 1) / A;
  182. /* -200C ~ 0C */
  183. if(resist >= 18.52 && resist < 100)
  184. {
  185. for(i = 0; i < 50; i++)
  186. {
  187. fT = fT0 + (resist - 100 * (1 + A * fT0 + B * fT0 * fT0 - 100 * C * fT0 * fT0 * fT0 + C * fT0 * fT0 * fT0 * fT0)) /
  188. (100 * (A + 2 * B * fT0 - 300 * C * fT0 * fT0 + 4 * C * fT0 * fT0 * fT0));
  189. if(fabs(fT - fT0) < 0.001) /* If | Rt1-Rt | < 0.001, t1 is the desired temperature */
  190. {
  191. return fT;
  192. }
  193. else
  194. {
  195. fT0 = fT;
  196. }
  197. }
  198. }
  199. /* 0C ~ 850C */
  200. else if(resist >= 100 && resist <= 390.481)
  201. {
  202. for(i = 0; i < 50; i++)
  203. {
  204. fT = fT0 + (resist - 100 * (1 + A * fT0 + B * fT0 * fT0)) / (100 * (A + 2 * B * fT0));
  205. if(fabs(fT - fT0) < 0.001) /* If | Rt1-Rt | < 0.001, t1 is the desired temperature */
  206. {
  207. return fT;
  208. }
  209. else
  210. {
  211. fT0 = fT;
  212. }
  213. }
  214. }
  215. return 0;
  216. }
  217. double ALGO_Temp_RTD_Res_PT1000(double resist)
  218. {
  219. return ALGO_Temp_RTD_Res_PT100(resist / 10.0);
  220. }
  221. /**
  222. * @brief
  223. *
  224. * @param type
  225. * @param Temp in Degrees Celsius
  226. * @return double in mV
  227. * @note https://srdata.nist.gov/
  228. */
  229. double ALGO_Temp_TC_TempToVol(uint8_t type, double Temp)
  230. {
  231. if(type == 'T'){
  232. if(Temp == 0)
  233. return 0;
  234. else if(Temp > 0){
  235. return (0
  236. + ((0.387481063640e-1) * Temp)
  237. + ((0.332922278800e-4) * Temp * Temp)
  238. + ((0.206182434040e-6) * Temp * Temp * Temp)
  239. + ((-0.218822568460e-8) * Temp * Temp * Temp * Temp)
  240. + ((0.109968809280e-10) * Temp * Temp * Temp * Temp * Temp)
  241. + ((-0.308157587720e-13) * Temp * Temp * Temp * Temp * Temp * Temp)
  242. + ((0.454791352900e-16) * Temp * Temp * Temp * Temp * Temp * Temp * Temp)
  243. + ((-0.275129016730e-19) * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp));
  244. }
  245. else if(Temp < 0){
  246. return (0
  247. + ((0.387481063640e-01) * Temp)
  248. + ((0.441944343470e-04) * Temp * Temp)
  249. + ((0.118443231050e-06) * Temp * Temp * Temp)
  250. + ((0.200329735540e-07) * Temp * Temp * Temp * Temp)
  251. + ((0.901380195590e-09) * Temp * Temp * Temp * Temp * Temp)
  252. + ((0.226511565930e-10) * Temp * Temp * Temp * Temp * Temp * Temp)
  253. + ((0.360711542050e-12) * Temp * Temp * Temp * Temp * Temp * Temp * Temp)
  254. + ((0.384939398830e-14) * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp)
  255. + ((0.282135219250e-16) * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp)
  256. + ((0.142515947790e-18) * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp)
  257. + ((0.487686622860e-21) * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp)
  258. + ((0.107955392700e-23) * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp)
  259. + ((0.139450270620e-26) * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp)
  260. + ((0.797951539270e-30) * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp * Temp));
  261. }
  262. }
  263. return 0;
  264. }
  265. /**
  266. * @brief
  267. *
  268. * @param type
  269. * @param voltage in mV
  270. * @return double in Degrees Celsius
  271. * @note https://srdata.nist.gov/
  272. */
  273. double ALGO_Temp_TC_VolToTemp(uint8_t type, double voltage)
  274. {
  275. if(type == 'T'){
  276. if(voltage == 0)
  277. return 0;
  278. else if(voltage > 0){
  279. return (0
  280. + ((2.592800e1) * voltage)
  281. + ((-7.602961e-1) * voltage * voltage)
  282. + ((4.637791e-2) * voltage * voltage * voltage)
  283. + ((-2.165394e-3) * voltage * voltage * voltage * voltage)
  284. + ((6.048144e-5) * voltage * voltage * voltage * voltage * voltage)
  285. + ((-7.293422e-7) * voltage * voltage * voltage * voltage * voltage * voltage));
  286. }
  287. else if(voltage < 0){
  288. return (0
  289. + ((2.5949192e1) * voltage)
  290. + ((-2.1316967e-1) * voltage * voltage)
  291. + ((7.9018692e-1) * voltage * voltage * voltage)
  292. + ((4.2527777e-1) * voltage * voltage * voltage * voltage)
  293. + ((1.3304473e-1) * voltage * voltage * voltage * voltage * voltage)
  294. + ((2.0241446e-2) * voltage * voltage * voltage * voltage * voltage * voltage)
  295. + ((1.2668171e-3) * voltage * voltage * voltage * voltage * voltage * voltage * voltage));
  296. }
  297. }
  298. return 0;
  299. }
  300. // resultTemp = ALGO_ResToKelvinTemp(ALGO_VoltageToResDown(resultTemp, vref_t, 10), 1, 3200);
  301. // T in C, R in R
  302. /**
  303. * @brief
  304. *
  305. * @param R in R, or v to Thermocouple, just follow your tableR
  306. * @param tableT
  307. * @param tableR
  308. * @param tableSize T/R table must be the same size
  309. * @return double
  310. */
  311. double ALGO_RT_Table_R2T(double R, const double* tableT, const double* tableR, uint16_t tableSize)
  312. {
  313. // negative temperature coefficient, like ntc
  314. if(tableR[0] > tableR[1]){
  315. // check border
  316. if(R < tableR[tableSize - 1] || R > tableR[0]) {
  317. return -273.15;
  318. }
  319. // cycle
  320. for(uint16_t i = 0; i < tableSize - 1; i++) {
  321. if(R == tableR[i]){
  322. return tableT[i];
  323. }
  324. if(R <= tableR[i] && R >= tableR[i + 1]) {
  325. double T1 = tableT[i];
  326. double T2 = tableT[i + 1];
  327. double R1 = tableR[i];
  328. double R2 = tableR[i + 1];
  329. return T1 + (R - R1) * (T2 - T1) / (R2 - R1);
  330. }
  331. }
  332. }
  333. // positive temperature coefficient, like rtd
  334. else{
  335. // check border
  336. if(R > tableR[tableSize - 1] || R < tableR[0]) {
  337. return -273.15;
  338. }
  339. // cycle
  340. for(uint16_t i = 0; i < tableSize - 1; i++) {
  341. if(R == tableR[i]){
  342. return tableT[i];
  343. }
  344. if(R >= tableR[i] && R <= tableR[i + 1]) {
  345. double T1 = tableT[i];
  346. double T2 = tableT[i + 1];
  347. double R1 = tableR[i];
  348. double R2 = tableR[i + 1];
  349. return T1 + (R - R1) * (T2 - T1) / (R2 - R1);
  350. }
  351. }
  352. }
  353. return -273.15;
  354. }
  355. /**
  356. * @brief
  357. *
  358. * @param T in C, just follow your tableT
  359. * @param tableT
  360. * @param tableR
  361. * @param tableSize T/R table must be the same size
  362. * @return double
  363. */
  364. double ALGO_RT_Table_T2R(double T, const double* tableT, const double* tableR, uint16_t tableSize)
  365. {
  366. // check border
  367. if(T > tableT[tableSize - 1] ||
  368. T < tableT[0]) {
  369. return -273.15;
  370. }
  371. // cycle
  372. for(uint16_t i = 0; i < tableSize - 1; i++) {
  373. if(T == tableR[i]){
  374. return tableT[i];
  375. }
  376. if(T <= tableR[i] && T >= tableR[i + 1]) {
  377. double T1 = tableT[i];
  378. double T2 = tableT[i + 1];
  379. double R1 = tableR[i];
  380. double R2 = tableR[i + 1];
  381. return R1 + (T - T1) * (R2 - R1) / (T2 - T1);
  382. }
  383. }
  384. return -273.15;
  385. }
  386. #endif /* __ALGO_Temperature_ATY_C */
  387. /******************************** End Of File *********************************/