🐛 Fix MAX31865 PT1000 normalization (#24407)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
parent
dbdb39f60f
commit
1690f49656
|
@ -133,13 +133,13 @@ SPISettings MAX31865::spiConfig = SPISettings(
|
||||||
/**
|
/**
|
||||||
* Initialize the SPI interface and set the number of RTD wires used
|
* Initialize the SPI interface and set the number of RTD wires used
|
||||||
*
|
*
|
||||||
* @param wires The number of wires in enum format. Can be MAX31865_2WIRE, MAX31865_3WIRE, or MAX31865_4WIRE.
|
* @param wires The number of wires as an enum: MAX31865_2WIRE, MAX31865_3WIRE, or MAX31865_4WIRE.
|
||||||
* @param zero The resistance of the RTD at 0 degC, in ohms.
|
* @param zero_res The resistance of the RTD at 0°C, in ohms.
|
||||||
* @param ref The resistance of the reference resistor, in ohms.
|
* @param ref_res The resistance of the reference resistor, in ohms.
|
||||||
* @param wire The resistance of the wire connecting the sensor to the RTD, in ohms.
|
* @param wire_res The resistance of the wire connecting the sensor to the RTD, in ohms.
|
||||||
*/
|
*/
|
||||||
void MAX31865::begin(max31865_numwires_t wires, float zero_res, float ref_res, float wire_res) {
|
void MAX31865::begin(max31865_numwires_t wires, const_float_t zero_res, const_float_t ref_res, const_float_t wire_res) {
|
||||||
zeroRes = zero_res;
|
resNormalizer = 100.0f / zero_res; // reciprocal of resistance, scaled by 100
|
||||||
refRes = ref_res;
|
refRes = ref_res;
|
||||||
wireRes = wire_res;
|
wireRes = wire_res;
|
||||||
|
|
||||||
|
@ -437,42 +437,61 @@ float MAX31865::temperature() {
|
||||||
*
|
*
|
||||||
* @return Temperature in C
|
* @return Temperature in C
|
||||||
*/
|
*/
|
||||||
float MAX31865::temperature(uint16_t adc_val) {
|
float MAX31865::temperature(const uint16_t adc_val) {
|
||||||
return temperature(((adc_val) * RECIPROCAL(32768.0f)) * refRes - wireRes);
|
return temperature(((adc_val) * RECIPROCAL(32768.0f)) * refRes - wireRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the temperature in C from the RTD resistance.
|
* Calculate the temperature in C from the RTD resistance.
|
||||||
* Uses the technique outlined in this PDF:
|
|
||||||
* http://www.analog.com/media/en/technical-documentation/application-notes/AN709_0.pdf
|
|
||||||
*
|
*
|
||||||
* @param rtd_res the resistance value in ohms
|
* @param rtd_res the resistance value in ohms
|
||||||
* @return the temperature in degC
|
* @return the temperature in °C
|
||||||
*/
|
*/
|
||||||
float MAX31865::temperature(float rtd_res) {
|
float MAX31865::temperature(float rtd_res) {
|
||||||
|
|
||||||
|
rtd_res *= resNormalizer; // normalize to 100 ohm
|
||||||
|
|
||||||
|
// Constants for calculating temperature from the measured RTD resistance.
|
||||||
|
// http://www.analog.com/media/en/technical-documentation/application-notes/AN709_0.pdf
|
||||||
|
constexpr float RTD_Z1 = -0.0039083,
|
||||||
|
RTD_Z2 = +1.758480889e-5,
|
||||||
|
RTD_Z3 = -2.31e-8,
|
||||||
|
RTD_Z4 = -1.155e-6;
|
||||||
|
|
||||||
|
// Callender-Van Dusen equation
|
||||||
float temp = (RTD_Z1 + sqrt(RTD_Z2 + (RTD_Z3 * rtd_res))) * RECIPROCAL(RTD_Z4);
|
float temp = (RTD_Z1 + sqrt(RTD_Z2 + (RTD_Z3 * rtd_res))) * RECIPROCAL(RTD_Z4);
|
||||||
|
|
||||||
// From the PDF...
|
|
||||||
//
|
//
|
||||||
// The previous equation is valid only for temperatures of 0°C and above.
|
// The previous equation is valid only for temperatures of 0°C and above.
|
||||||
// The equation for RRTD(t) that defines negative temperature behavior is a
|
// The equation for RRTD(t) that defines negative temperature behavior is a
|
||||||
// fourth-order polynomial (after expanding the third term) and is quite
|
// fourth-order polynomial (after expanding the third term) and is quite
|
||||||
// impractical to solve for a single expression of temperature as a function
|
// impractical to solve for a single expression of temperature as a function
|
||||||
// of resistance.
|
// of resistance. So here we use a Linear Approximation instead.
|
||||||
//
|
//
|
||||||
if (temp < 0) {
|
if (temp < 0) {
|
||||||
rtd_res = (rtd_res / zeroRes) * 100; // normalize to 100 ohm
|
#ifndef MAX31865_APPROX
|
||||||
float rpoly = rtd_res;
|
#define MAX31865_APPROX 5
|
||||||
|
#endif
|
||||||
|
|
||||||
temp = -242.02 + (2.2228 * rpoly);
|
constexpr float RTD_C[] = {
|
||||||
rpoly *= rtd_res; // square
|
#if MAX31865_APPROX == 5
|
||||||
temp += 2.5859e-3 * rpoly;
|
-242.02, +2.2228, +2.5859e-3, -4.8260e-6, -2.8183e-8, +1.5243e-10
|
||||||
rpoly *= rtd_res; // ^3
|
#elif MAX31865_APPROX == 4
|
||||||
temp -= 4.8260e-6 * rpoly;
|
-241.96, +2.2163, +2.8541e-3, -9.9121e-6, -1.7152e-8
|
||||||
rpoly *= rtd_res; // ^4
|
#elif MAX31865_APPROX == 3
|
||||||
temp -= 2.8183e-8 * rpoly;
|
-242.09, +2.2276, +2.5178e-3, -5.8620e-6
|
||||||
rpoly *= rtd_res; // ^5
|
#else
|
||||||
temp += 1.5243e-10 * rpoly;
|
-242.97, +2.2838, +1.4727e-3
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
float rpoly = rtd_res;
|
||||||
|
temp = RTD_C[0];
|
||||||
|
temp += rpoly * RTD_C[1];
|
||||||
|
rpoly *= rtd_res; temp += rpoly * RTD_C[2];
|
||||||
|
if (MAX31865_APPROX >= 3) rpoly *= rtd_res; temp += rpoly * RTD_C[3];
|
||||||
|
if (MAX31865_APPROX >= 4) rpoly *= rtd_res; temp += rpoly * RTD_C[4];
|
||||||
|
if (MAX31865_APPROX >= 5) rpoly *= rtd_res; temp += rpoly * RTD_C[5];
|
||||||
}
|
}
|
||||||
|
|
||||||
return temp;
|
return temp;
|
||||||
|
|
|
@ -73,13 +73,6 @@
|
||||||
#define MAX31865_FAULT_RTDINLOW 0x08 // D3
|
#define MAX31865_FAULT_RTDINLOW 0x08 // D3
|
||||||
#define MAX31865_FAULT_OVUV 0x04 // D2
|
#define MAX31865_FAULT_OVUV 0x04 // D2
|
||||||
|
|
||||||
// http://www.analog.com/media/en/technical-documentation/application-notes/AN709_0.pdf
|
|
||||||
// constants for calculating temperature from the measured RTD resistance.
|
|
||||||
#define RTD_Z1 -0.0039083
|
|
||||||
#define RTD_Z2 0.00001758480889
|
|
||||||
#define RTD_Z3 -0.0000000231
|
|
||||||
#define RTD_Z4 -0.000001155
|
|
||||||
|
|
||||||
typedef enum max31865_numwires {
|
typedef enum max31865_numwires {
|
||||||
MAX31865_2WIRE = 0,
|
MAX31865_2WIRE = 0,
|
||||||
MAX31865_3WIRE = 1,
|
MAX31865_3WIRE = 1,
|
||||||
|
@ -103,7 +96,7 @@ private:
|
||||||
|
|
||||||
uint16_t spiDelay;
|
uint16_t spiDelay;
|
||||||
|
|
||||||
float zeroRes, refRes, wireRes;
|
float resNormalizer, refRes, wireRes;
|
||||||
|
|
||||||
#if ENABLED(MAX31865_USE_READ_ERROR_DETECTION)
|
#if ENABLED(MAX31865_USE_READ_ERROR_DETECTION)
|
||||||
millis_t lastReadStamp = 0;
|
millis_t lastReadStamp = 0;
|
||||||
|
@ -160,7 +153,7 @@ public:
|
||||||
int8_t spi_clk);
|
int8_t spi_clk);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void begin(max31865_numwires_t wires, float zero_res, float ref_res, float wire_res);
|
void begin(max31865_numwires_t wires, const_float_t zero_res, const_float_t ref_res, const_float_t wire_res);
|
||||||
|
|
||||||
uint8_t readFault();
|
uint8_t readFault();
|
||||||
void clearFault();
|
void clearFault();
|
||||||
|
@ -168,6 +161,6 @@ public:
|
||||||
uint16_t readRaw();
|
uint16_t readRaw();
|
||||||
float readResistance();
|
float readResistance();
|
||||||
float temperature();
|
float temperature();
|
||||||
float temperature(uint16_t adc_val);
|
float temperature(const uint16_t adc_val);
|
||||||
float temperature(float rtd_res);
|
float temperature(float rtd_res);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue