Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix up MAX31865 / SPI (PT100 & PT1000) support #20074

Merged
merged 17 commits into from
Nov 11, 2020
Merged

Fix up MAX31865 / SPI (PT100 & PT1000) support #20074

merged 17 commits into from
Nov 11, 2020

Conversation

GadgetAngel
Copy link
Contributor

Requirements

The following equipment was used to test this PR:

  • SKR PRO V1.1 board
  • 2 PT100 sensors
  • (1) 100K Thermistor (to verify the temperatures being displayed by the Adafruit MAX31865 boards with PT100 sensors attached)
  • A 12864 LCD display attached to EXP1 and EXP2 port on the SKR PRO V1.1 board
  • a clamp on tap for the EXP2 ribbon cable so I can access the default hardware SPI lines (https://www.digikey.com/product-detail/en/te-connectivity-amp-connectors/1658622-1/AKC10B-ND/825411)
  • A TFT35 V2.0 Touch Display attached to TFT port on the SKR PRO V1.1 board
  • a soldering iron in a soldering stand
  • "helping hands" to hold the three temperature sensor so I can adjust them to see if temperature readings are correct and change as expected
  • laptop with USB connection to the SKR PRO V1.1 for use with pronterface
  • Ohm meter to check the PT100 sensor to ensure that they read ~110 Ohm
  • Dupont jumper cables to attach the two Adafruit MAX31865 boards. Some Dupont Jumpers cables were used to also create Y-Jumper cables

To test the Hardware SPI was working for the two Adafruit MAX31865 I used the below wiring diagram:
Two PT100swithTwoMAX31865 boardsinHWSPIonSKR PRO V1 1 boardWiring Diagram

Before my software modifications were made the picture below shows the error messages I would receive over the primary SERIAL_PORT via pronterface. The Errors were being produced constantly but the temperature reading on TEMP_SENSOR_0 was still correct:
Adafruit MAX31865 Error messages

Here are two videos showing the two Adafruit MAX31865 boards working correctly after running my branch of Marlin.

The video listed below shows the two Adafruit MAX31865 boards hooked to the SKR PRO V1.1 board and the setup with the PT100s, Thermistor and soldering iron (generates heat for the temperature sensors to detect).
https://drive.google.com/file/d/1y1Eci10ab0DECRKsVId_f1ElnZRGyxFv/view?usp=sharing

This video below shows that the error messages are no longer being produced to the SERIAL_PORT because the .readFault() property of the Adafruit MAX31865 board's object is being used to query the device.
https://drive.google.com/file/d/1rnHuzNvfPOKWnCE0Nfg66CuRqF8vWzth/view?usp=sharing


To test the Software SPI was working for the two Adafruit MAX31865 I used the below wiring diagram:
Two PT100swithTwoMAX31865 boardsinSW_SPIonSKR PRO V1 1 boardWiring Diagram

Due to the changes to get the temperature displayed correctly when testing the Hardware SPI, the software SPI worked like a charm.

Both Adafruit MAX31865 boards reported the correct temperatures and when I moved the sensor farther away from the heat source (soldering iron) the temperature changed as expected.

I used a 100K Thermistor on the third extruder to compare the temperature reading to the one I was getting from Marlin for the PT100s connected to the MAX31865 boards.

Description

Below I describe where I added code to Marlin or fixed the code that was present in Marlin:

Added two new Marlin variables in configuration.h file: MAX31865_SENSOR_OHMS_1 and MAX31865_CALIBRATION_OHMS_1. These new Marlin variables are tied to the MAX31865 on TEMP_SENSOR_1. Changed the name of these variables that Marlin already has for TEMP_SENSOR_0, they are now called :MAX31865_SENSOR_OHMS_0 and MAX31865_CALIBRATION_OHMS_0. I wanted separated Marlin variables so that I can place a PT100 on E0 and a PT1000 on E1.

In SanityCheck.h file, I added code to ensure that MAX31865_SENSOR_OHMS_1 and MAX31865_CALIBRATION_OHMS_1 were set if TEMP_SENSOR_1 was using MAX31865 board. I updated the check for TEMP_SENSOR_0 so it checks for MAX31865_SENSOR_OHMS_0 and MAX31865_CALIBRATION_OHMS_0.

The reset of the changes in this PR are done in temperature.cpp file.

At line 52, I check to see if the user defines MAX31865_CS2_PIN. If MAX31865_CS2_PIN is not defined I equate it to MAX6675_SS2_PIN which will then force Hardware SPI to be used.

At line 66, I changed the name of the max31865 object for the MAX31865 on TEMP_SENSOR_0 from "max31865" to "max31865_0". I then replace all occurrences of "max31865." in temperature.cpp to "max31865_0." I also changed all occurrences of MAX31865_SENSOR_OHMS to MAX31865_SENSOR_OHMS_0. Again I also changed all occurrences of MAX31865_CALIBRATION_OHMS to MAX31865_CALIBRATION_OHMS_0.

At line 73, I added the new object instantiation of the second MAX31865 board for TEMP_SENSOR_1, if the printer is using a MAX31865 board on TEMP_SENSOR_1. This new object is called "max31865_1."

In Temperature::analog_to_celsius_hotend(), I added the ability to convert the new object's (max31865_1) data into a Celsius temperature.

In Temperature::init(), I initialize the new object (max31865_1) and configure the new object to use MAX31865_2WIRE.

The rest of the changes in temperature.cpp where made in Temperature::read_max6675():

At line 2249, I added code that uses the correct MAX6675 BIT MASKS (MAX6675_ERROR_MASK, MAX6675_DISCARD_BITS, and MAX6675_SPEED_BITS) for the Adafruit MAX31865 board based on the data found on the MAX31865 data sheet (https://datasheets.maximintegrated.com/en/ds/MAX31865.pdf). Without this added code the Adafruit MAX31865 device ends up using the MAX6675 board's BIT MASKS which were incorrectly displaying error messages. On top of it all the number of discard bits Marlin was previously using was 3 bits which is what a MAX6675 board needs but the MAX31865 board only requires you to shift right by ONE bit.

At line 2275, I ensure the appropriate Adafruit MAX31865 object (max31865_0 or max31865_1) sends back the converted data so the correct temperature can be displayed in the correct variable. The return variable is changed if the number of extruders on the printer is greater than 1.

At line 2326, I added code so that Marlin will use the Adafruit MAX31865 library call readFault() property. The code chooses the appropriate MAX31865 object to use for the current call. If readFault() property returns a number greater than 1, a fault occurred on that object and the variable "fault" is changed from 1 to the actual fault value. Therefore at line 2337, I added a new variable to the AND statement (I added the variable "fault"). Since the variable "fault" is initialized to 1 and if a MAX31865 is not present on the printer, the IF block for checking MAX6675 errors still gets executed as before this change. At line 2350, I added code inside the MAX6675 error checking block that allows Marlin to tell the user which of the seven faults occurred on the MAX31865 board. I use the Adafruit MAX31865 library bit masks (included in Adafruit_MAX31865.h file) to determine which fault occurred. After the error message is display, the object that the fault occurred on is then used to clear the fault by calling the Adafruit MAX31865 property clearFault() and processing continues on.

Benefits

This PULL REQUEST stops the false error message that were being produce from occurring and being sent to SERIAL_PORT. See
#19994 (comment).

Added a new ability that when the Adafruit MAX31865 board is checked for faults, the code will now display which of the seven(7) possible faults it found on the SERIAL_PORT with an appropriate error message. Before it just displayed "Error: temp measurement error MAX6675", which does not indicate the fault condition of the Adafruit MAX31865. After a fault is found and message is displayed, the code will clear the fault on the board.

Fixed the incorrect temperature being displayed by the Adafruit MAX31865 board connected to TEMP_SENSOR_1.
This error was caused by the fact that Marlin never instantiated and object for the second Adafruit MAX31865 which meant it was never initialized and the raw data being produced by the board was never getting converted because Marlin did not handle the data coming from the board and convert it to Celsius. The wrong temperature value was read ~2047 at room temperature.

Marlin did display the correct temperature for the first Adafruit MAX31865 connected to TEMP_SENSOR_0.

Added a new ability that allows the user to use a (PT100 on E0 and a PT1000 on E1) OR (PT1000 on E0 and a PT100 on E1). To do this I updated the MAX31865_SENSOR_OHMS to MAX31865_SENSOR_OHMS_0. I also updated MAX31865_CALIBRATION_OHMS to MAX31865_CALIBRATION_OHMS_0. I then added two additional Marlin variables which are used for TEMP_SENSOR_1 called MAX31865_SENSOR_OHMS_1 and MAX31865_CALIBRATION_OHMS_1. With these four Marlin variables, the user can now use a PT100 and a PT1000 on the printer at the same time.

Added a check in SanityCheck.h that check to ensure that MAX31865_SENSOR_OHMS_1 and MAX31865_CALIBRATION_OHMS_1 are set if TEMP_SENSOR_1 is using the MAX31865 board.

Configurations

Configuration files for PR.zip

Related Issues

See #19994 (comment). This PR fixes the "temp errors" being sent to the SERIAL_PORT.

Fulls feature request fullfilled: #19663 (comment)

@sjasonsmith
Copy link
Contributor

I think @Bob-the-Kuhn added the original version of this. Perhaps they would be interested in reviewing the changes you made.

@sjasonsmith
Copy link
Contributor

@GadgetAngel you might change the title to mention PT100 and MAX31865, so that people will know whether it impacts them when looking at the list of open PRs.

@GadgetAngel GadgetAngel changed the title Marlin fix "temp errors" and other issues Marlin fix "temp errors" for Adafruit MAX31865, allows two MAX31865 boards to be used in SPI mode (PT100 & PT1000) Nov 8, 2020
@thinkyhead thinkyhead changed the title Marlin fix "temp errors" for Adafruit MAX31865, allows two MAX31865 boards to be used in SPI mode (PT100 & PT1000) Fix up MAX31865 / SPI (PT100 & PT1000) support Nov 9, 2020
Copy link
Contributor Author

@GadgetAngel GadgetAngel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good

Copy link
Contributor Author

@GadgetAngel GadgetAngel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good

@GadgetAngel
Copy link
Contributor Author

GadgetAngel commented Nov 11, 2020

@thinkyhead Is my understanding of the following correct:

In temperature.cpp starting at line 2294:

   const uint8_t fault = TERN0(HAS_MAX31865, maxref.readFault());

    if (DISABLED(IGNORE_THERMOCOUPLE_ERRORS) && (max6675_temp & MAX6675_ERROR_MASK) && fault) {
     // error block
    }
   else {
      max6675_temp >>= MAX6675_DISCARD_BITS;
      max6675_errors[hindex] = 0;
    }

If you want the error block to be executed when you have a MAX31855 in the system without a MAX31865 shouldn't you use
const uint8_t fault = TERN1(HAS_MAX31865, maxref.readFault()); ?

Does TERN0 return a 0 if HAS_MAX31865 is disabled?

If TERN0 returns a 0 when HAS_MAX31865 is disabled, then the error block will never get executed for the MAX31855 boards.

I think TERN0 needs to be TERN1. Made the change, If I am wrong you will change it back.

@GadgetAngel
Copy link
Contributor Author

@thinkyhead I have the following equipment that I can test with if you need me to help with testing this branch:

SKR PRO V1.1
GTR V1.0
SKR V1.3
SKR V1.4 turbo
TMC2209, TMC5160, TMC2130, TMC2208
PT100, PT1000, Thermocouple, Thermistor
MAX31865, MAX31855, MAX6675, AD8495, PT100 amplifier

If there is any particular configuration you want tested, just ask.

GadgetAngel and others added 16 commits November 11, 2020 15:21
This branch stops the false error message that were being produce from occurring and being sent to SERIAL_PORT. See #19994 (comment).

Added a new ability that when the Adafruit MAX31865 board is checked for faults, the code will now display which of the seven (7) possible faults it found on the SERIAL_PORT with an appropriate error message.  Before it just displayed "Error: temp measurement error MAX6675", which does not indicate the fault condition of the Adafruit MAX31865.  After a fault is found and message is displayed, the code will clear the fault on the board.

Fixed the incorrect temperature being displayed by the Adafruit MAX31865 board connected to TEMP_SENSOR_1.
This error was caused by the fact that Marlin never instantiated and object for the second Adafruit MAX31865 which meant it was never initialized and the raw data being produced by the board was never getting converted because Marlin did not handle the data coming from the board and convert it to Celsius.  The wrong temperature value was read ~2047 at room temperature.

Marlin did display the correct temperature for the first Adafruit MAX31865 connected to TEMP_SENSOR_0.

Added a new ability that allows the user to use a (PT100 on E0 and a PT1000 on E1) OR (PT1000 on E0 and a PT100 on E1).  To do this I updated the MAX31865_SENSOR_OHMS to MAX31865_SENSOR_OHMS_0.  I also updated  MAX31865_CALIBRATION_OHMS to  MAX31865_CALIBRATION_OHMS_0.  I then added two additional Marlin variables which are used for TEMP_SENSOR_1 called MAX31865_SENSOR_OHMS_1 and MAX31865_CALIBRATION_OHMS_1.  With these four Marlin variables, the user can now use a PT100 and a PT1000 on the printer at the same time.

Added a check in SanityCheck.h that check to ensure that MAX31865_SENSOR_OHMS_1 and MAX31865_CALIBRATION_OHMS_1 are set if TEMP_SENSOR_1 is using the MAX31865 board.

See #19994 (comment).  This branch fixes the "temp errors" being sent to the SERIAL_PORT.

Feature request fullfilled: #19663 (comment)
In temperature.h if HAS_MULTI_6675 does not have a 1 after it. HAS_MULTI_6675 is defined as NUL

In temperature.cpp  when Thermocouple is open the max6675_temp value is meant to have a TMAX * 4 so I added the pair of parentheses so the compiler would stop throwing a waring message about the statement being a binary statement.
@thinkyhead thinkyhead merged commit 40d442f into MarlinFirmware:bugfix-2.0.x Nov 11, 2020
FhlostonParadise pushed a commit to FhlostonParadise/Marlin that referenced this pull request Nov 21, 2020
Kannix2005 pushed a commit to Kannix2005/Marlin-1 that referenced this pull request Dec 7, 2020
vgadreau pushed a commit to vgadreau/Marlin that referenced this pull request Dec 9, 2020
tharts pushed a commit to tharts/Marlin that referenced this pull request Jan 6, 2021
dpreed pushed a commit to dpreed/Marlin_2.0.x that referenced this pull request Feb 5, 2021
kpishere pushed a commit to kpishere/Marlin that referenced this pull request Feb 19, 2021
W4tel-BiDi pushed a commit to W4tel-BiDi/Marlin that referenced this pull request Apr 5, 2021
thinkyhead pushed a commit to thinkyhead/Marlin that referenced this pull request Apr 28, 2021
thinkyhead pushed a commit to thinkyhead/Marlin that referenced this pull request Apr 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants