SSD1306 I2C

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
Swessels
Posts: 6
Joined: Fri Dec 22, 2017 4:20 pm
Location: Germany

SSD1306 I2C

Post by Swessels » Fri Dec 22, 2017 6:29 pm

Hi together,

i'm new to the ESP32 and it's also my first attempt using micropython. I've some experience with AVR and STM32 using GCC.<br/>
I've tried to use a 128x64 ssd1306 OLED display using the follwing library :

https://github.com/micropython/micropyt ... ssd1306.py"

Using an example from

https://www.hackster.io/hendra/ssd1306- ... hon-32b5fe

i got the following error (output from terminal):

>>> from machine import Pin,I2C
>>> import ssd1306
>>> iic = I2C(scl = Pin(22), sda = Pin(21), freq=100000)
>>> iic.scan()
[60]
>>> lcd = ssd1306.SSD1306_I2C(124,64,iic)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: function missing 1 required positional arguments
>>>

According to the output above the diplay is recogniced at address 0x3C, corresponding to the predefined value in ssd1306.py.
I don't know which argument is missing, please help.

Thanks in advance,
Stefan

User avatar
pythoncoder
Posts: 3613
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: SSD1306 I2C

Post by pythoncoder » Sat Dec 23, 2017 9:11 am

Unfortunately there is a problem with the latest version of the driver ssd1306.py. Until this is resolved please use the previous version which has the same functionality and interface. A copy is available here.
Peter Hinch

Swessels
Posts: 6
Joined: Fri Dec 22, 2017 4:20 pm
Location: Germany

Re: SSD1306 I2C

Post by Swessels » Sat Dec 23, 2017 2:58 pm

Thanks for your reply. The display is initialized and accepts commands like 'contrast', 'poweroff' etc.
Unfortuneately the display is corrupted. A lot of scattered points and a black bar occurs.
In the bar the text commanded with the text() command flashes shortly after sending show().
Additional pullups and other pins wont work. I think there is a timing-problem?. CPu frequency is 240 MHz.

SpotlightKid
Posts: 380
Joined: Wed Apr 08, 2015 5:19 am

Re: SSD1306 I2C

Post by SpotlightKid » Sat Dec 23, 2017 4:30 pm

pythoncoder wrote:
Sat Dec 23, 2017 9:11 am
Unfortunately there is a problem with the latest version of the driver ssd1306.py.
Yes, line 35 in there does seem to be incorrect:

Code: Select all

super.__init__(self.buffer, self.width, self.height, framebuf.MONO_VLSB)
The parentheses after super are missing.

User avatar
pythoncoder
Posts: 3613
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: SSD1306 I2C

Post by pythoncoder » Sat Dec 23, 2017 6:41 pm

@SpotlightKid Indeed. Alas that's the least of its problems. @Damien introduced a change to enable the framebuf class to be subclassed. I modified the SSD1306 driver to use this, a simple change which worked first time when I tested it.

Except that I'd forgotten that my test rigs had ssd1306.py implemented as frozen bytecode. So my testing was against the old proven build. When first tried using the new driver I had problems. I spotted the missing parens and realised that my testing must have gone awry :oops: I seem to get dumber with every passing year :cry:

It then emerged that the change @Damien introduced appears to have issues where a subclassed framebuf is itself subclassed. This has been raised on GitHub.

Until this is sorted out the solution is to use the old version as I suggested above.

@Swessels I have today been running the version of ssd1306.py which I recommended with I2C and SPI devices without issue. The hosts are Pyboards. So I suggest you tell us more about your test conditions.

What ESP32 board are you using? Is your display I2C or SPI connected? If you let us know, and post code which shows the pin numbers you're using I can test with an ESP32. You should use soft I2C/SPI (i.e. pass Pin instances to the constructor). Neither interface should be timing sensitive so it really ought to work. I would suggest trying pins which aren't used by the hardware I2C/SPI in case these are being used elsewhere - I think the Loboris port uses at least one of these hardware interfaces. Check this PDF for notes on pin allocations.
Peter Hinch

Swessels
Posts: 6
Joined: Fri Dec 22, 2017 4:20 pm
Location: Germany

Re: SSD1306 I2C

Post by Swessels » Sun Dec 24, 2017 5:53 am

My Board is a China - clone. The diplay in question is a 1,3", 128x64, connected per I2C.
I'm using a breadboard with no other components. Voltage supply via USB.

The code:

Code: Select all

from machine import Pin,I2C
import ssd1306

i2c = I2C(scl=Pin(22), sda=Pin(21), freq=100000)

lcd = ssd1306.SSD1306_I2C(128,64,i2c)
lcd.text("Hello",0,0)
lcd.show()
I've changed the pins to 33 for sda and 32 for scl and reduced the frequency to 50000, the same effect.
As stated before, additional pullups (4k7) won't work.

I'll try to use an adafruit SPI display later this day. Maybe the I2C display is damaged.

Best regards and merry christmas,
Stefan

User avatar
pythoncoder
Posts: 3613
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: SSD1306 I2C

Post by pythoncoder » Sun Dec 24, 2017 8:09 am

I have previously run an I2C SSD1306 display on ESP32 with the following pinout and code. While I can't fault what you've done so far I suggest you try this as a last chance. I used the official firmware with 4K7 external pullups to 3.3V.

Code: Select all

from machine import I2C, Pin
from ssd1306 import SSD1306_I2C

WIDTH = 128
HEIGHT = 64
i2c = I2C(-1, scl=Pin(23), sda=Pin(22))
ssd = SSD1306_I2C(WIDTH, HEIGHT, i2c)
ssd.fill(0)
If that fails I'd suspect the hardware - you should have better luck with Adafruit's excellent products.

Merry Christmas to you too, Stefan
Peter Hinch

fdufnews
Posts: 29
Joined: Mon Jul 25, 2016 11:31 am

Re: SSD1306 I2C

Post by fdufnews » Sun Dec 24, 2017 9:23 am

Swessels wrote:
Sun Dec 24, 2017 5:53 am
My Board is a China - clone. The diplay in question is a 1,3", 128x64, connected per I2C.
Maybe you can put a link to the board you use or at least a picture of it.
Some boards have an additionnal reset that need to be configured in order for the board to work as expected like this one for example viewtopic.php?f=18&t=4002&p=22973&hilit=heltec#p22973

User avatar
philwilkinson40
Posts: 59
Joined: Tue Nov 14, 2017 3:11 am
Location: Perth, Australia

Re: SSD1306 I2C

Post by philwilkinson40 » Sat Dec 30, 2017 8:09 am

I am in a very similar situation with probably the same generic board from China; Heltec.
IMG_20171230_51879.jpg
IMG_20171230_51879.jpg (49.8 KiB) Viewed 4763 times
The OLED definetly works as it had a test program running on initial boot, before I flashed the Micropython.

I have used the previous version of the SSD1306.py module as recommended by @pythoncoder
On the HELTEC PinOut SCL(15) and SDA(4). I have also pulled the reset pin(16) high.

main.py contains the basic code

Code: Select all

##Heltec OLED test 1

import machine
import ssd1306

#set reset Pin high
pin16 = machine.Pin(16, machine.Pin.OUT)
pin16.value(1)



#instantiate a i2c object
i2c = machine.I2C(-1, scl=machine.Pin(15), sda=machine.Pin(4))

#instanciate a SSD1306 object
oled = ssd1306.SSD1306(128, 64, i2c)

oled.fill(0)
oled.text('Micropython', 0,0)
oled.show()
this returns the error

Code: Select all

Traceback (most recent call last):
  File "main.py", line 16, in <module>
  File "ssd1306.py", line 53, in __init__
AttributeError: 'SSD1306' object has no attribute 'poweron'

User avatar
pythoncoder
Posts: 3613
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: SSD1306 I2C

Post by pythoncoder » Sat Dec 30, 2017 8:26 am

@philwilkinson40 Two points. Firstly you need to instantiate the display with

Code: Select all

oled = ssd1306.SSD1306_I2C(128, 64, i2c)
Secondly I don't know which version of ssd1306.py you're using but the line number doesn't correspond to the official version or the one I recommended. I suggest you try with this one. This is the version prior to the current problematic one.
Peter Hinch

Post Reply