Issue with Adafruit SSD1306 when uploading through PIO

I’m using an Adafruit SSD1306 128x64 OLED display with a Teensy 3.2 on a project I’m working on.

I’ve recently updated to version 1.3.0 of the Adafruit SSD1306 library in hopes that I will no longer have to modify the header within my projects for the library to work with the 128x64 OLED display. Unfortunately, the display does not do anything when code is uploaded with the PlatormIO plugin for VSCode. To make sure the display was working properly, I ran the Adafruit example program from the Arduino IDE, which works fine. However, if I copy the code into PIO and upload it there, nothing happens.

I imagine this is related to some library not being where it should / up to date or the recent update to PIO 4.0. Whatever the cause, I have no idea why this is happening and would appreciate any help. Thanks!

It’s possible that SSD1306 library is not properly linked with your application, try to add the next line to your platformio.ini:

lib_archive = no
1 Like

Unfortunately, that didn’t seem to work.

Can you share your build log here?

I’m pretty sure this is the build log. I just copied the Adafruit demo program into PIO.

> Executing task: C:\Users\Andrew\.platformio\penv\Scripts\platformio.exe run --target upload <

Processing teensy31 (platform: teensy; board: teensy31; framework: arduino)
----------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/teensy/teensy31.html
PLATFORM: Teensy 4.3.0 > Teensy 3.1 / 3.2
HARDWARE: MK20DX256 72MHz, 64KB RAM, 256KB Flash
DEBUG: Current (jlink) External (jlink)
PACKAGES: framework-arduinoteensy 1.145.0 (1.45), tool-teensy 1.145.0 (1.45), toolchain-gccarmnoneeabi 1.50401.0 (5.4.1)
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 95 compatible libraries
Scanning dependencies...
Dependency Graph
|-- <Adafruit SSD1306> 1.3.0
|   |-- <Adafruit GFX Library> 1.5.6
|   |   |-- <SPI> 1.0
|   |-- <Wire> 1.0
|   |-- <SPI> 1.0
|-- <Adafruit GFX Library> 1.5.6
|   |-- <SPI> 1.0
|-- <SPI> 1.0
|-- <Wire> 1.0
Linking .pio\build\teensy31\firmware.elf
Checking size .pio\build\teensy31\firmware.elf
Building .pio\build\teensy31\firmware.hex
Memory Usage -> http://bit.ly/pio-memory-usage
DATA:    [=         ]   5.9% (used 3852 bytes from 65536 bytes)
PROGRAM: [=         ]  13.2% (used 34584 bytes from 262144 bytes)
Configuring upload protocol...
AVAILABLE: jlink, teensy-cli, teensy-gui
CURRENT: upload_protocol = teensy-gui
Uploading .pio\build\teensy31\firmware.hex
===================================================================== [SUCCESS] Took 3.10 seconds =====================================================================

Terminal will be reused by tasks, press any key to close it.
1 Like

I’ve replicated your setup (Teensy 3.2, Adafruit 1.3" 128x64 OLED display, connected via SPI) and can successfully run it with the code below:

platformio.ini

[env:teensy31]
platform = teensy
board = teensy31
framework = arduino

lib_deps =
    Adafruit SSD1306@1.3.0
    Adafruit GFX Library@1.5.6

main.cpp

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

#define OLED_MOSI  11
#define OLED_CLK   13
#define OLED_DC    6
#define OLED_CS    10
#define OLED_RESET 5

Adafruit_SSD1306 display(128, 64, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

void setup() {
    Serial.begin(9600);

    if (!display.begin(SSD1306_SWITCHCAPVCC)) {
        Serial.println("SSD1306 allocation failed");
        for(;;);
    }

    display.display();
}

void loop() {
}

When run, the display shows the Adafruit logo.

The Arduino Teensy framework comes with its own version of the Adafruit SSD1306 library. But if specified as above, PlatformIO picks the latest one from Adafruit.

2 Likes

Thanks! However, I think I forgot to mention that I am running the SSD1306 display using I2C, not SPI. I tried adding the library versions to my platformio.ini , however it the screen still does not display.

OLED display with I2C is in stock as well. The below code works and displays the Adafruit logo:

#include <Arduino.h>
#include <Adafruit_SSD1306.h>

// SDA pin 18
// SCL pin 19

#define DISPLAY_ADDRESS 0x3C

Adafruit_SSD1306 display(128, 64);

void setup() {
    Serial.begin(9600);

    if (!display.begin(SSD1306_SWITCHCAPVCC, DISPLAY_ADDRESS)) {
        Serial.println("SSD1306 allocation failed");
        for(;;);
    }

    display.display();
}

void loop() {
}

Note that the logic for deriving the I2C address didn’t work in my case. It’s 0x3C but the library uses 0x3D for all displays with a height other than 32 pixels.

2 Likes

I really appreciate your help, but unfortunately the display still isn’t working from the PIO IDE in VSCode. I’ve included all my code from the Arduino IDE and PIO. The only difference I can see initially is that I am using pin 5 for Reset, but it still works from the Arduino IDE if I disable that (it fails on a power cycle, but initial upload is fine). I have tried both addresses, 0x3C and 0x3D from both IDEs. Arduino only works with 0x3D, which makes sense, however PIO still won’t worth with either.

Arduino:

#include <Adafruit_SSD1306.h>

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     5 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(128, 64, &Wire, OLED_RESET);

void setup() {
  Serial.begin(9600);

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3D)) { // Address 0x3D for 128x64
    Serial.println("SSD1306 allocation failed");
    for(;;); // Don't proceed, loop forever
  }

  // Show initial display buffer contents on the screen --
  display.display();
  delay(2000); // Pause for 2 seconds

  display.clearDisplay();
  display.drawPixel(10, 10, WHITE);
  display.display();
}

void loop() { Serial.println(":)"); }

PlatformIO

#include <Arduino.h>
#include <Adafruit_SSD1306.h>

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     5 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(128, 64, &Wire, OLED_RESET);

void setup() {
  Serial.begin(9600);

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3D)) { // Address 0x3D for 128x64
    Serial.println("SSD1306 allocation failed");
    for(;;); // Don't proceed, loop forever
  }

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();

  // Clear the buffer
  display.clearDisplay();
  display.drawPixel(10, 10, WHITE);
  display.display();

}

void loop() { Serial.println(":)"); }

platformio.ini

[env:teensy31]
platform = teensy
board = teensy31
framework = arduino
lib_archive = no
lib_deps = 
    Adafruit SSD1306@1.3.0
    Adafruit GFX Library@1.5.6

I’ve been struggling with this exact problem for 3 long weeks now. Put a delay(100) after Serial.begin(9600); and before if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C);.

I discovered this little fix by Using a scanner() to poll all I2C addresses and did one before and after display.begin(). and only the second one returned the address 0x3C is available.

Thinking about it, this screen uses an RC Timer to send a reset signal to the OLED. So in order for the screen to initialized the reset pulse must finish