Micro OLED displaying garbled pixels when trying to get example to run

I’m using a ESP32 Thing Plus-S3 and a Qwiic connector to get the Micro OLED breakout working. However, when I tried running the example sketch, the following displays.

I thought at first it was the random pixel function but after realizing nothing else was happening I commented it out and nothing changed. Then I stripped down the example code to just one example and it still shows the same; here’s the code for that.


#include <Wire.h>
#include <SFE_MicroOLED.h> 
#define PIN_RESET 4


MicroOLED oled(PIN_RESET); 

void setup()
{
  delay(100);
  Wire.begin(8, 9); 

  oled.begin(0x3D, Wire);    
  oled.clear(ALL); 
  oled.display();  

  delay(1000); 

  oled.clear(PAGE); 

}


void lineExample()
{
  int middleX = oled.getLCDWidth() / 2;
  int middleY = oled.getLCDHeight() / 2;
  int xEnd, yEnd;
  int lineWidth = min(middleX, middleY);

  printTitle("Lines!", 1);

  for (int i = 0; i < 3; i++)
  {
    for (int deg = 0; deg < 360; deg += 15)
    {
      xEnd = lineWidth * cos(deg * PI / 180.0);
      yEnd = lineWidth * sin(deg * PI / 180.0);

      oled.line(middleX, middleY, middleX + xEnd, middleY + yEnd);
      oled.display();
      delay(10);
    }
    for (int deg = 0; deg < 360; deg += 15)
    {
      xEnd = lineWidth * cos(deg * PI / 180.0);
      yEnd = lineWidth * sin(deg * PI / 180.0);

      oled.line(middleX, middleY, middleX + xEnd, middleY + yEnd, BLACK, NORM);
      oled.display();
      delay(10);
    }
  }
}


void loop()
{
  lineExample();  // Then the line example function


}


void printTitle(String title, int font)
{
  int middleX = oled.getLCDWidth() / 2;
  int middleY = oled.getLCDHeight() / 2;

  oled.clear(PAGE);
  oled.setFontType(font);
  // Try to set the cursor in the middle of the screen
  oled.setCursor(middleX - (oled.getFontWidth() * (title.length() / 2)),
                 middleY - (oled.getFontHeight() / 2));
  // Print the title:
  oled.print(title);
  oled.display();
  delay(1500);
  oled.clear(PAGE);
}

The random garbled pattern isn’t constant, sometimes it changes when I upload different code to the board.
Here’s what else I tried so far

  • Different Qwiic Cables (only have two, so maybe two are busted)
  • Did an I2C scan and got the address as 0x3D
  • Different USB cables, different ports
  • Basic sketch to just say hello, didn’t work

This is the first time I’m using an ESP32 and the Qwiic stuff so maybe there’s something simple I’m overlooking but I’ll appreciate any help.

The last thing you might try is disabling the pull-up resistors (you’d just de-solder that blob labeled “PU” and re-test)

If that doesn’t get it going, it is likely a defective module - Was it purchased from us? If so head over to Returns (contact vendor if purchased elsewhere) and we’ll get ya squared away

1 Like

Just commenting if anyone else runs into this problem - I haven’t desoldered and tested but I don’t necessarily need a screen for my project so I do plan to return it.

I did de-solder the jumper and tried. Still did not work. The Micro OLED works with an Uno red board. The ESP32 Thing Plus works with a 6dof board and does communicate with the Micro OLED. It response to the getLCDWidth() command. I have used multiple OLEDs and ESP32 Thing Plus boards. I am still at a loss.

What (if any) response/activity do you see on the screen? Does the OLED appear on i2c scan?

Thank you for getting back with me. My code looks like this;

void setup()
{
Serial.begin(115200);
Serial.println(“Running OLED example”);
delay(100); //Give display time to power on
Wire.begin(); //Setup I2C bus
Wire.setClock(400000); // Uncomment this line to increase the I2C bus speed to 400kHz

// Initalize the OLED device and related graphics system
if (oled.begin() == false) {
Serial.println(“Device begin failed. Freezing…”);
while (true)
;
}
Serial.println(“Begin success”);

width = oled.getLCDWidth();
height = oled.getLCDHeight();
Serial.print("width = ");
Serial.println(width);
Serial.print("height = ");
Serial.println(height);

// clear(ALL) will clear out the OLED’s graphic memory.
// clear(PAGE) will clear the Arduino’s display buffer.
oled.clear(ALL); // Clear the display’s memory (gets rid of artifacts)
// To actually draw anything on the display, you must call the
// display() function.
oled.display();

}
My serial response looks like this;


ets Jul 29 2019 12:21:46


rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)


configsip: 0, SPIWP:0xee


clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00


mode:DIO, clock div:1


load:0x3fff0030,len:4744


load:0x40078000,len:15672


load:0x40080400,len:3152


entry 0x4008059c


Running OLED example


Begin success


width = 64


height = 48

and the OLED looks like this;

Looks like a defective unit - Was it purchased from us? If so head over to Return Policy - SparkFun Electronics (contact vendor if purchased elsewhere) and we’ll get ya squared away

Two different OLED displays are working the same way on two different ESP32 boards. I switched both OLEDs to an Uno board and they both work just fine.

Ah - in that case it’s likely something going on with the i2c bus. Can you try a different i2c Hz in your code?

I will try that. The ESP 32 does work with other i2c devices. FYI

I did change the i2c clock from 400kHz back to 100kHz and then to 200kHz. No change.
I do have an Adafruit 9-DOF Absolute Orientation IMU Fusion Breakout that does work with the ESP32.
I do have a functioning sketch that runs both the 9-DOF board and the OLED from the Uno.
The sketch works on the ESP32, the OLED just does not display correctly with the ESP32.

#include <SFE_MicroOLED.h>

Could it be that the sketch is not being assembled and transferred to the ESP32 correctly?
If so, how do we correct it and why does the 9-DOF board still work?

Thanks again for your help
Tom

Gotcha.

I’m going to locate a couple of my esp32’s and OLEDs and run some tests to see if I get the same thing

Any success yet or are you seeing the same thing as I have?
Thanks for looking into this.

I had to wait on them to arrive but should be able to test later today and update this thread when :slight_smile:

Just wondering how it is going?
I have been preoccupied with other things but I still need to get the ESP thing plus working with the Micro OLED.
I got the OLED working with a Thing plus Artimis but not the Adafruit 9-DoF Accel+Gyro+Mag (BNO055).
Looking forward to the solution.

I got an S3 but I can’t find it for the life of me (getting ready to move!)

But after perusing this again, I think it might be worth declaring the micro oled address specifically in code….use this as a scaffold (you’ll need to add the first few white declarations)

Also, just to be sure: what board do you have selected for uploading in the IDE?

/*
SFE_MicroOLED Library Demo
Paul Clark @ SparkFun Electronics
Original Creation Date: December 11th, 2020

This sketch uses the MicroOLED library to show all the functionality built into the library
using the begin function defined in version v1.3 of the library - which allows different
TwoWire ports and custom I2C addresses to be used.

If you are using the standard Micro OLED display, its I2C address will be 0x3D or 0x3C
depending on how you have the D/C or ADDR jumper configured.

Hardware Connections:
This example assumes you are using Qwiic. See the SPI examples for
a detailed breakdown of connection info.

#include <Wire.h>
#include <SFE_MicroOLED.h> //Click here to get the library: http://librarymanager/All#SparkFun_Micro_OLED

#define PIN_RESET 4

/*
// This is the old way of instantiating oled. You can still do it this way if you want to.
#define DC_JUMPER 1
MicroOLED oled(PIN_RESET, DC_JUMPER); // I2C declaration
*/

// From version v1.3, we can also instantiate oled like this (but only for I2C)
MicroOLED oled(PIN_RESET); // The TwoWire I2C port is passed to .begin instead

void setup()
{
delay(100);
Wire.begin(); // ← Change this to (e.g.) Qwiic.begin(); as required
//Wire.setClock(400000); // Uncomment this line to increase the I2C bus speed to 400kHz

/*
// This is the old way of initializing the OLED.
// You can still do it this way if you want to - but only
// if you instantiated oled using: MicroOLED oled(PIN_RESET, DC_JUMPER)
oled.begin();    // Initialize the OLED
*/

// This is the new way of initializing the OLED.
// We can pass a different I2C address and TwoWire port
oled.begin(0x3D, Wire);    // Initialize the OLED

/*
// This is the new way of initializing the OLED.
// We can pass a different I2C address and TwoWire port
oled.begin(0x3C, Qwiic);    // Initialize the OLED
*/

oled.clear(ALL); // Clear the display’s internal memory
oled.display();  // Display what’s in the buffer (splashscreen)

delay(1000); // Delay 1000 ms

oled.clear(PAGE); // Clear the buffer.

randomSeed(analogRead(A0) + analogRead(A3));
}

void pixelExample()
{
printTitle(“Pixels”, 1);

for (int i = 0; i < 512; i++)
{
oled.pixel(random(oled.getLCDWidth()), random(oled.getLCDHeight()));
oled.display();
}
}

void lineExample()
{
int middleX = oled.getLCDWidth() / 2;
int middleY = oled.getLCDHeight() / 2;
int xEnd, yEnd;
int lineWidth = min(middleX, middleY);

printTitle(“Lines!”, 1);

for (int i = 0; i < 3; i++)
{
for (int deg = 0; deg < 360; deg += 15)
{
xEnd = lineWidth * cos(deg * PI / 180.0);
yEnd = lineWidth * sin(deg * PI / 180.0);

  oled.line(middleX, middleY, middleX + xEnd, middleY + yEnd);
  oled.display();
  delay(10);
}
for (int deg = 0; deg < 360; deg += 15)
{
  xEnd = lineWidth * cos(deg * PI / 180.0);
  yEnd = lineWidth * sin(deg * PI / 180.0);

  oled.line(middleX, middleY, middleX + xEnd, middleY + yEnd, BLACK, NORM);
  oled.display();
  delay(10);
}

}
}

void shapeExample()
{
printTitle(“Shapes!”, 0);

// Silly pong demo. It takes a lot of work to fake pong…
int paddleW = 3;  // Paddle width
int paddleH = 15; // Paddle height
// Paddle 0 (left) position coordinates
int paddle0_Y = (oled.getLCDHeight() / 2) - (paddleH / 2);
int paddle0_X = 2;
// Paddle 1 (right) position coordinates
int paddle1_Y = (oled.getLCDHeight() / 2) - (paddleH / 2);
int paddle1_X = oled.getLCDWidth() - 3 - paddleW;
int ball_rad = 2; // Ball radius
// Ball position coordinates
int ball_X = paddle0_X + paddleW + ball_rad;
int ball_Y = random(1 + ball_rad, oled.getLCDHeight() - ball_rad); //paddle0_Y + ball_rad;
int ballVelocityX = 1;                                             // Ball left/right velocity
int ballVelocityY = 1;                                             // Ball up/down velocity
int paddle0Velocity = -1;                                          // Paddle 0 velocity
int paddle1Velocity = 1;                                           // Paddle 1 velocity

//while(ball_X >= paddle0_X + paddleW - 1)
while ((ball_X - ball_rad > 1) &&
(ball_X + ball_rad < oled.getLCDWidth() - 2))
{
// Increment ball’s position
ball_X += ballVelocityX;
ball_Y += ballVelocityY;
// Check if the ball is colliding with the left paddle
if (ball_X - ball_rad < paddle0_X + paddleW)
{
// Check if ball is within paddle’s height
if ((ball_Y > paddle0_Y) && (ball_Y < paddle0_Y + paddleH))
{
ball_X++;                       // Move ball over one to the right
ballVelocityX = -ballVelocityX; // Change velocity
}
}
// Check if the ball hit the right paddle
if (ball_X + ball_rad > paddle1_X)
{
// Check if ball is within paddle’s height
if ((ball_Y > paddle1_Y) && (ball_Y < paddle1_Y + paddleH))
{
ball_X–;                       // Move ball over one to the left
ballVelocityX = -ballVelocityX; // change velocity
}
}
// Check if the ball hit the top or bottom
if ((ball_Y <= ball_rad) || (ball_Y >= (oled.getLCDHeight() - ball_rad - 1)))
{
// Change up/down velocity direction
ballVelocityY = -ballVelocityY;
}
// Move the paddles up and down
paddle0_Y += paddle0Velocity;
paddle1_Y += paddle1Velocity;
// Change paddle 0’s direction if it hit top/bottom
if ((paddle0_Y <= 1) || (paddle0_Y > oled.getLCDHeight() - 2 - paddleH))
{
paddle0Velocity = -paddle0Velocity;
}
// Change paddle 1’s direction if it hit top/bottom
if ((paddle1_Y <= 1) || (paddle1_Y > oled.getLCDHeight() - 2 - paddleH))
{
paddle1Velocity = -paddle1Velocity;
}

// Draw the Pong Field
oled.clear(PAGE); // Clear the page
// Draw an outline of the screen:
oled.rect(0, 0, oled.getLCDWidth() - 1, oled.getLCDHeight());
// Draw the center line
oled.rectFill(oled.getLCDWidth() / 2 - 1, 0, 2, oled.getLCDHeight());
// Draw the Paddles:
oled.rectFill(paddle0_X, paddle0_Y, paddleW, paddleH);
oled.rectFill(paddle1_X, paddle1_Y, paddleW, paddleH);
// Draw the ball:
oled.circle(ball_X, ball_Y, ball_rad);
// Actually draw everything on the screen:
oled.display();
delay(25); // Delay for visibility

}
delay(1000);
}

void textExamples()
{
printTitle(“Text!”, 1);

// Demonstrate font 0. 5x8 font
oled.clear(PAGE);     // Clear the screen
oled.setFontType(0);  // Set font to type 0
oled.setCursor(0, 0); // Set cursor to top-left
// There are 255 possible characters in the font 0 type.
// Lets run through all of them and print them out!
for (int i = 0; i <= 255; i++)
{
// You can write byte values and they’ll be mapped to
// their ASCII equivalent character.
oled.write(i);  // Write a byte out as a character
oled.display(); // Draw on the screen
delay(10);      // Wait 10ms
// We can only display 60 font 0 characters at a time.
// Every 60 characters, pause for a moment. Then clear
// the page and start over.
if ((i % 60 == 0) && (i != 0))
{
delay(500);           // Delay 500 ms
oled.clear(PAGE);     // Clear the page
oled.setCursor(0, 0); // Set cursor to top-left
}
}
delay(500); // Wait 500ms before next example

// Demonstrate font 1. 8x16. Let’s use the print function
// to display every character defined in this font.
oled.setFontType(1);  // Set font to type 1
oled.clear(PAGE);     // Clear the page
oled.setCursor(0, 0); // Set cursor to top-left
// Print can be used to print a string to the screen:
oled.print(" !"#$%&'()*+,-./01234");
oled.display(); // Refresh the display
delay(1000);    // Delay a second and repeat
oled.clear(PAGE);
oled.setCursor(0, 0);
oled.print(“56789:;<=>?@ABCDEFGHI”);
oled.display();
delay(1000);
oled.clear(PAGE);
oled.setCursor(0, 0);
oled.print(“JKLMNOPQRSTUVWXYZ[\]^”);
oled.display();
delay(1000);
oled.clear(PAGE);
oled.setCursor(0, 0);
oled.print(“_`abcdefghijklmnopqrs”);
oled.display();
delay(1000);
oled.clear(PAGE);
oled.setCursor(0, 0);
oled.print(“tuvwxyz{|}~”);
oled.display();
delay(1000);

// Demonstrate font 2. 10x16. Only numbers and ‘.’ are defined.
// This font looks like 7-segment displays.
// Lets use this big-ish font to display readings from the
// analog pins.
for (int i = 0; i < 25; i++)
{
oled.clear(PAGE);           // Clear the display
oled.setCursor(0, 0);       // Set cursor to top-left
oled.setFontType(0);        // Smallest font
oled.print("A0: ");         // Print “A0”
oled.setFontType(2);        // 7-segment font
oled.print(analogRead(A0)); // Print a0 reading
oled.setCursor(0, 16);      // Set cursor to top-middle-left
oled.setFontType(0);        // Repeat
oled.print("A3: ");
oled.setFontType(2);
oled.print(analogRead(A3));
oled.setCursor(0, 32);
oled.setFontType(0);
oled.print("A6: ");
oled.setFontType(2);
oled.print(analogRead(A6));
oled.display();
delay(100);
}

// Demonstrate font 3. 12x48. Stopwatch demo.
oled.setFontType(3); // Use the biggest font
int ms = 0;
int s = 0;
while (s <= 5)
{
oled.clear(PAGE);     // Clear the display
oled.setCursor(0, 0); // Set cursor to top-left
if (s < 10)
oled.print(“00”); // Print “00” if s is 1 digit
else if (s < 100)
oled.print(“0”); // Print “0” if s is 2 digits
oled.print(s);     // Print s’s value
oled.print(“:”);   // Print “:”
oled.print(ms);    // Print ms value
oled.display();    // Draw on the screen
ms++;              // Increment ms
if (ms >= 10)      // If ms is >= 10
{
ms = 0; // Set ms back to 0
s++;    // and increment s
}
}
}

void loop()
{
pixelExample();  // Run the pixel example function
lineExample();  // Then the line example function
shapeExample(); // Then the shape example
textExamples(); // Finally the text example
}

// Center and print a small title
// This function is quick and dirty. Only works for titles one
// line long.
void printTitle(String title, int font)
{
int middleX = oled.getLCDWidth() / 2;
int middleY = oled.getLCDHeight() / 2;

oled.clear(PAGE);
oled.setFontType(font);
// Try to set the cursor in the middle of the screen
oled.setCursor(middleX - (oled.getFontWidth() * (title.length() / 2)),
middleY - (oled.getFontHeight() / 2));
// Print the title:
oled.print(title);
oled.display();
delay(1500);
oled.clear(PAGE);
}

The board I am using is the SparkFun ESP32 Thing Plus.
I tried copying the code below but it has multiple Compilation errors. I looks very similar to the
Examples from Custom Libraries/SparkFun Micro OLED Breakout/Example3_MultiDemo
I am getting some response with this Demo, see enclosed Pictures (I tried to send a video but it was to large).

(attachments)




It worked fine on my regular Thing Plus - still haven’t re-found the S3 :-/
I can have my boss try an S3 as well and see how that goes (I’m also going to test with the usb-c thing plus because I have one of those too)

UPDATE
The usb-c version is garbled like your unit, I am testing/fiddling with code now…

Ok, I got the usb-c one to work as well simply by updating the “Sparkfun qwiic OLED library” to 1.0.13 and running the examples from ‘Sparkfun Qwiic OLED graphics library’

Hi Tom (@tgoodman ),

Please forgive me for asking the dumb questions, but have you checked that you have installed “esp32” / “ESP32 Arduino” board package by “Espressif Systems” and have selected the “SparkFun ESP32-S3 Thing Plus” as the board? The “-S3” is important. You will get very strange results if you have selected a different board.

I hope this helps,
Paul