ESP32-S3, TFT_eSPI ILI9341 display and MAX31855 thermocouple ic

Hi,

I'm a little confused as to how to set up my SPI code if using a TFT display (ILI9341 driver) and a MAX31855 (well, four actually) module.

I've been using the MAX31855 (one module) with an ESP32C3 with onboard OLED using the U8G2LIB library and all is working fine, but I want to use a TFT display with Bodmer's library as it's fantastic and have used it on other projects. The problem is though that I can't get my head around how to set up the SPI bit.

I'm not using a specific library to control the MAX31855, and for those interested, here's the code that I'm using that works great on an OLED and i2c:

#include <SPI.h>
#include <U8g2lib.h>
#include <Wire.h>

// Define the pins connected to the MAX31855
#define MAX31855_CS 3    // CS pin
#define MAX31855_MISO 8  // MISO pin
#define MAX31855_SCK 10  // SCK pin
#define SDA_PIN 5        // 5
#define SCL_PIN 6        // 6
char buf[10];            // Array for showing rpm on OLED display
float maxTemp = 0;
uint32_t prevMillis = 0;
uint32_t interval = 1000;

U8G2_SSD1306_72X40_ER_F_HW_I2C u8g2(U8G2_R2, /* reset=*/U8X8_PIN_NONE);  // Frame Buffer  EastRising 0.42" OLED

// Function to read temperature from MAX31855
double readTemp() {
  // Select the MAX31855
  digitalWrite(MAX31855_CS, LOW);
  delayMicroseconds(1);

  // Read the data
  byte data[4];
  SPI.transfer(data, sizeof(data));

  // Deselect the MAX31855
  digitalWrite(MAX31855_CS, HIGH);

  // Check for thermocouple error
  if (data[3] & 0x01) {
    Serial.println("Thermocouple Error");
    return NAN;  // Not a Number
  }

  // Combine the data
  int32_t tempRaw = ((data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]) >> 18;

  // Convert to Celsius
  return tempRaw * 0.25;
}

void setup() {
  // Initialize SPI communication
  SPI.begin(MAX31855_SCK, MAX31855_MISO, MAX31855_CS);
  Wire.begin(SDA_PIN, SCL_PIN);
  Wire.setClock(400000);  // choose 400 kHz I2C rate
  u8g2.begin();
  u8g2.enableUTF8Print();
  Serial.begin(115200);
  delay(250);

  // Set the CS pin as an output
  pinMode(MAX31855_CS, OUTPUT);

  prevMillis = millis();
}

void loop() {
  // Read temperature from MAX31855
  double temperature = readTemp();

  if (temperature > maxTemp) {
    maxTemp = temperature;
  }

  // Print temperature to serial monitor
  //  if (!isnan(temperature)) {
  //    Serial.print("Temperature: ");
  //    Serial.print(temperature);
  //    Serial.println(" °C");
  //  }


  if (millis() - prevMillis >= interval) {
    prevMillis = millis();
    u8g2.clearBuffer();  // clear the internal memory
    u8g2.setFont(u8g2_font_logisoso18_tf);
    u8g2.setCursor(0, 22);
    sprintf(buf, "%5.1f°C", temperature);
    u8g2.print(buf);
    u8g2.setFont(u8g2_font_helvR10_tf);
    u8g2.setCursor(10, 40);
    u8g2.printf("%5.1f°C", maxTemp);
    u8g2.sendBuffer();  // transfer internal memory to the display
  }

  delay(100);  // Wait for 100ms
}

Now I want to use an ESP32 S3 zero board.

I set some pins for the SPI in the User_Setup.h file and ran a couple of the TFT_eSPI examples on the S3 board and all works fine. It's just that I don't know how to set up the pins to also use the MAX31855 modules.

I understand that the chip select pins need to be all different for each device, but do I just use the MISO and SCK pins as defined in the User_Setup.h file for the MAX31855? I read a few things of people saying that they have issues and had to set a specific SCK pin(s). That was mostly specific to the MAX6675 module, but they work pretty much the same as the 31855 so I presume that what works for the 6675 will work for the 31855. However, I can't find any specific code for how to do this.

If anyone can assist I would be super grateful as I don't really want to have to stick with an OLED display purely due to my incompetence! :slight_smile:

Fingers crossed that the answer to this puzzle is not too complicated.

If more info is required then please let me know.

Cheers,

Matt

Update.

With a fair bit of research last night and some ChatGPT assistance I now have the following code (shown below), which at least works. I get the temperature displayed and it updates as expected every second.

Just to fill in the blanks I'm using an EXP32 S3 Zero board. 2.2" TFT display (ILI9341 driver) and TFT_eSPI library. Arduino IDE 2.3.2 and ESP32 V2.0.11 boards manager.

I think that I have something to work on now, and maybe this will help others in the same sticky situation. It's not exactly what I want, but I think that I can figure it out from here.

Maybe someone knows a different way of doing it.

Anyway, here's the code.

#include <SPI.h>
#include <TFT_eSPI.h>

// Define the pins connected to the TFT display
#define TFT_CS    3
#define TFT_RST   1
#define TFT_DC    2

TFT_eSPI tft = TFT_eSPI();  // Create TFT object

// Define the pins connected to the MAX31855 IC
#define MAX31855_CS   8   // CS pin for MAX31855

// Define shared SPI pins for TFT and MAX31855 modules
#define SHARED_SPI_MISO  10
#define SHARED_SPI_MOSI  12

// Define SCK pin for TFT display
#define TFT_SPI_SCK   11

// Define custom SCK pin for MAX31855 module
#define MAX31855_SPI_SCK   9

// Create an instance of SPIClass for TFT display
SPIClass spi_tft(HSPI);

// Create an instance of SPIClass for MAX31855 module
SPIClass spi_max31855(VSPI);

// Function to read temperature from a MAX31855 IC
double readTemp(int csPin) {
  // Select the MAX31855
  digitalWrite(csPin, LOW);
  delayMicroseconds(1);

  // Read the data
  byte data[4];
  spi_max31855.transfer(data, sizeof(data));

  // Deselect the MAX31855
  digitalWrite(csPin, HIGH);

  // Check for thermocouple error
  if (data[3] & 0x01) {
    tft.println("Thermocouple Error");
    return NAN; // Not a Number
  }

  // Combine the data
  int32_t tempRaw = ((data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]) >> 18;

  // Convert to Celsius
  return tempRaw * 0.25;
}

void setup() {
  // Initialize SPI communication for TFT display
  spi_tft.begin(TFT_SPI_SCK, SHARED_SPI_MISO, SHARED_SPI_MOSI);
  
  // Set the CS pin for TFT display as output
  pinMode(TFT_CS, OUTPUT);
  
  // Initialize TFT display
  tft.init();
  tft.setRotation(1);
  tft.fillScreen(TFT_BLACK);
  tft.setTextColor(TFT_WHITE);
  tft.setTextSize(2);
  
  // Initialize SPI communication for MAX31855 module
  spi_max31855.begin(MAX31855_SPI_SCK, SHARED_SPI_MISO, SHARED_SPI_MOSI);
  
  // Set the CS pin for MAX31855 module as output
  pinMode(MAX31855_CS, OUTPUT);
}

void loop() {
  // Read temperature from MAX31855 IC
  double temperature = readTemp(MAX31855_CS);
  
  // Create sprite for displaying temperature
  TFT_eSprite tempSprite = TFT_eSprite(&tft);
  tempSprite.createSprite(160, 80); // Create sprite with dimensions of 160x80 pixels
  tempSprite.fillSprite(TFT_BLACK); // Fill sprite with black color
  tempSprite.setTextSize(2);
  tempSprite.setCursor(10, 20);
  tempSprite.println("Temperature:");
  tempSprite.setTextSize(2);
  tempSprite.setCursor(40, 50);
  tempSprite.print(temperature);
  tempSprite.println(" C");
  tempSprite.pushSprite(0, 0); // Display sprite on TFT display
  
  delay(1000);  // Wait for 1 second
}

Cheers,

Matt

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