SPI and I2C Clash?

Processing: GPS_PIM525_1708_CASE_01_GPS_WORKS_TXT...
GPS_PIM525_1708_CASE_01_GPS_WORKS.ino (2.4 KB)
GPS_PIM525_1708_CASE_01_SSD_WORKS.ino (2.4 KB)

Hi Folks,
Trying to integrate an SSD1306 display SPI and a Pimoroni PIM525 I2C GPS module. in the case of the code that will run the GPS with all instructions included except the display code from the loop GPS works. Conversely when Adafruit_GPS GPS(&Wire) is included in the SSD code both stop working. How does one resolve h/ware clashes in the Arduino?

Connecting of the 5 SSD Pins to the SPI defaults or for example A0-A4 makes little difference to the behavior in either case

Did you forget to post a question ?

How about below :wink:

@kuizatz, your topic has been moved to a more suitable location on the forum. Installation and Troubleshooting is not for problems with your project :wink: See About the Installation & Troubleshooting category.

Please post your code in a post ( and don't forget the code tags :wink: ) instead of attaching it. You're now missing out on knowledgeable people who are using cell phones.

Added in one of the 3 edits ?

The original post was just;

Processing: GPS_PIM525_1708_CASE_01_GPS_WORKS_TXT...
GPS_PIM525_1708_CASE_01_GPS_WORKS.ino (2.4 KB)
GPS_PIM525_1708_CASE_01_SSD_WORKS.ino (2.4 KB)

1 Like

What hardware are you running this on? I believe that the SSD1306 graphics library takes up a lot of RAM. Are you running out of RAM? Did the IDE give you a warning message about memory usage?

1 Like

Apologies.

Will clean up the post an insert eh natice code later today. Usage, in both 44 & 51 % respectivily. Running on an UNO, but behalves the sames on on NANO 33 BLE or a staright NANO. Clearly one is owerwriting the other. I can see that the I2C device is at 10H via a scan, however to date havenet located some good information of manageing the memoery location for SPI, or fiding where it is fopr that matter....

AFAIK, most (All?) Arduino-like board take care to provide SPI and I2C interfaces that do not conflict with each other - there shouldn't be a "hardware clash" (except perhaps "interrupt" pins?), and you should probably look elsewhere for the source of your problems.

Thanks, clearly posting challenged, posted in a rush. OK on the code tags will use them from here

Is there some reason you have two display.begin() calls?

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

I would get rid of the delays and use millis timing instead:

  display.setCursor(0, 22), display.print(F("Aug-21 - Ver:")), display.print(v);
  display.setCursor(0, 34), display.print(F("    Post: #: ")), display.println(tp);
  display.display();
  delay(1000);
  display.clearDisplay();
  display.display();
  delay(1000);

It is HIGHLY likely that having a two second delay between each character is not going to work properly for the GPS module.

Running on an UNO, however the same behaviour demonstrated on a NANO 33 BLE as well.

In the case of the GPS it works well with SSD code commented out, conversely the GPS code operates fine with the SSD code commented out.

When compiled with all code uncommented out the code uses 53% of the program space available. Individually GPS uses 43% and SSD uses 51%.

An I2c scan confirms the 0x10 addr for the GPS module which is from Pimoroni PIM525.

Below are the two sets that do work as they are. The GPS example below and the SSD below that.

Hopefully this is a touch clearer...Cheers

/* 
   GPS_PIM525_1708_CASE_01_GPS_WORKS
   GPS data flows well when only, SSD begin test & display cmnds from loop commented out.
   Including or not SPI.h or Wire.h makes no difference in any case
*/

#include <Adafruit_GPS.h>
//#include <SPI.h>             // No difference in or out
//#include <Wire.h>            // I2C needs it? no difference in or out
//#include <Adafruit_GFX.h>    // Not be needed for basic txt
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Run dsiplay on most convi
#define OLED_CLK   8
#define OLED_MOSI  9
#define OLED_RESET 10
#define OLED_DC    11
#define OLED_CS    12
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

// Dummy vars for loop
float v = 1708;     // Version
float t = 15.27;   // Temp
float h = 87.81;   // Humidity
int   tp = 0;      // Total Posts

// ********************  Connect to the GPS on the hardware I2C port **********************
Adafruit_GPS GPS(&Wire);
// ********************  Connect to the GPS on the hardware I2C port **********************

void setup() {
  // ********************  GPS Begin ********************************************************
  GPS.begin(0x10);  // The I2C address to use is 0x10
  // ********************  GPS Begin ********************************************************

  Serial.begin(115200);
  Serial.println("Adafruit GPS library basic I2C test!");
  display.begin(SSD1306_SWITCHCAPVCC);
  //  if(!display.begin(SSD1306_SWITCHCAPVCC)) {
  //  Serial.println(F("SSD1306 allocation failed"));
  //  for(;;); // Don't proceed, loop forever
  //  }
  display.display();
  delay(1000);
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
}

void loop() {
  if (Serial.available()) {
    char c = Serial.read();
    GPS.write(c);
  }
  if (GPS.available()) {
    char c = GPS.read();
    //    Serial.write(c);
    Serial.print(c);
  }

  //  display.setCursor(0, 22), display.print(F("Aug-21 - Ver:")), display.print(v);
  //  display.setCursor(0, 34), display.print(F("    Post: #: ")), display.println(tp);
  //  display.display();
  //  delay(1000);
  //  display.clearDisplay();
  //  display.display();
  //  delay(1000);
  //  tp=tp+1;

}

/* 
   GPS_PIM525_1708_CASE_01_SSD_WORKS
   SSD works, so long as "Adafruit_GPS GPS(&Wire);" & "GPS.begin(0x10);" commented out. GPS.r/w 
   calls in loop disabled as well
   Including or not SPI.h or Wire.h makes no difference in any case
*/

#include <Adafruit_GPS.h>
//#include <SPI.h>             // No difference in or out
//#include <Wire.h>            // I2C needs it? no difference ion or out
//#include <Adafruit_GFX.h>    // Not be needed for basic txt
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Run dsiplay on most convi
#define OLED_CLK   8
#define OLED_MOSI  9
#define OLED_RESET 10
#define OLED_DC    11
#define OLED_CS    12
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

// Dummy vars for loop
float v = 1708;     // Version
float t = 15.27;   // Temp
float h = 87.81;   // Humidity
int   tp = 0;      // Total Posts

// ********************  Connect to the GPS on the hardware I2C port **********************
//Adafruit_GPS GPS(&Wire);
// ********************  Connect to the GPS on the hardware I2C port **********************

void setup() {
  // ********************  GPS Begin ********************************************************
  //GPS.begin(0x10);  // The I2C address to use is 0x10
  // ********************  GPS Begin ********************************************************

  Serial.begin(115200);
  Serial.println("Adafruit GPS library basic I2C test!");
  display.begin(SSD1306_SWITCHCAPVCC);
  if (!display.begin(SSD1306_SWITCHCAPVCC)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;); // Don't proceed, loop forever
  }
  display.display();
  delay(1000);
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
}

void loop() {
  //  if (Serial.available()) {
  //    char c = Serial.read();
  //    GPS.write(c);
  //  }
  //  if (GPS.available()) {
  //    char c = GPS.read();
  ////    Serial.write(c);
  //    Serial.print(c);
  //  }

  display.setCursor(0, 22), display.print(F("Aug-21 - Ver:")), display.print(v);
  display.setCursor(0, 34), display.print(F("    Post: #: ")), display.println(tp);
  display.display();
  delay(1000);
  display.clearDisplay();
  display.display();
  delay(1000);
  tp = tp + 1;

}

Thanks for the response. Initially I had only the single display.begin, however trying to debug I added the if !display.begin as I wanted to see if the board manages to report that the allocation did or didnt work. OK on the millis thanks will look at that, and noted the delays.

With all the code compiled, irrespective of the delays, if I include one display cmd in the loop, the GPS will stop and the SSD will fail on allocation....fun :slight_smile:

If you leave all display commands out of loop, are you able to print to the display in setup?

Seems odd that just including any display command in loop will cause display.begin to fail. On the UNO/Nano I would think you are running out of ram, but the Nano 33 BLE would not have that problem.

Have you tried using the u8g2 library with a page buffer, or the u8x8 library if you only need text?

As soon as I include the "Adafruit_GPS GPS(&Wire);" the error "SSD1306 Allocation failed" reports.

If I comment out the display cmds in loop and simply use "display.begin(SSD1306_SWITCHCAPVCC);" in the setup, the GPS will work, however the SSD allocation clearly fails as the SSD1306 will not display the ADA banner, however the GPS data flows nicely.

Thnx I will get a look at u8g2 & u8x8...

I'm fairly sure you are running out of ram on the UNO/Nano, a 128 x 64 display takes 1024 bytes of ram for the buffer.

OK thanks for the response. That to me (arduino newbee) sounds more plausible than anything else I can think of. The Arduino UNO has 32K bytes of Flash memory and 2K bytes of SRAM, when compiled the IDE says 53% of prog space used, so I need to understand more about that generally. I have a MEGA 256 so I will run it up on that to see the result.

Solved all works fine on a MEGA256. Clearly a RAM issue. Are you aware of any tools that can be used to debug Arduino IDE as it appears to not have "any" ?

Do not be too concerned about the percentage of program (flash) memory used, that is a fixed amount that will not change when the code is running. Anything up to 100% is fine, and the compiler will generate an error if you exceed 100%.

The SRAM (dynamic memory) percentage is what is important, and in this case is misleading because the compiler only shows the percentage of SRAM needed by global variables. The Adafruit SSD1306 library needs memory for a display buffer, but this is allocated at runtime, not as a global variable, so is not included in the percentage the compiler reports. For a 128 x 64 display, the buffer needs (128 x 64 bits ) / (8 bits per byte) = 1024 bytes of memory, 50% of the UNO's SRAM.

Thanks very much for the clarification, very helpful.