SSD1306 & MAX31856 won't coexist on same SPI bus (adafruit libraries)

Hi,

Firstly, apologies if this is in the wrong section, I'm pretty new here!

I'm building a multigauge system for my car, it uses 3 SPI SSD1306 type 0.96" OLED displays.

The leftmost display is a graph of the selected input, the other two displays show smaller text based upon other inputs. The inputs are rotated around the displays with a button push (for now).

Here's a video of the setup before it went onto stripboard and into the vehicle:

I'm using software SPI - simply because I had no clue that there was HW SPI available when I started the project and I've not yet refactored.

I recently added a MAX31856 into the solution so that I can monitor exhaust gas temperature, and this works fine on the same pins as the OLED displays BUT the OLED displays are then drawn as filled white (as though they aren initialising constantly perhaps?). The max does however return valid data when the bus is shared (tested by outputting to the serial port)

I was originally using a MAX31856 library that I found online and figured that this may be stomping on the pins and/or not releasing CS correctly so refactored to use the adafruit max31586 library, only to get the same problem.

I then decided to move the max onto it's own software SPI bus and this results in everything working as expected.

I then had a look in the libraries to check some basics, endianness, bus rate etc. The libraries operate at different bus rates, so I set them to be the same and still the problem persists when sharing the bus.

So, I'm either doing something ridiculous in my code, or the 2 devices simply can't coexist on the same bus with the adafruit libraries.

This isn't a showstopper just yet because I have enough digital pins spare for my application, but I like things to be elegant so it would be great to have a single bus).

Here's a trimmed copy of the code that relates to how the devices are set up:

#include <Adafruit_SSD1306.h>
#include <Adafruit_MAX31856.h>

#define OLED_RESET  13
#define OLED_CS     12
#define OLED_DC     11  //MISO DC
#define OLED_CLK    10  //D0
#define OLED_MOSI    9  //D1
#define OLED_CS_2    4
#define OLED_CS_3    3
#define MAX_CS       5
#define MAX_DC       2  //MISO DI
#define MAX_CLK      7  //CLK
#define MAX_MOSI     6  //DO 

//Adafruit_MAX31856 max = Adafruit_MAX31856(MAX_CS, MAX_DC, MAX_MOSI, MAX_CLK); // seperate buses

Adafruit_MAX31856 max = Adafruit_MAX31856(MAX_CS, OLED_DC, OLED_MOSI, OLED_CLK); // shared bus

Adafruit_SSD1306 display1(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
Adafruit_SSD1306 display2(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS_2);
Adafruit_SSD1306 display3(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS_3);

//  code removed for clarity

void setup()   {
  display1.begin(SSD1306_SWITCHCAPVCC, SSD1306_I2C_ADDRESS, true);
  display2.begin(SSD1306_SWITCHCAPVCC, SSD1306_I2C_ADDRESS, false);
  display3.begin(SSD1306_SWITCHCAPVCC, SSD1306_I2C_ADDRESS, false);

  display1.clearDisplay();   // clears the screen and buffer
  display2.clearDisplay();   // clears the screen and buffer
  display3.clearDisplay();   // clears the screen and buffer
 
  max.begin();

  max.setThermocoupleType(MAX31856_TCTYPE_K);

// code removed for clarity
}

void loop() {
// do sensor reading and display drawing
}

Any ideas?

In your code, both devices operate on software SPI mode, which probably will not work. Try both devices in hardware SPI mode (both libs will use SPI.h):

Adafruit_MAX31856 max = Adafruit_MAX31856(MAX_CS); // shared bus

Adafruit_SSD1306 display1(OLED_DC, OLED_RESET, OLED_CS);
Adafruit_SSD1306 display2(OLED_DC, OLED_RESET, OLED_CS_2);
Adafruit_SSD1306 display3(OLED_DC, OLED_RESET, OLED_CS_3);

Oliver

Thanks, I'll give that a try.