Looking online for small SSD1306 OLED screens to use with Arduino over I2C, I find products that look like this:

User-facing side The hidden details

The sellers don't offer datasheets - and the product descriptions don't say anything about whether the SCL/SDA lines are 5V tolerant.

Based on what is visible in the pictures, there appears to be a regulator for the VCC line - so this will indeed be taken down to 3.3V or whatever that screen needs to work. But the rest of the board is just resistors and capacitors - no level-shifting in sight.

I worry that these sellers simply play on the tolerances of these screens - and will either fry immediately with 5V SDA/SCL signals, or will age quickly and fry a bit later.

What do you guys think?

  • \$\begingroup\$ Why not level shift on the Arduino side to 3.3v? \$\endgroup\$
    – Ron Beyer
    Nov 18, 2017 at 16:25
  • 1
    \$\begingroup\$ I think if a component doesn't have a datasheet, I don't waste my time thinking about it, and find another that does. \$\endgroup\$
    – Matt Young
    Nov 18, 2017 at 16:29
  • \$\begingroup\$ @Ron Beyer: That's indeed an option. IMHO though, their claiming "for Arduino" in their descriptions is misleading - it makes it seem like it's OK to connect this to Arduino pins A4 and A5 and all will work just fine. \$\endgroup\$
    – ttsiodras
    Nov 18, 2017 at 16:31

3 Answers 3


I2C is properly an open collector (well, today, open drain) bus, which is to say that the active devices only ever drive low, and the pullup resistors are relied on to raise the bus to the supply rail otherwise.

So for a starting point, you'd want to be sure that your only I2C pullup resistors connect to a 3.3v rail, and that you have none on the Arduino board or elsewhere which would connect to 5v.

The ATmega chips used in typical Arduino's have specifications that indicate they work fairly well with 3.3v inputs when running off a 5v supply, so reading the signal should be fine.

The greater challenge is that you would need to be sure that at no time does the Arduino ever actively drive the I2C lines high, for example, due to software error or loading of a different program. (Arguably you also want to make sure it never activates the internal pullups, but those are fairly weak and so less likely to be a problem).

If you can't make this guarantee, I2C is also fairly compatible with MOSFET-based level shifting, and such modules are sold by many sources. Here's an excerpt from one channel of the the schematic of Sparkfun's version. You'd probably want to replace (or simply parallel) those 10K resistor with resistors of a more typical I2C bus pullup value.

enter image description here

And of course you'd also want to measure the actual operating voltage of the board rather than assume that it is 3.3v. With the MOSFET level translator, you have wide latitude even for something like a 1.8v I2C on the low side. But without the level translator, you need to be sure that the I2C bus voltage is high enough to be reliably read as a 1 by your Arduino, which it may not be if it is substantially lower than 3.3v.


The vast majority of these displays are based on the SSD1306 which is indeed a 3.3 V maximum I2C device.

Connecting to an AVR type MCU can be problematic and there is a good description of the problem here in Arduino land ....and a simple cure using separate pullups. Depending on the display you buy you may find there are onboard pullups to 3.3 V rail or level shifters such as Adafruit use in their displays.

Adding the two 4k7 resistors also acts as a divider with any internal pullup on the MCU, but the voltage is very close to maximum and can exceed it depending on your MCU.

  • \$\begingroup\$ Thank you Jack - I was not aware of that article, it was very informative. \$\endgroup\$
    – ttsiodras
    Nov 18, 2017 at 19:53
  • \$\begingroup\$ To make sure I understood the 4.7K recommendation correctly I made a schematic in Eagle - does this look OK? \$\endgroup\$
    – ttsiodras
    Nov 19, 2017 at 21:59
  • \$\begingroup\$ Correct. If there are 5 V pullups turned on in your MCU there is a voltage divider effect between 3.3 - 5 V. This means the input may rise above 3.3 V and it uses the protective devices usually present on an input to shunt the signal. It's best to alter your drive library to not pull the SCL/SDA high, then this solution is perfect. \$\endgroup\$ Nov 19, 2017 at 22:53
  • \$\begingroup\$ Great. I did a test on a breadboard and measured with my tiny scope - both SCL and SDA are pulsing between ground and 3.3V when I send the data on the screen. Clearly the u8glib library never pulls high - all good! :-) I proceeded to route for perfboard prototype - thanks, Jack! \$\endgroup\$
    – ttsiodras
    Nov 20, 2017 at 8:53

The controller is not 5V tolerant. From what I've read this board needs external pull ups. Unless there is a resistor voltage divider, which can be used for 5v to 3.3v translation, you should provide your own.

There are plenty of simple transistor plus resistor voltage translators for i2c around. Or use a 3.3V arduino or other MCU.

  • \$\begingroup\$ Dividers won't really work with I2C \$\endgroup\$ Nov 18, 2017 at 17:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.