Browse Source

🐛 Fix and improve MAX31865 (#23215)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
John Lagonikas 2 years ago
parent
commit
9e6ded3cdf
No account linked to committer's email address

+ 9
- 0
Marlin/Configuration_adv.h View File

@@ -142,11 +142,20 @@
142 142
  *   FORCE_HW_SPI:   Ignore SCK/MOSI/MISO pins and just use the CS pin & default SPI bus.
143 143
  *   MAX31865_WIRES: Set the number of wires for the probe connected to a MAX31865 board, 2-4. Default: 2
144 144
  *   MAX31865_50HZ:  Enable 50Hz filter instead of the default 60Hz.
145
+ *   MAX31865_USE_READ_ERROR_DETECTION: Detects random read errors from value spikes (a 20°C difference in less than 1sec)
146
+ *   MAX31865_USE_AUTO_MODE: Faster and more frequent reads than 1-shot, but bias voltage always on, slightly affecting RTD temperature.
147
+ *   MAX31865_MIN_SAMPLING_TIME_MSEC: in 1-shot mode, the minimum time between subsequent reads. This reduces the effect of bias voltage by leaving the sensor unpowered for longer intervals.
148
+ *   MAX31865_WIRE_OHMS: In 2-wire configurations, manually set the wire resistance for more accurate readings
145 149
  */
146 150
 //#define TEMP_SENSOR_FORCE_HW_SPI
147 151
 //#define MAX31865_SENSOR_WIRES_0 2
148 152
 //#define MAX31865_SENSOR_WIRES_1 2
149 153
 //#define MAX31865_50HZ_FILTER
154
+//#define MAX31865_USE_READ_ERROR_DETECTION
155
+//#define MAX31865_USE_AUTO_MODE
156
+//#define MAX31865_MIN_SAMPLING_TIME_MSEC 100
157
+//#define MAX31865_WIRE_OHMS_0 0.0f
158
+//#define MAX31865_WIRE_OHMS_1 0.0f
150 159
 
151 160
 /**
152 161
  * Hephestos 2 24V heated bed upgrade kit.

+ 6
- 0
Marlin/src/inc/Conditionals_adv.h View File

@@ -159,6 +159,9 @@
159 159
     #ifndef MAX31865_SENSOR_WIRES_0
160 160
       #define MAX31865_SENSOR_WIRES_0 2
161 161
     #endif
162
+    #ifndef MAX31865_WIRE_OHMS_0
163
+      #define MAX31865_WIRE_OHMS_0 0.0f
164
+    #endif
162 165
   #elif TEMP_SENSOR_0 == -3
163 166
     #define TEMP_SENSOR_0_IS_MAX31855 1
164 167
     #define TEMP_SENSOR_0_MAX_TC_TMIN -270
@@ -193,6 +196,9 @@
193 196
     #ifndef MAX31865_SENSOR_WIRES_1
194 197
       #define MAX31865_SENSOR_WIRES_1 2
195 198
     #endif
199
+    #ifndef MAX31865_WIRE_OHMS_1
200
+      #define MAX31865_WIRE_OHMS_1 0.0f
201
+    #endif
196 202
   #elif TEMP_SENSOR_1 == -3
197 203
     #define TEMP_SENSOR_1_IS_MAX31855 1
198 204
     #define TEMP_SENSOR_1_MAX_TC_TMIN -270

+ 188
- 125
Marlin/src/libs/MAX31865.cpp View File

@@ -40,20 +40,23 @@
40 40
  * All rights reserved.
41 41
  */
42 42
 
43
-// Useful for RTD debugging.
44
-//#define MAX31865_DEBUG
45
-//#define MAX31865_DEBUG_SPI
46
-
47 43
 #include "../inc/MarlinConfig.h"
48 44
 
49 45
 #if HAS_MAX31865 && !USE_ADAFRUIT_MAX31865
50 46
 
51 47
 #include "MAX31865.h"
52 48
 
49
+#ifndef MAX31865_MIN_SAMPLING_TIME_MSEC
50
+  #define MAX31865_MIN_SAMPLING_TIME_MSEC 0
51
+#endif
52
+
53 53
 #ifdef TARGET_LPC1768
54 54
   #include <SoftwareSPI.h>
55 55
 #endif
56 56
 
57
+#define DEBUG_OUT ENABLED(DEBUG_MAX31865)
58
+#include "../core/debug_out.h"
59
+
57 60
 // The maximum speed the MAX31865 can do is 5 MHz
58 61
 SPISettings MAX31865::spiConfig = SPISettings(
59 62
   TERN(TARGET_LPC1768, SPI_QUARTER_SPEED, TERN(ARDUINO_ARCH_STM32, SPI_CLOCK_DIV4, 500000)),
@@ -61,7 +64,7 @@ SPISettings MAX31865::spiConfig = SPISettings(
61 64
   SPI_MODE1 // CPOL0 CPHA1
62 65
 );
63 66
 
64
-#ifndef LARGE_PINMAP
67
+#if DISABLED(LARGE_PINMAP)
65 68
 
66 69
   /**
67 70
    * Create the interface object using software (bitbang) SPI for PIN values
@@ -137,117 +140,121 @@ SPISettings MAX31865::spiConfig = SPISettings(
137 140
  * @param wires  The number of wires in enum format. Can be MAX31865_2WIRE, MAX31865_3WIRE, or MAX31865_4WIRE.
138 141
  * @param zero   The resistance of the RTD at 0 degC, in ohms.
139 142
  * @param ref    The resistance of the reference resistor, in ohms.
143
+ * @param wire   The resistance of the wire connecting the sensor to the RTD, in ohms.
140 144
  */
141
-void MAX31865::begin(max31865_numwires_t wires, float zero, float ref) {
142
-  zeroRes = zero;
143
-  refRes = ref;
145
+void MAX31865::begin(max31865_numwires_t wires, float zero_res, float ref_res, float wire_res) {
146
+  zeroRes = zero_res;
147
+  refRes = ref_res;
148
+  wireRes = wire_res;
144 149
 
145
-  OUT_WRITE(cselPin, HIGH);
150
+  pinMode(cselPin, OUTPUT);
151
+  digitalWrite(cselPin, HIGH);
146 152
 
147
-  if (sclkPin != TERN(LARGE_PINMAP, -1UL, -1)) {
153
+  if (sclkPin != TERN(LARGE_PINMAP, -1UL, 255))
148 154
     softSpiBegin(SPI_QUARTER_SPEED); // Define pin modes for Software SPI
149
-  }
150 155
   else {
151
-    #ifdef MAX31865_DEBUG
152
-      SERIAL_ECHOLNPGM("Initializing MAX31865 Hardware SPI");
153
-    #endif
156
+    DEBUG_ECHOLNPGM("Initializing MAX31865 Hardware SPI");
154 157
     SPI.begin();    // Start and configure hardware SPI
155 158
   }
156 159
 
157
-  setWires(wires);
158
-  enableBias(false);
159
-  autoConvert(false);
160
-  clearFault();
161
-
162
-  #ifdef MAX31865_DEBUG_SPI
163
-    SERIAL_ECHOLNPGM(
164
-      TERN(LARGE_PINMAP, "LARGE_PINMAP", "Regular")
165
-      " begin call with cselPin: ", cselPin,
166
-      " misoPin: ", misoPin,
167
-      " sclkPin: ", sclkPin,
168
-      " mosiPin: ", mosiPin,
169
-      " config: ", readRegister8(MAX31865_CONFIG_REG)
170
-    );
171
-  #endif
160
+  initFixedFlags(wires);
161
+
162
+  clearFault(); // also initializes flags
163
+
164
+  #if DISABLED(MAX31865_USE_AUTO_MODE) // make a proper first 1 shot read to initialize _lastRead
165
+
166
+    enableBias();
167
+    DELAY_US(11500);
168
+    oneShot();
169
+    DELAY_US(65000);
170
+    uint16_t rtd = readRegister16(MAX31865_RTDMSB_REG);
171
+
172
+    if (rtd & 1) {
173
+      lastRead = 0xFFFF; // some invalid value
174
+      lastFault = readRegister8(MAX31865_FAULTSTAT_REG);
175
+      clearFault(); // also clears the bias voltage flag, so no further action is required
176
+
177
+      DEBUG_ECHOLNPGM("MAX31865 read fault: ", rtd);
178
+    }
179
+    else {
180
+      DEBUG_ECHOLNPGM("RTD MSB:", (rtd >> 8), "  RTD LSB:", (rtd & 0x00FF));
181
+
182
+      resetFlags();
183
+
184
+      lastRead = rtd;
185
+      nextEvent = SETUP_BIAS_VOLTAGE;
186
+      millis_t now = millis();
187
+      nextEventStamp = now + MAX31865_MIN_SAMPLING_TIME_MSEC;
188
+
189
+      TERN_(MAX31865_USE_READ_ERROR_DETECTION, lastReadStamp = now);
190
+    }
191
+
192
+  #endif // !MAX31865_USE_AUTO_MODE
193
+
194
+  DEBUG_ECHOLNPGM(
195
+    TERN(LARGE_PINMAP, "LARGE_PINMAP", "Regular")
196
+    " begin call with cselPin: ", cselPin,
197
+    " misoPin: ", misoPin,
198
+    " sclkPin: ", sclkPin,
199
+    " mosiPin: ", mosiPin,
200
+    " config: ", readRegister8(MAX31865_CONFIG_REG)
201
+  );
172 202
 }
173 203
 
174 204
 /**
175
- * Read the raw 8-bit FAULTSTAT register
205
+ * Return and clear the last fault value
176 206
  *
177
- * @return The raw unsigned 8-bit FAULT status register
207
+ * @return The raw unsigned 8-bit FAULT status register or spike fault
178 208
  */
179 209
 uint8_t MAX31865::readFault() {
180
-  return readRegister8(MAX31865_FAULTSTAT_REG);
210
+  uint8_t r = lastFault;
211
+  lastFault = 0;
212
+  return r;
181 213
 }
182 214
 
183 215
 /**
184
- * Clear all faults in FAULTSTAT.
216
+ * Clear last fault
185 217
  */
186 218
 void MAX31865::clearFault() {
187 219
   setConfig(MAX31865_CONFIG_FAULTSTAT, 1);
188 220
 }
189 221
 
190 222
 /**
191
- * Whether we want to have continuous conversions (50/60 Hz)
192
- *
193
- * @param b  If true, auto conversion is enabled
194
- */
195
-void MAX31865::autoConvert(bool b) {
196
-  setConfig(MAX31865_CONFIG_MODEAUTO, b);
197
-}
198
-
199
-/**
200
- * Whether we want filter out 50Hz noise or 60Hz noise
201
- *
202
- * @param b  If true, 50Hz noise is filtered, else 60Hz(default)
223
+ * Reset flags
203 224
  */
204
-void MAX31865::enable50HzFilter(bool b) {
205
-  setConfig(MAX31865_CONFIG_FILT50HZ, b);
225
+void MAX31865::resetFlags() {
226
+  writeRegister8(MAX31865_CONFIG_REG, stdFlags);
206 227
 }
207 228
 
208 229
 /**
209 230
  * Enable the bias voltage on the RTD sensor
210
- *
211
- * @param b  If true bias is enabled, else disabled
212 231
  */
213
-void MAX31865::enableBias(bool b) {
214
-  setConfig(MAX31865_CONFIG_BIAS, b);
215
-
216
-  // From the datasheet:
217
-  // Note that if VBIAS is off (to reduce supply current between conversions), any filter
218
-  // capacitors at the RTDIN inputs need to charge before an accurate conversion can be
219
-  // performed. Therefore, enable VBIAS and wait at least 10.5 time constants of the input
220
-  // RC network plus an additional 1ms before initiating the conversion.
221
-  if (b)
222
-    DELAY_US(11500); //11.5ms
232
+void MAX31865::enableBias() {
233
+  setConfig(MAX31865_CONFIG_BIAS, 1);
223 234
 }
224 235
 
225 236
 /**
226 237
  * Start a one-shot temperature reading.
227 238
  */
228 239
 void MAX31865::oneShot() {
229
-  setConfig(MAX31865_CONFIG_1SHOT, 1);
230
-
231
-  // From the datasheet:
232
-  // Note that a single conversion requires approximately 52ms in 60Hz filter
233
-  // mode or 62.5ms in 50Hz filter mode to complete. 1-Shot is a self-clearing bit.
234
-  // TODO: switch this out depending on the filter mode.
235
-  DELAY_US(65000); // 65ms
240
+  setConfig(MAX31865_CONFIG_1SHOT | MAX31865_CONFIG_BIAS, 1);
236 241
 }
237 242
 
238 243
 /**
239
- * How many wires we have in our RTD setup, can be MAX31865_2WIRE,
240
- * MAX31865_3WIRE, or MAX31865_4WIRE
244
+ * Initialize standard flags with flags that will not change during operation (Hz, polling mode and no. of wires)
241 245
  *
242 246
  * @param wires The number of wires in enum format
243 247
  */
244
-void MAX31865::setWires(max31865_numwires_t wires) {
245
-  uint8_t t = readRegister8(MAX31865_CONFIG_REG);
248
+void MAX31865::initFixedFlags(max31865_numwires_t wires) {
249
+
250
+  // set config-defined flags (same for all sensors)
251
+  stdFlags = TERN(MAX31865_50HZ_FILTER, MAX31865_CONFIG_FILT50HZ, MAX31865_CONFIG_FILT60HZ) |
252
+              TERN(MAX31865_USE_AUTO_MODE, MAX31865_CONFIG_MODEAUTO | MAX31865_CONFIG_BIAS, MAX31865_CONFIG_MODEOFF);
253
+
246 254
   if (wires == MAX31865_3WIRE)
247
-    t |= MAX31865_CONFIG_3WIRE;
248
-  else // 2 or 4 wire
249
-    t &= ~MAX31865_CONFIG_3WIRE;
250
-  writeRegister8(MAX31865_CONFIG_REG, t);
255
+    stdFlags |= MAX31865_CONFIG_3WIRE;
256
+  else  // 2 or 4 wire
257
+    stdFlags &= ~MAX31865_CONFIG_3WIRE;
251 258
 }
252 259
 
253 260
 /**
@@ -257,33 +264,96 @@ void MAX31865::setWires(max31865_numwires_t wires) {
257 264
  * @return The raw unsigned 16-bit register value with ERROR bit attached, NOT temperature!
258 265
  */
259 266
 uint16_t MAX31865::readRaw() {
260
-  clearFault();
261
-  enableBias(true);
262 267
 
263
-  oneShot();
264
-  uint16_t rtd = readRegister16(MAX31865_RTDMSB_REG);
268
+  #if ENABLED(MAX31865_USE_AUTO_MODE)
265 269
 
266
-  #ifdef MAX31865_DEBUG
267
-    SERIAL_ECHOLNPGM("RTD MSB:", (rtd >> 8), "  RTD LSB:", (rtd & 0x00FF));
268
-  #endif
270
+    const uint16_t rtd = readRegister16(MAX31865_RTDMSB_REG);
271
+    DEBUG_ECHOLNPGM("MAX31865 RTD MSB:", (rtd >> 8), " LSB:", (rtd & 0x00FF));
272
+
273
+    if (rtd & 1) {
274
+      lastFault = readRegister8(MAX31865_FAULTSTAT_REG);
275
+      lastRead |= 1;
276
+      clearFault(); // also clears the bias voltage flag, so no further action is required
277
+      DEBUG_ECHOLNPGM("MAX31865 read fault: ", rtd);
278
+    }
279
+    #if ENABLED(MAX31865_USE_READ_ERROR_DETECTION)
280
+      else if (ABS(lastRead - rtd) > 500 && PENDING(millis(), lastReadStamp + 1000)) { // if two readings within a second differ too much (~20°C), consider it a read error.
281
+        lastFault = 0x01;
282
+        lastRead |= 1;
283
+        DEBUG_ECHOLNPGM("MAX31865 read error: ", rtd);
284
+      }
285
+    #endif
286
+    else {
287
+      lastRead = rtd;
288
+      TERN_(MAX31865_USE_READ_ERROR_DETECTION, lastReadStamp = millis());
289
+    }
269 290
 
270
-  // Disable the bias to lower power dissipation between reads.
271
-  // If the ref resistor heats up, the temperature reading will be skewed.
272
-  enableBias(false);
291
+  #else
292
+
293
+    if (PENDING(millis(), nextEventStamp)) {
294
+      DEBUG_ECHOLNPGM("MAX31865 waiting for event ", nextEvent);
295
+      return lastRead;
296
+    }
297
+
298
+    switch (nextEvent) {
299
+      case SETUP_BIAS_VOLTAGE:
300
+        enableBias();
301
+        nextEventStamp = millis() + 11; // wait at least 11msec before enabling 1shot
302
+        nextEvent = SETUP_1_SHOT_MODE;
303
+        DEBUG_ECHOLN("MAX31865 bias voltage enabled");
304
+        break;
305
+
306
+      case SETUP_1_SHOT_MODE:
307
+        oneShot();
308
+        nextEventStamp = millis() + 65; // wait at least 65msec before reading RTD register
309
+        nextEvent = READ_RTD_REG;
310
+        DEBUG_ECHOLN("MAX31865 1 shot mode enabled");
311
+        break;
312
+
313
+      case READ_RTD_REG: {
314
+        const uint16_t rtd = readRegister16(MAX31865_RTDMSB_REG);
315
+        DEBUG_ECHOLNPGM("MAX31865 RTD MSB:", (rtd >> 8), " LSB:", (rtd & 0x00FF));
316
+
317
+        if (rtd & 1) {
318
+          lastFault = readRegister8(MAX31865_FAULTSTAT_REG);
319
+          lastRead |= 1;
320
+          clearFault(); // also clears the bias voltage flag, so no further action is required
321
+          DEBUG_ECHOLNPGM("MAX31865 read fault: ", rtd);
322
+        }
323
+        #if ENABLED(MAX31865_USE_READ_ERROR_DETECTION)
324
+          else if (ABS(lastRead - rtd) > 500 && PENDING(millis(), lastReadStamp + 1000)) { // if two readings within a second differ too much (~20°C), consider it a read error.
325
+            lastFault = 0x01;
326
+            lastRead |= 1;
327
+            DEBUG_ECHOLNPGM("MAX31865 read error: ", rtd);
328
+          }
329
+        #endif
330
+        else {
331
+          lastRead = rtd;
332
+          TERN_(MAX31865_USE_READ_ERROR_DETECTION, lastReadStamp = millis());
333
+        }
334
+
335
+        if (!(rtd & 1))   // if clearFault() was not invoked, need to clear the bias voltage and 1-shot flags
336
+          resetFlags();
337
+
338
+        nextEvent = SETUP_BIAS_VOLTAGE;
339
+        nextEventStamp = millis() + MAX31865_MIN_SAMPLING_TIME_MSEC; // next step should not occur within less than MAX31865_MIN_SAMPLING_TIME_MSEC from the last one
340
+      } break;
341
+    }
342
+
343
+  #endif
273 344
 
274
-  return rtd;
345
+  return lastRead;
275 346
 }
276 347
 
277 348
 /**
278 349
  * Calculate and return the resistance value of the connected RTD.
279 350
  *
280
- * @param  refResistor The value of the matching reference resistor, usually 430 or 4300
281 351
  * @return             The raw RTD resistance value, NOT temperature!
282 352
  */
283 353
 float MAX31865::readResistance() {
284 354
   // Strip the error bit (D0) and convert to a float ratio.
285 355
   // less precise method: (readRaw() * refRes) >> 16
286
-  return (((readRaw() >> 1) / 32768.0f) * refRes);
356
+  return ((readRaw() * RECIPROCAL(65536.0f)) * refRes - wireRes);
287 357
 }
288 358
 
289 359
 /**
@@ -301,7 +371,7 @@ float MAX31865::temperature() {
301 371
  * @return  Temperature in C
302 372
  */
303 373
 float MAX31865::temperature(uint16_t adc_val) {
304
-  return temperature(((adc_val) / 32768.0f) * refRes);
374
+  return temperature(((adc_val) * RECIPROCAL(32768.0f)) * refRes - wireRes);
305 375
 }
306 376
 
307 377
 /**
@@ -352,11 +422,8 @@ float MAX31865::temperature(float rtd_res) {
352 422
  * @param enable  whether to enable or disable the value
353 423
  */
354 424
 void MAX31865::setConfig(uint8_t config, bool enable) {
355
-  uint8_t t = readRegister8(MAX31865_CONFIG_REG);
356
-  if (enable)
357
-    t |= config;
358
-  else
359
-    t &= ~config; // disable
425
+  uint8_t t = stdFlags;
426
+  if (enable) t |= config; else t &= ~config;
360 427
   writeRegister8(MAX31865_CONFIG_REG, t);
361 428
 }
362 429
 
@@ -369,7 +436,6 @@ void MAX31865::setConfig(uint8_t config, bool enable) {
369 436
 uint8_t MAX31865::readRegister8(uint8_t addr) {
370 437
   uint8_t ret = 0;
371 438
   readRegisterN(addr, &ret, 1);
372
-
373 439
   return ret;
374 440
 }
375 441
 
@@ -380,14 +446,9 @@ uint8_t MAX31865::readRegister8(uint8_t addr) {
380 446
  * @return       both register contents as a single 16-bit int
381 447
  */
382 448
 uint16_t MAX31865::readRegister16(uint8_t addr) {
383
-  uint8_t buffer[2] = {0, 0};
449
+  uint8_t buffer[2] = { 0 };
384 450
   readRegisterN(addr, buffer, 2);
385
-
386
-  uint16_t ret = buffer[0];
387
-  ret <<= 8;
388
-  ret |= buffer[1];
389
-
390
-  return ret;
451
+  return uint16_t(buffer[0]) << 8 | buffer[1];
391 452
 }
392 453
 
393 454
 /**
@@ -399,12 +460,12 @@ uint16_t MAX31865::readRegister16(uint8_t addr) {
399 460
  */
400 461
 void MAX31865::readRegisterN(uint8_t addr, uint8_t buffer[], uint8_t n) {
401 462
   addr &= 0x7F; // make sure top bit is not set
402
-  if (sclkPin == TERN(LARGE_PINMAP, -1UL, -1))
463
+  if (sclkPin == TERN(LARGE_PINMAP, -1UL, 255))
403 464
     SPI.beginTransaction(spiConfig);
404 465
   else
405
-    WRITE(sclkPin, LOW);
466
+    digitalWrite(sclkPin, LOW);
406 467
 
407
-  WRITE(cselPin, LOW);
468
+  digitalWrite(cselPin, LOW);
408 469
 
409 470
   #ifdef TARGET_LPC1768
410 471
     DELAY_CYCLES(spiSpeed);
@@ -414,16 +475,13 @@ void MAX31865::readRegisterN(uint8_t addr, uint8_t buffer[], uint8_t n) {
414 475
 
415 476
   while (n--) {
416 477
     buffer[0] = spiTransfer(0xFF);
417
-    #ifdef MAX31865_DEBUG_SPI
418
-      SERIAL_ECHOLNPGM("buffer read ", n, " data: ", buffer[0]);
419
-    #endif
420 478
     buffer++;
421 479
   }
422 480
 
423
-  if (sclkPin == TERN(LARGE_PINMAP, -1UL, -1))
481
+  if (sclkPin == TERN(LARGE_PINMAP, -1UL, 255))
424 482
     SPI.endTransaction();
425 483
 
426
-  WRITE(cselPin, HIGH);
484
+  digitalWrite(cselPin, HIGH);
427 485
 }
428 486
 
429 487
 /**
@@ -433,12 +491,12 @@ void MAX31865::readRegisterN(uint8_t addr, uint8_t buffer[], uint8_t n) {
433 491
  * @param data  the data to write
434 492
  */
435 493
 void MAX31865::writeRegister8(uint8_t addr, uint8_t data) {
436
-  if (sclkPin == TERN(LARGE_PINMAP, -1UL, -1))
494
+  if (sclkPin == TERN(LARGE_PINMAP, -1UL, 255))
437 495
     SPI.beginTransaction(spiConfig);
438 496
   else
439
-    WRITE(sclkPin, LOW);
497
+    digitalWrite(sclkPin, LOW);
440 498
 
441
-  WRITE(cselPin, LOW);
499
+  digitalWrite(cselPin, LOW);
442 500
 
443 501
   #ifdef TARGET_LPC1768
444 502
     DELAY_CYCLES(spiSpeed);
@@ -447,10 +505,10 @@ void MAX31865::writeRegister8(uint8_t addr, uint8_t data) {
447 505
   spiTransfer(addr | 0x80); // make sure top bit is set
448 506
   spiTransfer(data);
449 507
 
450
-  if (sclkPin == TERN(LARGE_PINMAP, -1UL, -1))
508
+  if (sclkPin == TERN(LARGE_PINMAP, -1UL, 255))
451 509
     SPI.endTransaction();
452 510
 
453
-  WRITE(cselPin, HIGH);
511
+  digitalWrite(cselPin, HIGH);
454 512
 }
455 513
 
456 514
 /**
@@ -463,36 +521,41 @@ void MAX31865::writeRegister8(uint8_t addr, uint8_t data) {
463 521
  * @return    the 8-bit response
464 522
  */
465 523
 uint8_t MAX31865::spiTransfer(uint8_t x) {
466
-  if (sclkPin == TERN(LARGE_PINMAP, -1UL, -1))
524
+
525
+  if (sclkPin == TERN(LARGE_PINMAP, -1UL, 255))
467 526
     return SPI.transfer(x);
468 527
 
469 528
   #ifdef TARGET_LPC1768
529
+
470 530
     return swSpiTransfer(x, spiSpeed, sclkPin, misoPin, mosiPin);
531
+
471 532
   #else
533
+
472 534
     uint8_t reply = 0;
473 535
     for (int i = 7; i >= 0; i--) {
474
-      WRITE(sclkPin, HIGH);         DELAY_NS_VAR(spiDelay);
536
+      digitalWrite(sclkPin, HIGH);       DELAY_NS_VAR(spiDelay);
475 537
       reply <<= 1;
476
-      WRITE(mosiPin, x & _BV(i));   DELAY_NS_VAR(spiDelay);
477
-      if (READ(misoPin)) reply |= 1;
478
-      WRITE(sclkPin, LOW);          DELAY_NS_VAR(spiDelay);
538
+      digitalWrite(mosiPin, x & _BV(i)); DELAY_NS_VAR(spiDelay);
539
+      if (digitalRead(misoPin)) reply |= 1;
540
+      digitalWrite(sclkPin, LOW);        DELAY_NS_VAR(spiDelay);
479 541
     }
480 542
     return reply;
543
+
481 544
   #endif
482 545
 }
483 546
 
484 547
 void MAX31865::softSpiBegin(const uint8_t spi_speed) {
485
-  #ifdef MAX31865_DEBUG
486
-    SERIAL_ECHOLNPGM("Initializing MAX31865 Software SPI");
487
-  #endif
548
+  DEBUG_ECHOLNPGM("Initializing MAX31865 Software SPI");
549
+
488 550
   #ifdef TARGET_LPC1768
489 551
     swSpiBegin(sclkPin, misoPin, mosiPin);
490 552
     spiSpeed = swSpiInit(spi_speed, sclkPin, mosiPin);
491 553
   #else
492 554
     spiDelay = (100UL << spi_speed) / 3; // Calculate delay in ns. Top speed is ~10MHz, or 100ns delay between bits.
493
-    OUT_WRITE(sclkPin, LOW);
494
-    SET_OUTPUT(mosiPin);
495
-    SET_INPUT(misoPin);
555
+    pinMode(sclkPin, OUTPUT);
556
+    digitalWrite(sclkPin, LOW);
557
+    pinMode(mosiPin, OUTPUT);
558
+    pinMode(misoPin, INPUT);
496 559
   #endif
497 560
 }
498 561
 

+ 34
- 9
Marlin/src/libs/MAX31865.h View File

@@ -41,6 +41,8 @@
41 41
  */
42 42
 #pragma once
43 43
 
44
+//#define DEBUG_MAX31865
45
+
44 46
 #include "../inc/MarlinConfig.h"
45 47
 #include "../HAL/shared/Delay.h"
46 48
 #include HAL_PATH(../HAL, MarlinSPI.h)
@@ -84,6 +86,14 @@ typedef enum max31865_numwires {
84 86
   MAX31865_4WIRE = 0
85 87
 } max31865_numwires_t;
86 88
 
89
+#if DISABLED(MAX31865_USE_AUTO_MODE)
90
+  typedef enum one_shot_event : uint8_t {
91
+    SETUP_BIAS_VOLTAGE,
92
+    SETUP_1_SHOT_MODE,
93
+    READ_RTD_REG
94
+  } one_shot_event_t;
95
+#endif
96
+
87 97
 /* Interface class for the MAX31865 RTD Sensor reader */
88 98
 class MAX31865 {
89 99
 private:
@@ -97,7 +107,21 @@ private:
97 107
     uint16_t spiDelay;
98 108
   #endif
99 109
 
100
-  float zeroRes, refRes;
110
+  float zeroRes, refRes, wireRes;
111
+
112
+  #if ENABLED(MAX31865_USE_READ_ERROR_DETECTION)
113
+    millis_t lastReadStamp = 0;
114
+  #endif
115
+
116
+  uint16_t lastRead = 0;
117
+  uint8_t lastFault = 0;
118
+
119
+  #if DISABLED(MAX31865_USE_AUTO_MODE)
120
+    millis_t nextEventStamp;
121
+    one_shot_event_t nextEvent;
122
+  #endif
123
+
124
+  uint8_t stdFlags = 0;
101 125
 
102 126
   void setConfig(uint8_t config, bool enable);
103 127
 
@@ -110,8 +134,15 @@ private:
110 134
 
111 135
   void softSpiBegin(const uint8_t spi_speed);
112 136
 
137
+  void initFixedFlags(max31865_numwires_t wires);
138
+
139
+  void enable50HzFilter(bool b);
140
+  void enableBias();
141
+  void oneShot();
142
+  void resetFlags();
143
+
113 144
 public:
114
-  #ifdef LARGE_PINMAP
145
+  #if ENABLED(LARGE_PINMAP)
115 146
     MAX31865(uint32_t spi_cs, uint8_t pin_mapping);
116 147
     MAX31865(uint32_t spi_cs, uint32_t spi_mosi, uint32_t spi_miso,
117 148
              uint32_t spi_clk, uint8_t pin_mapping);
@@ -121,17 +152,11 @@ public:
121 152
              int8_t spi_clk);
122 153
   #endif
123 154
 
124
-  void begin(max31865_numwires_t wires, float zero, float ref);
155
+  void begin(max31865_numwires_t wires, float zero_res, float ref_res, float wire_res);
125 156
 
126 157
   uint8_t readFault();
127 158
   void clearFault();
128 159
 
129
-  void setWires(max31865_numwires_t wires);
130
-  void autoConvert(bool b);
131
-  void enable50HzFilter(bool b);
132
-  void enableBias(bool b);
133
-  void oneShot();
134
-
135 160
   uint16_t readRaw();
136 161
   float readResistance();
137 162
   float temperature();

+ 2
- 8
Marlin/src/module/temperature.cpp View File

@@ -2202,11 +2202,8 @@ void Temperature::init() {
2202 2202
     #elif TEMP_SENSOR_IS_MAX(0, 31865)
2203 2203
       max31865_0.begin(
2204 2204
         MAX31865_WIRES(MAX31865_SENSOR_WIRES_0) // MAX31865_2WIRE, MAX31865_3WIRE, MAX31865_4WIRE
2205
-        OPTARG(LIB_INTERNAL_MAX31865, MAX31865_SENSOR_OHMS_0, MAX31865_CALIBRATION_OHMS_0)
2205
+        OPTARG(LIB_INTERNAL_MAX31865, MAX31865_SENSOR_OHMS_0, MAX31865_CALIBRATION_OHMS_0, MAX31865_WIRE_OHMS_0)
2206 2206
       );
2207
-      #if defined(LIB_INTERNAL_MAX31865) && ENABLED(MAX31865_50HZ_FILTER)
2208
-        max31865_0.enable50HzFilter(1);
2209
-      #endif
2210 2207
     #endif
2211 2208
 
2212 2209
     #if TEMP_SENSOR_IS_MAX(1, 6675) && HAS_MAX6675_LIBRARY
@@ -2216,11 +2213,8 @@ void Temperature::init() {
2216 2213
     #elif TEMP_SENSOR_IS_MAX(1, 31865)
2217 2214
       max31865_1.begin(
2218 2215
         MAX31865_WIRES(MAX31865_SENSOR_WIRES_1) // MAX31865_2WIRE, MAX31865_3WIRE, MAX31865_4WIRE
2219
-        OPTARG(LIB_INTERNAL_MAX31865, MAX31865_SENSOR_OHMS_1, MAX31865_CALIBRATION_OHMS_1)
2216
+        OPTARG(LIB_INTERNAL_MAX31865, MAX31865_SENSOR_OHMS_1, MAX31865_CALIBRATION_OHMS_1, MAX31865_WIRE_OHMS_1)
2220 2217
       );
2221
-      #if defined(LIB_INTERNAL_MAX31865) && ENABLED(MAX31865_50HZ_FILTER)
2222
-        max31865_1.enable50HzFilter(1);
2223
-      #endif
2224 2218
     #endif
2225 2219
     #undef MAX31865_WIRES
2226 2220
     #undef _MAX31865_WIRES

Loading…
Cancel
Save