Bläddra i källkod

🐛 Fix MAX31865 PT1000 normalization (#24407)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
John Lagonikas 2 år sedan
förälder
incheckning
31d286750c
Inget konto är kopplat till bidragsgivarens mejladress
2 ändrade filer med 45 tillägg och 33 borttagningar
  1. 42
    23
      Marlin/src/libs/MAX31865.cpp
  2. 3
    10
      Marlin/src/libs/MAX31865.h

+ 42
- 23
Marlin/src/libs/MAX31865.cpp Visa fil

@@ -133,13 +133,13 @@ SPISettings MAX31865::spiConfig = SPISettings(
133 133
 /**
134 134
  * Initialize the SPI interface and set the number of RTD wires used
135 135
  *
136
- * @param wires  The number of wires in enum format. Can be MAX31865_2WIRE, MAX31865_3WIRE, or MAX31865_4WIRE.
137
- * @param zero   The resistance of the RTD at 0 degC, in ohms.
138
- * @param ref    The resistance of the reference resistor, in ohms.
139
- * @param wire   The resistance of the wire connecting the sensor to the RTD, in ohms.
136
+ * @param wires     The number of wires as an enum: MAX31865_2WIRE, MAX31865_3WIRE, or MAX31865_4WIRE.
137
+ * @param zero_res  The resistance of the RTD at 0°C, in ohms.
138
+ * @param ref_res   The resistance of the reference resistor, in ohms.
139
+ * @param wire_res  The resistance of the wire connecting the sensor to the RTD, in ohms.
140 140
  */
141
-void MAX31865::begin(max31865_numwires_t wires, float zero_res, float ref_res, float wire_res) {
142
-  zeroRes = zero_res;
141
+void MAX31865::begin(max31865_numwires_t wires, const_float_t zero_res, const_float_t ref_res, const_float_t wire_res) {
142
+  resNormalizer = 100.0f / zero_res;  // reciprocal of resistance, scaled by 100
143 143
   refRes = ref_res;
144 144
   wireRes = wire_res;
145 145
 
@@ -437,42 +437,61 @@ float MAX31865::temperature() {
437 437
  *
438 438
  * @return  Temperature in C
439 439
  */
440
-float MAX31865::temperature(uint16_t adc_val) {
440
+float MAX31865::temperature(const uint16_t adc_val) {
441 441
   return temperature(((adc_val) * RECIPROCAL(32768.0f)) * refRes - wireRes);
442 442
 }
443 443
 
444 444
 /**
445 445
  * Calculate the temperature in C from the RTD resistance.
446
- * Uses the technique outlined in this PDF:
447
- * http://www.analog.com/media/en/technical-documentation/application-notes/AN709_0.pdf
448 446
  *
449 447
  * @param    rtd_res  the resistance value in ohms
450
- * @return            the temperature in degC
448
+ * @return            the temperature in °C
451 449
  */
452 450
 float MAX31865::temperature(float rtd_res) {
451
+
452
+  rtd_res *= resNormalizer; // normalize to 100 ohm
453
+
454
+  // Constants for calculating temperature from the measured RTD resistance.
455
+  // http://www.analog.com/media/en/technical-documentation/application-notes/AN709_0.pdf
456
+  constexpr float RTD_Z1 = -0.0039083,
457
+                  RTD_Z2 = +1.758480889e-5,
458
+                  RTD_Z3 = -2.31e-8,
459
+                  RTD_Z4 = -1.155e-6;
460
+
461
+  // Callender-Van Dusen equation
453 462
   float temp = (RTD_Z1 + sqrt(RTD_Z2 + (RTD_Z3 * rtd_res))) * RECIPROCAL(RTD_Z4);
454 463
 
455
-  // From the PDF...
456 464
   //
457 465
   // The previous equation is valid only for temperatures of 0°C and above.
458 466
   // The equation for RRTD(t) that defines negative temperature behavior is a
459 467
   // fourth-order polynomial (after expanding the third term) and is quite
460 468
   // impractical to solve for a single expression of temperature as a function
461
-  // of resistance.
469
+  // of resistance. So here we use a Linear Approximation instead.
462 470
   //
463 471
   if (temp < 0) {
464
-    rtd_res = (rtd_res / zeroRes) * 100; // normalize to 100 ohm
465
-    float rpoly = rtd_res;
472
+    #ifndef MAX31865_APPROX
473
+      #define MAX31865_APPROX 5
474
+    #endif
475
+
476
+    constexpr float RTD_C[] = {
477
+      #if MAX31865_APPROX == 5
478
+        -242.02, +2.2228, +2.5859e-3, -4.8260e-6, -2.8183e-8, +1.5243e-10
479
+      #elif MAX31865_APPROX == 4
480
+        -241.96, +2.2163, +2.8541e-3, -9.9121e-6, -1.7152e-8
481
+      #elif MAX31865_APPROX == 3
482
+        -242.09, +2.2276, +2.5178e-3, -5.8620e-6
483
+      #else
484
+        -242.97, +2.2838, +1.4727e-3
485
+      #endif
486
+    };
466 487
 
467
-    temp = -242.02 + (2.2228 * rpoly);
468
-    rpoly *= rtd_res; // square
469
-    temp += 2.5859e-3 * rpoly;
470
-    rpoly *= rtd_res; // ^3
471
-    temp -= 4.8260e-6 * rpoly;
472
-    rpoly *= rtd_res; // ^4
473
-    temp -= 2.8183e-8 * rpoly;
474
-    rpoly *= rtd_res; // ^5
475
-    temp += 1.5243e-10 * rpoly;
488
+    float rpoly = rtd_res;
489
+    temp = RTD_C[0];
490
+    temp += rpoly * RTD_C[1];
491
+    rpoly *= rtd_res; temp += rpoly * RTD_C[2];
492
+    if (MAX31865_APPROX >= 3) rpoly *= rtd_res; temp += rpoly * RTD_C[3];
493
+    if (MAX31865_APPROX >= 4) rpoly *= rtd_res; temp += rpoly * RTD_C[4];
494
+    if (MAX31865_APPROX >= 5) rpoly *= rtd_res; temp += rpoly * RTD_C[5];
476 495
   }
477 496
 
478 497
   return temp;

+ 3
- 10
Marlin/src/libs/MAX31865.h Visa fil

@@ -73,13 +73,6 @@
73 73
 #define MAX31865_FAULT_RTDINLOW 0x08    // D3
74 74
 #define MAX31865_FAULT_OVUV 0x04        // D2
75 75
 
76
-// http://www.analog.com/media/en/technical-documentation/application-notes/AN709_0.pdf
77
-// constants for calculating temperature from the measured RTD resistance.
78
-#define RTD_Z1 -0.0039083
79
-#define RTD_Z2 0.00001758480889
80
-#define RTD_Z3 -0.0000000231
81
-#define RTD_Z4 -0.000001155
82
-
83 76
 typedef enum max31865_numwires {
84 77
   MAX31865_2WIRE = 0,
85 78
   MAX31865_3WIRE = 1,
@@ -103,7 +96,7 @@ private:
103 96
 
104 97
   uint16_t spiDelay;
105 98
 
106
-  float zeroRes, refRes, wireRes;
99
+  float resNormalizer, refRes, wireRes;
107 100
 
108 101
   #if ENABLED(MAX31865_USE_READ_ERROR_DETECTION)
109 102
     millis_t lastReadStamp = 0;
@@ -160,7 +153,7 @@ public:
160 153
              int8_t spi_clk);
161 154
   #endif
162 155
 
163
-  void begin(max31865_numwires_t wires, float zero_res, float ref_res, float wire_res);
156
+  void begin(max31865_numwires_t wires, const_float_t zero_res, const_float_t ref_res, const_float_t wire_res);
164 157
 
165 158
   uint8_t readFault();
166 159
   void clearFault();
@@ -168,6 +161,6 @@ public:
168 161
   uint16_t readRaw();
169 162
   float readResistance();
170 163
   float temperature();
171
-  float temperature(uint16_t adc_val);
164
+  float temperature(const uint16_t adc_val);
172 165
   float temperature(float rtd_res);
173 166
 };

Laddar…
Avbryt
Spara