Can't initialize CAN bus and SSD1306

I've got some hardware (mega 2560) with 2 128x32 SSD1306 OLEDS and an MCP2515 CAN transceiver. They work separately, but not together. If I run the code as below, the screens will work, but if I uncomment the CAN initialization in the setup loop, the displays no longer respond. Thoughts?

In another project, with one screen communicating via I2C and the CAN transceiver communicating via SPI it works fine.

///// LIBRARIES /////
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#include <SPI.h>
#include <mcp_can.h>
#include <FastLED.h>
#include <Adafruit_GPS.h>

///// DEFINE /////
//#define OLED_RESET 4  // OLED display reset pin
#define CAN0_CS 53  // CAN Bus Chip Select pin
#define CAN0_INT 18  // CAN Bus Interrupt pin

// GPS
#define GPSECHO  false        // do not send raw GPS data to serial monitor 

// OLED Screen 1
#define SCREEN_W 128 // OLED display width, in pixels
#define SCREEN_H 32 // OLED display height, in pixels
#define MOSI  51    // SPI Master Out Pin
#define CLK   52    // SPI Clock Pin
#define OLED_DC_1    6
#define OLED_CS_1  5
#define OLED_RST_1 7

// OLED Screen 2
//#define SCREEN_W_2 128 // both screens are the same size, use only one width definition
//#define SCREEN_H_2 32 // both screens are the same size, use only one height definition
#define OLED_DC_2  28
#define OLED_CS_2  29
#define OLED_RST_2 26

// LED Tach
// How many leds in your strip?
#define NUM_LEDS 32     // how many warning leds
#define WARN_LEDS 6     // how many warning LEDS on each side of midpoint (shift LEDS included)
#define SHIFT_LEDS 2    // how many shift light LEDS on each side of midpoint
#define TACH_DATA_PIN 22     // which pin sends data to LED tachometer

///// INITIALIZE /////
MCP_CAN CAN0(CAN0_CS);     // Set CS to pin 53
Adafruit_SSD1306 display1(SCREEN_W, SCREEN_H, MOSI, CLK, OLED_DC_1, OLED_RST_1, OLED_CS_1);
Adafruit_SSD1306 display2(SCREEN_W, SCREEN_H, MOSI, CLK, OLED_DC_2, OLED_RST_2, OLED_CS_2);
CRGB leds[NUM_LEDS];

Adafruit_GPS GPS(&Serial2);   // set serial2 to GPS object

///// GLOBAL VARIABLES /////

int splashTime = 1500; //how long should the splash screens show?

//Engine Parameters for Display
float oilPrs = 25;


///// SETUP LOOP //////////////////////////////////////////////////////////////////
void setup() {

  Serial.begin(115200); // open the serial port at 115200 bps:

  // Initialize LED Tach
  FastLED.addLeds<WS2812, TACH_DATA_PIN, GRB>(leds, NUM_LEDS);
  
  // Initialize displays
  display1.begin(SSD1306_SWITCHCAPVCC);  // initialize with SPI
  display2.begin(SSD1306_SWITCHCAPVCC);  // initialize with SPI
  dispSettings (&display1);
  delay(2000);  

  // // Initialize MCP2515 running at 8MHz with a baudrate of 500kb/s and the masks and filters disabled.
  // if(CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_8MHZ) == CAN_OK) Serial.println("MCP2515 Initialized Successfully!");
  // else Serial.println("Error Initializing MCP2515...");

  // // Set up CAN interrupt pin
  // pinMode(CAN0_INT, INPUT); 
  // CAN0.setMode(MCP_NORMAL);   // Change to normal mode to allow messages to be transmitted

  dispOilPrs(&display1);
  delay(2000);
  dispSettings (&display1);
  delay(2000);
  dispOilPrs(&display1);

}



///// MAIN LOOP //////////////////////////////////////////////////////////////////
void loop() {
}

///// SCREEN DRAWING FUNCTIONS /////
void dispSettings (Adafruit_SSD1306 *display) {
    display->setTextColor(WHITE); 
    display->clearDisplay();             //clear buffer
    display->setTextSize(3);             // text size
    display->setCursor(0,4);
    display->println("Settings");                 
    display->display();
}

void dispOilPrs (Adafruit_SSD1306 *display) {
    display->setTextColor(WHITE); 
    display->clearDisplay();             //clear buffer
    display->setTextSize(2);             // text size
    display->setCursor(1,1);
    display->println("Oil");        
    display->setCursor(1,18);
    display->println("Press");
    display->setTextSize(3); 
    display->setCursor(72,6);
    display->println(oilPrs, 0);         
    display->display();
}
1 Like

It looks like you're using a software SPI for the SSD1306s and the hardware SPI for the CAN controller. And they're both on the same pins. That's not going to work. Use the hardware SPI constructors for the SSD1306s:

Adafruit_SSD1306 displayX(SCREEN_W, SCREEN_W, &SPI, OLED_DC_x, OLED_RST_x OLED_CS_x);

1 Like

Thank you! I guess I didn't realize that I was using the software SPI constructor, changing to hardware worked a charm.

1 Like

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