Pyboard + SSD1306

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
doublevee
Posts: 75
Joined: Mon Jul 02, 2018 11:09 pm

Pyboard + SSD1306

Post by doublevee » Tue Jul 24, 2018 8:04 am

I have been struggling unsuccessfully to get a Pyboard (v1.1) and SSD1306 based OLED talking. I have no issues using the ESP8266 or ESP32.

It is very confusing (to me) whether to user the pyb or machine library for instantiating an I2C object. I have used both, and they both work correctly; if I issue i2c.scan() for example, I correctly detect my I2C device.

e.g.

import pyb
i2c = pyb.I2C(2)
i2c.scan()

OR

import machine
i2c = machine.I2C(2)
i2c.scan()

OR

import machine
pscl = machine.Pin('Y9', machine.Pin.OUT_PP)
psda = machine.Pin('Y10', machine.Pin.OUT_PP)
i2c = machine.I2C(scl=pscl, sda=psda)
i2c.scan()

However, when I try to pass this object to the ssd1306 library:

import ssd1306
display = ssd1306.SSD1306_I2C(128, 32, i2c, 0x3c)

it always fails with the following message:

TypeError: object with buffer protocol required

Would anyone be able to advise me please? It seems such a stupid issue to have, so am I doing something silly here?

I have done lots of reading online and across the forum before posting here. What does this error message mean as well? (I am learning Python and so like to understand these things as much as possible).

Many thanks!

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Pyboard + SSD1306

Post by Roberthh » Tue Jul 24, 2018 10:29 am

Would you please post the full error message with backtrace. That shows the line number and call stack.

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

Re: Pyboard + SSD1306

Post by pythoncoder » Tue Jul 24, 2018 5:44 pm

This may be a firmware issue. I suggest upgrading. Also ensure you are using the latest SSD1306 driver, as there was a change made relatively recently. Firmware and driver must match.
Peter Hinch
Index to my micropython libraries.

doublevee
Posts: 75
Joined: Mon Jul 02, 2018 11:09 pm

Re: Pyboard + SSD1306

Post by doublevee » Tue Jul 24, 2018 8:29 pm

Thanks for your responses.

This is the very simple test program:
----------------------------------------------------------------------
import machine
import ssd1306

i2c = machine.I2C(2)
scan = i2c.scan()
print (scan)

display = ssd1306.SSD1306_I2C(128, 32, i2c, 0x3c)
----------------------------------------------------------------------
and this is the error message I receive:
----------------------------------------------------------------------
[119]
Traceback (most recent call last):
File "<stdin>", line 8, in <module>
TypeError: object with buffer protocol required
----------------------------------------------------------------------
The scan is correctly detecting my I2C mux at 0x77 on bus 2.

Version of Pyboard is:
MicroPython v1.9.3 on 2017-11-01; PYBv1.1 with STM32F405RG

This is the version of ssd1306.py I am using:
https://github.com/micropython/micropyt ... ssd1306.py

doublevee
Posts: 75
Joined: Mon Jul 02, 2018 11:09 pm

Re: Pyboard + SSD1306

Post by doublevee » Tue Jul 24, 2018 10:19 pm

I have now upgraded to v1.9.4 and am receiving much more output regarding the error.

Example 1:
----------------------------------------------------------------
from pyb import I2C
import ssd1306

i2c = I2C(1, I2C.MASTER)
print(i2c.scan())

display = ssd1306.SSD1306_I2C(128, 32, i2c, 0x3c)
----------------------------------------------------------------
Generates the following error:
----------------------------------------------------------------
[112]
Traceback (most recent call last):
File "<stdin>", line 7, in <module>
File "ssd1306.py", line 99, in __init__
File "ssd1306.py", line 36, in __init__
File "ssd1306.py", line 61, in init_display
File "ssd1306.py", line 104, in write_cmd
AttributeError: 'I2C' object has no attribute 'writeto'
----------------------------------------------------------------

Example 2:
----------------------------------------------------------------
import machine
import ssd1306

i2c = machine.I2C(1)
scan = i2c.scan()
print (scan)

display = ssd1306.SSD1306_I2C(128, 32, i2c, 0x3c)
----------------------------------------------------------------
Generates the following error:
----------------------------------------------------------------
[112]
Traceback (most recent call last):
File "<stdin>", line 8, in <module>
File "ssd1306.py", line 99, in __init__
File "ssd1306.py", line 36, in __init__
File "ssd1306.py", line 61, in init_display
File "ssd1306.py", line 104, in write_cmd
OSError: [Errno 19] ENODEV
----------------------------------------------------------------

Quite frustrating but hopefully this will mean something to one of the experts!!

I don't understand why there are different error messages either :(

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

Re: Pyboard + SSD1306

Post by pythoncoder » Wed Jul 25, 2018 4:54 am

Your second example using machine is correct, but I think the device address is wrong. Your device is reporting 112 (0x70). Try

Code: Select all

display = ssd1306.SSD1306_I2C(128, 32, i2c, 0x70)
Peter Hinch
Index to my micropython libraries.

doublevee
Posts: 75
Joined: Mon Jul 02, 2018 11:09 pm

Re: Pyboard + SSD1306

Post by doublevee » Wed Jul 25, 2018 7:55 am

Thanks Peter for your reply. I think it might help to describe a little more what I am trying to achieve.

I have a Pyboard v1.1 connected to 2 x TCA9548 I2C switches using both hardware I2C buses. Each switch is connected to an SSD1306 based 128x32 OLED I2C module on channel 1. The purpose of the switches is to allow more screens to be added at a later date if necessary.

Until the switch receives a value (default is all channels off) then only the switch is detected during a scan. Switch 1 is hardwired to 0x70, switch 2 to 0x77.

Using machine.I2C I am unable to write to the I2C bus - following the documentation for 1.9.4, I cannot get this to work, so there is obviously something very fundamental that I am doing wrong here. In your previous reply you confirmed I should be using machine and not pyb for I2C operation.

As I mentioned in my previous post, I can correctly scan bus 1 using the following, and the switch at 0x70 is detected:

>>> import machine
>>> i2c=machine.I2C(1)
>>> i2c.scan()
[112]

However, I am unable to write the channel command to the switch:

>>> i2c.writeto(0x70, 0x1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object with buffer protocol required

I'm back to my favourite 'buffer protocol required' :(

So I tried this again, but using pyb instead of machine. This is what I did:
>>> import pyb
>>> i2c=pyb.I2C(1,I2C.MASTER)
>>> i2c.scan()
[112]
>>> i2c.send(0x1,0x70)
>>> i2c.scan()
[60, 112]

You can see the switch again correctly detected, and this time I am able to write to the switch to select channel 1, and then it correctly detects both the switch and the OLED module sitting behind it.

So i then tried the following:
>>> display = ssd1306.SSD1306_I2C(128,32,i2c,0x3c)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "ssd1306.py", line 99, in __init__
File "ssd1306.py", line 36, in __init__
File "ssd1306.py", line 61, in init_display
File "ssd1306.py", line 104, in write_cmd
AttributeError: 'I2C' object has no attribute 'writeto'

Something was defintiely sent to the OLED module as I have a smattering of dots on the screen, so progress of sorts, but again the AttributeError.

If machine is the correct method of using the STM32F4 I2C buses, what is the command to write to the bus? I have been following the documentation here:

http://docs.micropython.org/en/latest/p ... hlight=i2c

I am thoroughly confused now :)

doublevee
Posts: 75
Joined: Mon Jul 02, 2018 11:09 pm

Re: Pyboard + SSD1306

Post by doublevee » Wed Jul 25, 2018 7:58 am

Just to add, with the I2C switch configured to channel 1, I tried the following as well:

>>> i2c.scan()
[60, 112]
>>> i2c=machine.I2C(1)
>>> display = ssd1306.SSD1306_I2C(128,32,i2c,0x3c)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "ssd1306.py", line 99, in __init__
File "ssd1306.py", line 36, in __init__
File "ssd1306.py", line 63, in init_display
File "ssd1306.py", line 91, in show
File "ssd1306.py", line 109, in write_data
OSError: I2C operation not supported

chuckbook
Posts: 135
Joined: Fri Oct 30, 2015 11:55 pm

Re: Pyboard + SSD1306

Post by chuckbook » Wed Jul 25, 2018 8:03 am

Just use:

Code: Select all

i2c.writeto(0x70, b'\x01')
instead of:

Code: Select all

i2c.writeto(0x70, 0x01)

doublevee
Posts: 75
Joined: Mon Jul 02, 2018 11:09 pm

Re: Pyboard + SSD1306

Post by doublevee » Wed Jul 25, 2018 11:17 pm

Thank you chuckbook - that got the command working and I have read up on Python bytes :)

Now just need to work out why the screen doesn't initialise properly.......

Post Reply