0.96 OLED display I2C config - Page 1
Forum section: electronics / beginners

author: jvlobo
author_rank: Contributor
timestamp: May 09, 2022, 08:28:47 pm
content: Hello everyoneI got a new display but I'm struggling to use it over I2C. I've been investigating and there seems to be many different versions of these SSD1306 0.96 OLED displays... and sadly the one I got doesn't come with any information on how to configure it for using it with I2C.This is the one I have:So I just connected the jumper on the left and middle pad that says "HC" (which I supposed it is IIC).But then I'm not sure if I should populate or change the position of any of the resistors/capacitors.I haven't been able to get anything on the display using I2C. But I was able to use it with SPI.If anyone knows or have experience with this display I would highly appreciate the help.Thanks a lot.

author: MikeK
author_rank: Super Contributor
timestamp: May 09, 2022, 08:53:19 pm
content: That's the SPI version, not I2C. I don't think you can change it.

author: jvlobo
author_rank: Contributor
timestamp: May 09, 2022, 09:33:10 pm
content: Thanks for the reply.But are you sure about that?? I've seen many different 0.96 OLED displays that work both with SPI and I2C.And this one has the jumper to select I2C/SPI.

author: Ian.M
author_rank: Super Contributor
timestamp: May 09, 2022, 09:47:32 pm
content: I2C on a SSD1306 OLED needs D2 broken out, (and ideally run through an open drain buffer as its weaker than allowed by the I2C spec) as it provides the ACK from the display slave back to the master MCU, and needs to be connected to D1, the display's input-only SDA pin. Also there are two other pins that need a different state to select I2C mode vs SPI mode. If those pins are on the flatflex, you can trace what components to hack on the PCB, but if they aren't, you are S.O.L.

author: jvlobo
author_rank: Contributor
timestamp: May 09, 2022, 10:09:15 pm
content: Thank you.I was taking a look a thisdocumentthat shows some examples of how to interface the SSD1306. On the I2C I saw the D0 and D1 connected to 10K resistors (something that is not done on the SPI one). And on my board, I can see those two 10K resistors. That is also why I believed I could achieve the I2C connection here.I'm also tried to figure out the other pins but I'm a bit lost as the flex cable has 30 pins and in those examples there are 24.

author: ledtester
author_rank: Super Contributor
timestamp: May 09, 2022, 10:17:23 pm
content: This looks like the official SD1306 datasheet:https://www.rhydolabz.com/documents/SSD1306.pdfStarting on page 18 it describes how to configure the I/O lines for I2C, 3-wire SPI and 4-wire SPI.I found the datasheet on this page:https://www.rhydolabz.com/displays-c-88/096-oled-display-module-spii2c-128x64-6-pin-white-p-2260.htmland that has some pics of a 6-pin module with some resistor config information silk-screened on the back of the PCB.

author: jvlobo
author_rank: Contributor
timestamp: May 09, 2022, 10:20:22 pm
content: Thanks for the info. I'll take look to that document.Indeed the board's pins are like mine, just with SCL and SDA instead of D0 and D1.

author: Ian.M
author_rank: Super Contributor
timestamp: May 09, 2022, 10:27:32 pm
content: The problem is: You need the pinout of the actual display (not the assembled display + breakout) to tell you which pin of the flatflex goes to which bump of the SSD1306 die, mounted chip-on-flex. To determine this you usually need the display part number which is on the back of the display which has been bonded to the other side of the breakout PCB, and its very unlikely for the display or the number to survive being peeled off to read it.You may be lucky and be able to identify enough pins by tracing them from named pins/pads of the breakout to the flatflex and match them up to a similar enough display with the same flatflex pinout, but if you get it wrong, odds are you'll damage the display.

author: jvlobo
author_rank: Contributor
timestamp: May 09, 2022, 10:32:14 pm
content: UnderstoodI will try to trace the pins but honestly, I'm taking this as a learning exercise so I wouldn't really mind damaging the display. They are not expensive so I could get an already working I2C out of the box. But having this one and having the possibility to get t to work over I2C I'm up for the challenge heheThanks!

author: rstofer
author_rank: Super Contributor
timestamp: May 10, 2022, 01:59:13 am
content: I have a couple of incantations of the 0.96 OLED display for I2C and they vary in that the Vcc and Gnd pins are swapped. Both have only 4 pins. This is the one I use with the MicroPython version of the ssd1306 driverhttps://www.amazon.com/gp/product/B085WCRS7CI'm not sure which version you have but I would be very curious about it being I2C.I'm pretty sure this is the library I use:https://github.com/micropython/micropython/blob/master/drivers/display/ssd1306.pyIt looks like I pulled out the SPI specific code to save a little space.

author: jvlobo
author_rank: Contributor
timestamp: May 10, 2022, 08:09:51 am
content: Thank you.I'll check it out.

author: DavidAlfa
author_rank: Super Contributor
timestamp: May 11, 2022, 07:17:16 pm
content: That's exactly your screen? In every detail?S1 looks like the interface selector (IM1), switching between VCC and GND, in that picture it's already set in I2C Mode! Left=i2c, right=spi.And R2+R3 seems to be the i2c pullups.In I2C Mode, the signals are as follows:- RST still provides reset functionality, it can also be left unused, connected to VCC.- DC is unused and must be connected to gnd (There's R6 for that)- CS is the I2C lower address bit, but it's already connected to gnd in that display.- D0=SCL- D1=SDAAre you correctly sending the data, following the I2C format?You can't just send the bytes as-is like in spi, the oled i2c protocol is like this:Code: [Address (0x3C)] [mode(cmd=0x00,data=0x40)]  Ex. To turn the screen on:Code:     (display on CMD)To send data (Write to the display RAM):Code:   [data 0]...[data n] Edit: Confirmed:https://forum.arduino.cc/t/ssd1306-oled-display-config/658283

author: jvlobo
author_rank: Contributor
timestamp: May 11, 2022, 08:02:01 pm
content: Thanks David.That is exactly my screen, correct. I took that picture.I tried connecting the pins as you suggested. To see if the I2C is working I'm running an I2C Scanner on my Arduino UNO:https://playground.arduino.cc/Main/I2cScanner/But it never finds anything

author: Ian.M
author_rank: Super Contributor
timestamp: May 11, 2022, 09:47:36 pm
content: Quote from: DavidAlfa on May 11, 2022, 07:17:16 pmI wouldn't call that 'confirmed' as it was a single reply noting that 'HC' might represent 'IIC' thus I2C to an uneducated Chinese eye, so making the 'HC' side of the solder jumper might put it in I2C mode. There was no followup giving the O.P's success or failure.Lets refer to theSSD1306(IC) datasheet.N.B. This is not the display datasheet, just the COG or chip-on-flex display controller datasheet so you wont find the ribbon connector pinout in it or details of the display size.From an interfacing point of view, the interesting stuff starts just before section 8, with 'Table 7-1 : MCU Bus Interface Pin Selection' There are THREE interface selection pins BS0-BS2, which select the interface mode.Taking BS2 as the MSB:BS2:0 Interface000 4 wire serial001 3 wire serial010 I2C100 6800 parallel110 8080 parallelAs you can see its possible to switch between I2C and 4 wire serial by a single solder jumper for SSD1306 pin BS1.However lets review the connections given in section 8:Quote from: datasheetandQuote from: datasheetIf D2 (SDA out) is not linked to D1 (SDA in), the SSD1306 cant ACK any data or address it receives on the I2C bus. The pullup will provide a NACK instead. This is non I2C standard compliant as ACK is usually used to indicate the receiver is present cant can accept more data. Therefore without the D1-D2 link, the SSD1306 cant be seen byi2cdetector other I2C scanners as they probe each address in turn looking for an ACK to map the connected devices. You'll also have to configure your I2C library to perform multi-byte writes ignoring the NACKs, rather than aborting on the first NACK.Note that D2 is only for ACKs, you cant read back any SSD1306 registers or display RAM.If your display is COG, due to the ITO track resistance, D2 needs buffering with an open drain non-inverting buffer, so it can properly drive SDA low against the pullup current. If its chip-on-flex the low resistance copper tracks mean you don't need a buffer and can simply link D2 and D1.TLDR: find D2 and link it to D1 for I2C mode to work properly!

author: jvlobo
author_rank: Contributor
timestamp: May 11, 2022, 10:02:27 pm
content: Thanks for the detailed explanationSo, from my original picture. Knowing (or assuming) that those two 10k resistors are connected to D0 and D1 I could assume that the next pin is D2, and the ones following, D3 to D7 are connected together to ground.The thing is that D2 in this case is also connected to D3-D7, not sure why this is like that or if was a defect. I'll try to "disconnect it" and see what I get.

author: jvlobo
author_rank: Contributor
timestamp: May 11, 2022, 10:22:26 pm
content: WOW, some progress!!QuoteSo cool 👏🏽👏🏽I tried with an example sketch from the Adafruit library and it shows a lot of dots on the screen, so something must be wrong still. I'll keep investigating

author: Ian.M
author_rank: Super Contributor
timestamp: May 11, 2022, 10:25:18 pm
content: Disconnect it and patch it to a length of 30 AWG Kynar wirewrap wire or magnet wire so you can connect stuff to it. Connect it to a 10K pullup to +3.3V, and scope the signal on it. You should see a low-going ACK pulse for the receipt of the I2C display address byte and every data byte after it in the same transfer. If so, you can safely connect it to D1. If not, you've got the wrong pin or it isn't in I2C mode or you aren't using the correct display address.Edit: So you went ahead and tied it to D1, and it worked? *GREAT* Ignore the paragraph above!

author: DavidAlfa
author_rank: Super Contributor
timestamp: May 11, 2022, 11:10:58 pm
content: Ian, I said so because to date, all spi oleds I had could be configured to i2c just like that.I don't have exactly that model, but they're all very similar.Also, I thought the 0.96" used the SH1106, and the 1.3" the SSD1306, they're very similar but not identical, check the SH1106 attachment.Also attached the pinout.

author: Ian.M
author_rank: Super Contributor
timestamp: May 12, 2022, 12:10:00 am
content: Yes, displays with aSH1106controller don't need D2 strapped to D1 for I2C mode, as you note above. Fortunately, D2 is Hi-Z in I2C mode so strapping it does no harm.Probably the best way forward for a display that refuses to ACK and doesn't appear to have D2 strapped to D1, is to investigate D2 as I suggested in reply #16. If you get ACK pulses on D2, it must have a SSD1306 controller, so will need them strapped. If it doesn't ACK on D2 but does on D1 (check this first before hacking the PCB) it must be a SH1106. If the PCB already has D1 strapped to D2 you should be getting ACKs on the combined SDA, and you'll have to distinguish between them by the display address mapping, or by attempting to read from it.Note that reading from a SH1106 over I2C has some quirks. See:https://arduino.stackexchange.com/questions/50640/reading-ram-from-sh1106-oled-controller-through-i2candhttps://picaxeforum.co.uk/threads/fyi-comparing-the-ssd1306-and-sh1106-oled-drivers.32387/which goes into more detail as the PICAXE doesn't have an OLED driver library so they are doing 'bare metal' register level access.

author: jvlobo
author_rank: Contributor
timestamp: May 12, 2022, 10:41:17 am
content: Thanks a lot guys. Got it 100% working nowAs a summary, these are the things I had to do:Connect D2 to D1 (by soldering a thin wire straight on the actual board)Connect the pins (in my case testing with an Arduino UNO):RST: connect to Arduino's Reset pin or VCCDC: connect to GNDD0: connect to pin A5 (19)D1: connect to pin A4 (18)To see if the display is found over I2C you can try with aI2C scanner.Then, to actually get something on the screen, I tried with the examplesimple_demofrom thess_oledlibrary, specifying the pins for SDA and SCLCode:#define SDA_PIN 19#define SCL_PIN 18And it works!Thanks again everyone. Hopefully this helps someone else out there