SPI 128x64 OLED doesn't seem to like the MAX31865 and it's library

I’m working on a temperature controller for my Kamado smoker and am running into issues getting the PT100 sensor board to work properly and the OLED to display while using the PT100. If I comment out the code for the MAX31865 then the OLED displays properly, but once I put the lines back for the temperature sensing then the OLED flashes something that looks kind of like jumbled up bits of the words that I want for just a moment before going back to black. I’m using a Comidox MAX31865 off of ebay. I assume it is just a knock off of the Adafruit board but you know what is said of such things. (the Adafruit board was out of stock or I’d have bought it there)

I tried a different library for the OLED and that did not work either. I’ve tested the OLED on it’s own and it works fine. The MAX31865 board does not give proper outputs using the example code. I’m hoping it isn’t a board issue but I’m guessing there may be one. Though the issues that I’m having just having the code in there for it messes up the OLED even if I take the 31865 board off of the circuit.

The other thing is that the MAX31865 board does not read the correct temperature. I put a 100 ohm resistor an a jumper to simulate a 3 wire PT100 at 0 deg C but it is giving really high values instead.

Maybe the 2 issues are connected but I’m not an expert on SPI and various ways to set that up. I also had a PID library active for a while but the OLED wouldn’t work with that so I am doing a simple PID function of my own and will adjust the K values with trim pots on the board.

Would pull up resistors potentially help? I wonder if there’s a floating voltage that’s resetting the OLED

The OLED displays properly when I comment out this line and any other max31865 code after it:
thermo.begin(MAX31865_3WIRE); // set to 2WIRE or 4WIRE as necessary THIS INTERFERES WITH OLED

The code is attached. Any help is greatly appreciated!

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_MAX31865.h>


//Define Variables we'll be connecting to
int Temperature_Setpoint, Temperature_Actual, Blower;

volatile int sleep_counter = 0;  // OLED sleep timer in main loop cycles

int cycle_time = 0;
int Error = 0, Reset = 0, Output = 0, PreError = 0;
float Kp = 5.0, Ki = 0.5, Kd = 0;   //Specify the links and initial tuning parameters

#define SCREEN_WAKE 2
#define ON_SWITCH 6
#define OLED_RESET 7

#define OLED_CS    9
#define TEMP_CS    10
#define MOSI   11   //sdi on peripheral - SDA on OLED
#define MISO    12    //sdo on peripheral
#define CLK   13


Adafruit_SSD1306 display(128, 64, MOSI, CLK, 12, OLED_RESET, OLED_CS);  // MOSI, CLK, MISO, OLED_RESET, OLED_CS

Adafruit_MAX31865 thermo = Adafruit_MAX31865(TEMP_CS, MOSI, MISO, CLK); // TEMP_CS, MOSI, MISO, CLK



void setup() {
  Serial.begin(9600);
  
  if(!display.begin(SSD1306_SWITCHCAPVCC)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

  attachInterrupt(digitalPinToInterrupt(SCREEN_WAKE), wake_interrupt, RISING); // interrupt for waking up the OLED after timing out

  thermo.begin(MAX31865_3WIRE);  // set to 2WIRE or 4WIRE as necessary THIS INTERFERES WITH OLED


  // Clear the buffer
  display.clearDisplay();
  display.display();

  delay(500);

}


void loop() {

  // Check the trim potentiometers for PID constants

  Kp = analogRead(A0) / 102.4;
  Ki = analogRead(A1) / 102.4;
  Kd = analogRead(A2) / 102.4;

//  Serial.print("Switch state: "); Serial.println(switch_state);
  

  Temperature_Setpoint = analogRead(A4) * .488 + 150; // convert analog value to a desired temperature
  
  
  int Duty_Cycle = analogRead(A3) / 20.0 + 50;
  if (Duty_Cycle > 100) {
    Duty_Cycle = 100;
  }

  Temperature_Actual = thermo.temperature(100.0, 430.0); //  RTD SENSOR

  
  my_PID();   // call the PID function to calculate the output

  if (Blower > 255) { Blower = 255; }
  if (Blower < 100) { Blower = 100; }

  if(digitalRead(ON_SWITCH) == 1) { // check if the blower on/off switch is on
    if (cycle_time < Duty_Cycle) {
      analogWrite(3, 255);
      delay(250);
      analogWrite(3, Blower);
      delay(1000);
    }
    else {
      analogWrite(3, 0);
      Serial.println(" Main switch is off ");
      delay(50);
    }
    
    
  }
  //**********************PID*********************

  

  cycle_time = cycle_time + 10;

  if (cycle_time > 100) {
    cycle_time = 0;
  }
  

  if (sleep_counter > 500) {    // if the time has 
    Serial.println("Display goes to sleep");
    display.clearDisplay();
    display.display();
  }
  else {
    Serial.println("Display on");
    writeDisplay();
  }

  sleep_counter = sleep_counter + 1;

  /*
  Serial.print("Kp = ");
  Serial.print(Kp);
  
  Serial.print(", Ki = ");
  Serial.print(Ki);
  
  Serial.print(", Kd = ");
  Serial.print(Kd);

  */
  
  Serial.print(", Active Switch State = ");
  Serial.print(digitalRead(6));

  Serial.print(", Temperature Setpoint = ");
  Serial.print(Temperature_Setpoint);

  Serial.print(", Temperature Actual = ");
  Serial.print(Temperature_Actual);

//  uint16_t rtd = thermo.readRTD();
//
//  Serial.print(" RTD value: "); Serial.print(rtd);
  
  Serial.print(", Duty Cycle = ");
  Serial.print(Duty_Cycle);

  Serial.print(", cycle time = ");
  Serial.print(cycle_time);

  Serial.print(", Blower PWM = ");
  Serial.print(Blower);

  Serial.print(", Sleep timer = ");
  Serial.print(sleep_counter);



  Serial.println(",   end line");
}

void writeDisplay() {
  display.clearDisplay();
  Serial.println("in display");

  Serial.print("Actual temperature: "); Serial.println(Temperature_Actual);

  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);

  // display the temperature set point
  display.setCursor(2,2);
  display.println("Temperature Setpoint");
  display.setTextSize(2);
  display.setCursor(5,12);
  display.println(Temperature_Setpoint);
  display.setCursor(50,12);
  display.println("F");
/*
  display.setTextSize(1);
  // display the measured temperature
  display.setCursor(2,32);
  display.println("Actual Temperature");
  display.setTextSize(2);
  display.setCursor(5,42);
  display.println(Temperature_Actual);
  display.setCursor(50,42);
  display.println("F");

  display.setTextSize(1);
  display.setCursor(80,2);
  // indicate if the switch is on or off
  if(switch_state = true) {
    // display on indication
    display.println("RUN");
  }
  else {
    // display off indicator
    display.println("STANDBY");
  }

  display.setTextSize(1);
  // write Kp
  display.setCursor(80,14);
  display.println("Kp");
  display.setCursor(96,14);
  display.println(Kp);
  
  

  // write Ki
  display.setCursor(80,26);
  display.println("Ki");
  display.setCursor(96,26);
  display.println(Ki);
  
  

  // write Kd
  display.setCursor(80,38);
  display.println("Kd");
  display.setCursor(96,38);
  display.println(Kd);
  
  

  // write duty cycle
  display.setCursor(80,50);
  display.println("DC");
  display.setCursor(96,50);
  display.println(Duty_Cycle);
  display.setCursor(118,50);
  display.println("%");
  
  

    // 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();
  }
*/


  display.display();
  delay(1000);


}



void my_PID() {
  
   Error = Temperature_Setpoint - Temperature_Actual;         // calculate the error for the proportional component
   Reset = Reset + Ki * Error;                                // calculate the integral value
   Blower = Kp * Error + Reset + Kd * PreError - Kd * Error;  // calculate the output with the derivative component
   PreError = Error;                                          // save the error for the next loop
}

void wake_interrupt() {
  // reset the countdown timer
  sleep_counter = 0;

}

grill_temperature_control.ino (6.73 KB)

Please post links to the hardware that you have bought e,g. OLED and sensor board.
Yes, these items might be fairly generic. But posting links removes all doubt and ambiguity.

It looks as if you are bit-bashing SPI on a Uno's hardware SPI pins. Again, it is easy to say "Uno"
I would never trust bit-bashing on the same pins from two different libraries.

SPI is designed to run on hardware SPI. i.e. where it is intended to have multiple devices on the same hardware SPI bus.

First off. I would change both constructors to the HW SPI versions.

David.

I may have found at least one error. I equated the DC pin on the OLED with the MISO pin. I may have to do a bit of rewiring!

I pulled the OLED DC pin off to a different pin and the OLED works great now. The temperature sensor board still is reading 660C at a 100 ohm resistance. I do have the actual adafruit board coming from digikey along with a new PT100 probe. I do think something is a bit off with the board that I have.

Reading is fundamental!!

My problem with the PT100 amp board was that I didn't have the jumpers configured correctly. One last review of the Adafruit page on it got me set right. Now the OLED and the MAX31865 work great. I just need to get a temperature probe holder for the grill and I can start dialing in my PID constants.