MAX31865 on ESP32

Hello,
I am using the MAX31865 on an ESP32. I used the example Code for debuing and adjusted the CS,MISO,MOSI and CLK GPIOs.

/*************************************************** 
  This is a library for the Adafruit PT100/P1000 RTD Sensor w/MAX31865

  Designed specifically to work with the Adafruit RTD Sensor
  ----> https://www.adafruit.com/products/3328

  This sensor uses SPI to communicate, 4 pins are required to  
  interface
  Adafruit invests time and resources providing this open source code, 
  please support Adafruit and open-source hardware by purchasing 
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.  
  BSD license, all text above must be included in any redistribution
 ****************************************************/

#include <Adafruit_MAX31865.h>

#define CS_A 27
#define CS_B 33
#define CS_C 32

#define DRDY_A 15
#define DRDY_B 25
#define DRDY_C 14

#define SDI 23
#define SDO 19
#define CLK 18


// Use software SPI: CS, DI, DO, CLK
Adafruit_MAX31865 thermo = Adafruit_MAX31865(CS_A, SDI, SDO, CLK);
// use hardware SPI, just pass in the CS pin
//Adafruit_MAX31865 thermo = Adafruit_MAX31865(10);

// The value of the Rref resistor. Use 430.0 for PT100 and 4300.0 for PT1000
#define RREF      430.0
// The 'nominal' 0-degrees-C resistance of the sensor
// 100.0 for PT100, 1000.0 for PT1000
#define RNOMINAL  100.0

void setup() {
  Serial.begin(115200);
  Serial.println("Adafruit MAX31865 PT100 Sensor Test!");
  delay(1000);
  thermo.begin(MAX31865_4WIRE);  // set to 2WIRE or 4WIRE as necessary
  delay(1000);
}


void loop() {
  uint16_t rtd = thermo.readRTD();

  Serial.print("RTD value: "); Serial.println(rtd);
  float ratio = rtd;
  ratio /= 32768;
  Serial.print("Ratio = "); Serial.println(ratio,8);
  Serial.print("Resistance = "); Serial.println(RREF*ratio,8);
  Serial.print("Temperature = "); Serial.println(thermo.temperature(RNOMINAL, RREF));

  // Check and print any faults
  uint8_t fault = thermo.readFault();
  if (fault) {
    Serial.print("Fault 0x"); Serial.println(fault, HEX);
    if (fault & MAX31865_FAULT_HIGHTHRESH) {
      Serial.println("RTD High Threshold"); 
    }
    if (fault & MAX31865_FAULT_LOWTHRESH) {
      Serial.println("RTD Low Threshold"); 
    }
    if (fault & MAX31865_FAULT_REFINLOW) {
      Serial.println("REFIN- > 0.85 x Bias"); 
    }
    if (fault & MAX31865_FAULT_REFINHIGH) {
      Serial.println("REFIN- < 0.85 x Bias - FORCE- open"); 
    }
    if (fault & MAX31865_FAULT_RTDINLOW) {
      Serial.println("RTDIN- < 0.85 x Bias - FORCE- open"); 
    }
    if (fault & MAX31865_FAULT_OVUV) {
      Serial.println("Under/Over voltage"); 
    }
    thermo.clearFault();
    *((uint32_t*) DR_REG_RTCCNTL_BASE) |= BIT31; //Core reset of CPU and register (0x03 0x03 Software System Reset Core R
  }
  Serial.println();
  delay(1000);
}

When flashing the code and starting the code seems to work fine, but when I reset the hardware or disconnect and reconnect after a few seconds it goes into the error loop and this is the output i get:
RTD value: 32767
10:22:24.772 -> Ratio = 0.99996948
10:22:24.772 -> Resistance = 429.98687744
10:22:24.772 -> Temperature = 988,79
10:22:24.866 -> Fault 0xFF
10:22:24.866 -> RTD High Threshold
10:22:24.866 -> RTD Low Threshold
10:22:24.866 -> REFIN- > 0.85 x Bias
10:22:24.866 -> REFIN- < 0.85 x Bias - FORCE- ⸮ets Jun 8 2016 00:22:57

It seems that the RTD is always close to the maximum 32k and i only measure a Temp of 1000.
I am using a PT100 and 4Wire Sensing

Thank you very much

I could not solve the issue with the Adafruit library. However I found an incredible helpful video on yt and adapted my code to it.
Link to yt video: MAX31865 - Pt100 RTD module - YouTube
My Code:

/*************************************************** 
  This is a library for the Adafruit PT100/P1000 RTD Sensor w/MAX31865

  Designed specifically to work with the Adafruit RTD Sensor
  ----> https://www.adafruit.com/products/3328

  This sensor uses SPI to communicate, 4 pins are required to  
  interface
  Adafruit invests time and resources providing this open source code, 
  please support Adafruit and open-source hardware by purchasing 
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.  
  BSD license, all text above must be included in any redistribution
 ****************************************************/

#include <Adafruit_MAX31865.h>
#include <stdlib.h>
#include <SPI.h>

#define CS_A 27
#define CS_B 33
#define CS_C 32

#define DRDY_A 15
#define DRDY_B 25
#define DRDY_C 14

#define SDI 23
#define SDO 19
#define CLK 18


//CS => CS //Arduino 10
//MISO => SDO //Arduino 12
//MOSI => SDI //Arduino 11
//SCK => SCK //Arduino 13

//Variables for the PT100 boards
double resistance;
uint8_t reg1, reg2; //reg1 holds MSB, reg2 holds LSB for RTD
uint16_t fullreg; //fullreg holds the combined reg1 and reg2
double temperature;
//Variables and parameters for the R - T conversion
double Z1, Z2, Z3, Z4, Rt;
double RTDa = 3.9083e-3;
double RTDb = -5.775e-7;
double rpoly = 0;



//const int chipSelectPin = 10;

void setup()
{
  SPI.begin();
  Serial.begin(115200); //Start serial
  pinMode(CS_A, OUTPUT); //because CS is manually switched  
  pinMode(CS_B, OUTPUT);
  pinMode(CS_C, OUTPUT);
  
}

void loop()
{
  readRegister(CS_A);
  convertToTemperature(CS_A);
  delay(10);

  readRegister(CS_B);
  convertToTemperature(CS_B);
  delay(10);

  readRegister(CS_C);
  convertToTemperature(CS_C);
  delay(10);
}


void convertToTemperature(int8_t CS)
{
  switch(CS){
    case 27: Serial.println("Temperaturmessung von MAX_A startet!");
    break;
    case 33: Serial.println("Temperaturmessung von MAX_B startet!");
    break;
    case 32: Serial.println("Temperaturmessung von MAX_C startet!");
    break;
    default: Serial.println("Kein entsprechender CS vorhanden"); break;
    }
  Rt = resistance;
  Rt /= 32768;
  Rt *= 430; //This is now the real resistance in Ohms
  Serial.print("Resistance: ");
  Serial.println(Rt); //Temperature in Celsius degrees
  Z1 = -RTDa;
  Z2 = RTDa * RTDa - (4 * RTDb);
  Z3 = (4 * RTDb) / 100;
  Z4 = 2 * RTDb;

  temperature = Z2 + (Z3 * Rt);
  temperature = (sqrt(temperature) + Z1) / Z4;

  if (temperature >= 0)
  {
    Serial.print("Temperature: ");
    Serial.println(temperature); //Temperature in Celsius degrees
    return; //exit
  }
  else
  {
    Rt /= 100;
    Rt *= 100; // normalize to 100 ohm

    rpoly = Rt;

    temperature = -242.02;
    temperature += 2.2228 * rpoly;
    rpoly *= Rt; // square
    temperature += 2.5859e-3 * rpoly;
    rpoly *= Rt; // ^3
    temperature -= 4.8260e-6 * rpoly;
    rpoly *= Rt; // ^4
    temperature -= 2.8183e-8 * rpoly;
    rpoly *= Rt; // ^5
    temperature += 1.5243e-10 * rpoly;

    Serial.print("Temperature: ");
    Serial.println(temperature); //Temperature in Celsius degrees
  }
  //Note: all formulas can be found in the AN-709 application note from Analog Devices
}


void readRegister(int8_t ChipSel)
{
  SPI.beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE1));
  digitalWrite(ChipSel, LOW);

  SPI.transfer(0x80); //80h = 128 - config register
  SPI.transfer(0xA0); // A0h = 160 - 1010000: set bias high, start 1-shot, 2/4-Wire
  delay(10); // Wartezeit fuer Conversion
  //Von Schreiben in Lesen muss High-Low gesetzt werden
  digitalWrite(ChipSel, HIGH);
  digitalWrite(ChipSel, LOW);
  //
  
  SPI.transfer(1); // Daten sollen ausgelesen werden
  reg1 = SPI.transfer(0xFF); // 8 Bit vom MSB
  reg2 = SPI.transfer(0xFF); // 8 Bit vom LSB
  digitalWrite(ChipSel, HIGH);

  fullreg = reg1; //read MSB
  fullreg <<= 8;  //Shift to the MSB part
  fullreg |= reg2; //read LSB and combine it with MSB
  fullreg >>= 1; //Shift D0 out. -> eigentlich nur 15Bit und nicht 16
  resistance = fullreg; //pass the value to the resistance variable
  //note: this is not yet the resistance of the RTD!

  digitalWrite(ChipSel, LOW);
  SPI.transfer(0x80); //80h = 128
  //SPI.transfer(0x00); //144 = 10010000
  SPI.endTransaction();
  digitalWrite(ChipSel, HIGH);

}

I changed some of the Data written to the Controlregister and I had to add some delay to make it work. This Code is adapted for 3 separate MAX31685 which share the MISO,MOSI,CLK signals and are each assigned 1 CS pin. I left out the DRDY Pins and just toggle the Conversion every 30ms for each ADC. If you have any tips on how to improve my code, or if you know the solution on why the Adafruit library did not work for me please feel free to reply.
Have a nice day :slight_smile:

2 Likes

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.