/* * @Date: 2025-07-04 13:05:24 * @Author: mypx * @LastEditors: mypx mypx_coder@163.com * @LastEditTime: 2025-07-10 13:28:55 * @FilePath: pt100x.c * @Description: * Copyright (c) 2025 by mypx, All Rights Reserved. */ #include "pt100x.h" #include /* * Low temperature region (T < 0°C): * R(T) = R0(1 + A*T + B*T^2 + C*(T - R0)T^3) * High temperature region (T >= 0°C): * R(T) = R0(1 + A*T + B*T^2) */ #define A 3.9083e-3 #define B -5.775e-7 #define C -4.183e-12 #define PT100_R0 100 #define PT1000_R0 1000 /** * @brief Calculate the temperature based on the resistance value of a PT100 * platinum resistor (precise calculation). * @param resistance Measured resistance value (Ω). * @param ptType Type of the PT sensor (PT100 or PT1000). * @return Temperature value (°C), returns NaN if the resistance value is invalid. */ double pt_precise_temperature(double resistance, PtType ptType) { double R0 = (ptType == PT100) ? PT100_R0 : PT1000_R0; if (resistance < R0) { // Build the cubic equation: a*T³ + b*T² + c*T + d = 0 double a = C * R0; double b = B - 100 * C; double c = A; double d = 1 - resistance / R0; // Use Newton's iteration method to solve the equation double T = 0.0; // Initial guess value int max_iterations = 100; double tolerance = 1e-6; for (int i = 0; i < max_iterations; i++) { // Calculate the polynomial value and its derivative double f = a * T * T * T + b * T * T + c * T + d; double df = 3 * a * T * T + 2 * b * T + c; // Check if the derivative is close to zero if (fabs(df) < tolerance) break; // Iterative update double delta = f / df; T -= delta; // Check convergence if (fabs(delta) < tolerance) break; } return T; } else { // High temperature region (T ≥ 0°C): Solve the quadratic equation // Quadratic equation: B*T² + A*T + (1 - R/R0) = 0 double discriminant = A * A - 4 * B * (1 - resistance / R0); if (discriminant < 0) { return NAN; } // Take the positive root return (-A + sqrt(discriminant)) / (2 * B); } } /** * @brief Calculate the temperature based on the resistance value of a PT100 platinum resistor * (engineering approximation). * @param resistance Measured resistance value (Ω). * @param type Type of the PT sensor (PT100 or PT1000). * @return Temperature value (°C). */ double pt_approximate_temperature(double resistance, PtType type) { double R0 = (type == PT100) ? PT100_R0 : PT1000_R0; return (resistance / R0 - 1) / 0.00385; } float pt_temperature_to_resistance(double t, PtType type) { float resistance; float r0 = (type == PT100) ? PT100_R0 : PT1000_R0; if (t >= 0.0f) { resistance = r0 * (1 + A * t + B * t * t); } else { resistance = r0 * (1 + A * t + B * t * t + C * (t - r0) * t * t * t); } return resistance; }