Pyboard + SSD1306
Pyboard + SSD1306
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!
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!
Re: Pyboard + SSD1306
Would you please post the full error message with backtrace. That shows the line number and call stack.
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Pyboard + SSD1306
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.
Index to my micropython libraries.
Re: Pyboard + SSD1306
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
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
Re: Pyboard + SSD1306
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
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
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Pyboard + SSD1306
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.
Index to my micropython libraries.
Re: Pyboard + SSD1306
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
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
Re: Pyboard + SSD1306
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
>>> 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
Re: Pyboard + SSD1306
Just use:
instead of:
Code: Select all
i2c.writeto(0x70, b'\x01')
Code: Select all
i2c.writeto(0x70, 0x01)
Re: Pyboard + SSD1306
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.......
Now just need to work out why the screen doesn't initialise properly.......