Recalcitrant SH1106 OLED [Solved: SCK & MOSI were swapped]

always as like it’s connected to GND or configured as low immadiately on setup? also is it made active low before or after the SPI configuration? (can imagine a floating GPIO pin causing a false clock pulse causing everything to shift out of sync)

Here’s some bitbanging test sketch that ‘blinks’ all oled pixels on and off (ram content)
just change the pin numbers accordingly

#define OLED_CS   12
#define OLED_DC   4
#define OLED_RST  6
#define OLED_SCK  15
#define OLED_SDA  16

const uint8_t PROGMEM lcdBootProgram[] =
  0x8D, 0x14,                   // Charge Pump Setting v = enable (0x14)
  0xA1,                         // Set Segment Re-map
  0xC8,                         // Set COM Output Scan Direction
  0x81, 0xCF,                   // Set Contrast v = 0xCF
  0xD9, 0xF1,                   // Set Precharge = 0xF1
  0x02,                         // Set column address for left most pixel 
  0xAF,                          // Display On

void SPItransfer(uint8_t b)
  for (uint8_t i = 128; i != 0; i >>= 1)
    // shift bits out
    if (b & i)
    //clock bit
    delayMicroseconds(1); // digitalWrite is slow already but just incase
    digitalWrite(OLED_SCK, HIGH);

void bootOLED()
  for (uint8_t i = 0; i < sizeof(lcdBootProgram); i++)
    SPItransfer(pgm_read_byte(lcdBootProgram + i));

void setup() {
#if (__AVR_DEVICE_NAME__ == atmega32u4)
 SPCR = 0; //disable SPI mode from Arduboy bootloader menu
 digitalWrite(OLED_RST, LOW); // keep display in reset
 pinMode(OLED_CS, OUTPUT);
 digitalWrite(OLED_CS, HIGH); // inactive
 pinMode(OLED_DC, OUTPUT);
 digitalWrite(OLED_DC, LOW); // command mode
 digitalWrite(OLED_SCK, LOW);
 digitalWrite(OLED_SDA, LOW);
 digitalWrite(OLED_RST, HIGH); // release reset
 digitalWrite(OLED_CS, LOW); // active

void loop() {
  SPItransfer(0xA5); // all pixels on
  SPItransfer(0xA4); // all pixels from RAM

Fun fact: I didn’t get an F-ing thing on my SH1106 screen too at first. Then I realized the bootloader menu configured hardware SPI which I had to turn off (SPCR = 0) for bitbanging the SPI pins :stuck_out_tongue:

1 Like

Go Arduboy!


So, massive thanks to @Mr.Blinky for that test code. It was just lovely to have some code that was “known” working for the SH1106. I hooked the OLED module up to the Arduino M0 and it worked, after I commented out the conditional SPI disable for ATMEGA32U which for some reason was upsetting the preprocessor/compiler. It did not work on GAMOO, connected to the OLED module.

I looked into the SPI disable for the SAMD21 and it depends on which SERCOM your SPI port is configured to, so here are your options. Interestingly, the Sparkfun SAMD21 board that I think @MLXXXp’s version was based on uses SPI pads on SERCOM1 but they end up mapping to the ATMEGA328P-based Arduino pins of D10,11,12,13 for CS/SS, MISO, MOSI, SCK. The Arduino M0 uses SERCOM4 and can only be accessed via the ISCP header. Here’s the code to disable SPI on your SAMD21. Obviously change the SERCOM number to match what’s specified in your Arduino variant.h hardware file.

//Disable SPI 1

So my failure to drive the OLED module from GAMOO, in the end, came down to wrong mapping of jumper wires across the 0.1" headers. RST and CS are perhaps the worst two to mix up, which is what I did. When you want to talk to the chip, you are turning it off…

Once rectified, I have the OLED module working with GAMOO, using the u8g2 demo to ensure graphics and text appear as intended. This indicates that my previous failures were to do with how my bare OLED is wired up on the GAMOO, which must be different to how the OLED module is wired up. Some more probing of that module to obtain a proper schematic now seems in order, to determine whether I can green wire a bodge or will need a board respin before I can get it working.


Digging a bit deeper into the module layout and these are my conclusions. I put the current GAMOO schematic on the left and what I believe the module schematic is on the right (ignoring the 3 pin SMT IC and associated cap C8, which I assume is a voltage regulator to make the part 5V compatible):

The capacitors have very different values to those suggested by the Waveshare datasheet and which I have been using. I desoldered each one to test, so I’m confident they aren’t being affected by the other module components. I suppose it must have saved complexity in loading the SMT pick and place to double up 150nF caps on VCC pin. I will order some 33nF and 150nF caps to place on the GAMOO in lieu of the higher values. I don’t think that grounding pin 7 will make much difference but it’s there as a last resort (sadly no easy way to do this with the way I have routed the PCB, so will greenwire onto the flex cable pads). Interested to hear what others think about pin 7. Pleasingly, the module worked again when I resoldered the caps to the pads I think they came from :grin:.

Finally, the additional pullups on SCK and MOSI don’t have footprints on the GAMOO PCB but I have soldered 2x 4.7k pullup through-hole resistors onto the header on the board, so there’s no doubt that the lines are getting whipped back up to VDD.

Interestingly, this datasheet for SH1106, hosted on the Heltec website, suggests charge pump capacitor values of 220nF, rather than the 1uF in the Waveshare display datasheet. Time to buy some caps.

I’d be surprised if any of the differences between the GAMOO and module schematics you posted make any difference in operation whatsoever.

On the module, is VDDB (pin 6) connected to VDD (pin 9) so it receives power (3.3V VCC) or not?

Yes - I have just double checked. That was an error in my schematic. This is the corrected one.

Sigh. I realise I’m scraping the barrel. But I feel that the power supply isn’t the issue, now I can power the module from the GAMOO VCC. It’s certainly possible that I was solder-bridging underneath the flex PCB but I did probe for shorts and didn’t find any. I also deliberately allowed a little standoff with the second display I connected (but checked for soldering continuity).

Suggestions for other things to try would be very welcome.

Sorry, from everything you’ve said I’m just as perplexed as you are. :confounded:

Instead of ordering or waiting for capacitors, you could try putting your GAMOO values on the module to see if it still works.

You could also remove the MOSI and SCK 10k pullup resistors from the module to rule that out.

1 Like

I like this.

They’ll be here on Tuesday. My values are 0805 and the footprints on the module are 0603 - I can’t be bothered to fudge around trying to make them fit and run the risk of lifting pads and ruining my only working display!

You could likely solder your 0805s on top of the 0603s. Adding an additional 30nF or 150nF to the much higher values you’re using won’t make much of a difference.

Edit: You could solder each 0805 vertically to one side of a 0603 then use a small wire to connect the other side. This would make them easy to add and remove, with little chance of damaging anything.

So, you fixed it?? It looks like you fixed it! What is the opposite of recalcitrant? Calcitrant? Did you calcify your display?

@bateske, No. @SimonMerrett has managed to get a PC board module with an OLED display working when wired to his GAMOO board. He still hasn’t been able to get a bare OLED display, with only a flex cable soldered directly to his GAMOO board, to work.

We have been discussing what the differences are between these two scenarios that might cause the module to work but not the bare display.

I see two schematics in the most recent post, which one is being used?

The Pin 7 looks like it should be disconnected and there is also pullup resistors on the spi lines? That doesn’t seem right.

The most recent post of two schematics represents how the GAMOO PCB is (on the left) and how my best efforts to reverse engineer the OLED module’s PCB is (on the right). The pull ups on the module are to allow you to swap a resistor and convert the OLED to be in I2C mode. I added them to GAMOO in an attempt to replicate the successful way the module was working (but it didn’t work). Pin 7 looks like it should be disconnected because that’s what it says in a display manufacturer’s datasheet (not the control chip manufacturer), so I made the Kicad schematic part pin name “NC”. That’s the extent of its provenance, so could easily be wrong. It appears from continuing probing that the module has grounded this pin. I have no way of knowing if this pad on the flex cable is even connected to the SH1106 chip inside the display, so there’s not much to do other than trying to ground it and see if that makes a difference. Perhaps @Mr.Blinky and anyone else with a 1.3" OLED would be good enough to probe the status of their pin 7.

Compliant, or perhaps docile.

I’ve been skimming the conversation but it’s been a long time since it’s made any sense to me.
This must be what it’s like for other people when I start discussing template metaprogramming. :P

I’m sorry but I didn’t read everything, but have you gone through and tested you didn’t accidentally put a resistor instead of a capacitor somewhere or wrong value something like that? i.e. have you tried bringing up more than one board? Bad physical trace? You got out the circuit analyser so I’m guessing you’ve got continuity everywhere you are expecting it?

I notice the module is showing two ground nets, I doubt that they actually are physically isolating them on the board, the frequency isnt high enough for that to matter…

Your capacitor values are off by an order of a magnitude? But looks like you are probably using the specification and the chinese board is just using all the same?

Most of my problems generally come from physical problems on board lay out, I’ll swear something should be working until I look at everything under a microscope and see that I’ve got an trace that I missed or is overlapping a drill or some such thing.

1 Like

If the flex cable used for your displays is the same as the one used for the actual Arduboy then you’ll find that pin 7 is not connected to anything. It won’t matter if you tie it to anything or leave it floating.

You can verify this by examining pin 7 of the flex cable. It’s obvious that it goes nowhere.

1 Like

Here’s a photo of pin 7 of a 1.3" SSD1306 display that I recently purchased from BuyDisplay


Here’s one of a 0.96" SSD1306 on a I2C module


1 Like