polarimeter_software/User/driver/pt_res/pt100x.c

112 lines
3.1 KiB
C
Raw Permalink Normal View History

2025-09-30 02:37:23 +00:00
/*
* @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 <math.h>
/*
* 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;
}