1 1
hallo1

I2C OLED broken at kernel 5.4.20+

Recommended Posts

Armbianmonitor:

I am using a orangepi win plus.

I have attached a ssd1306 OLED display to the board, using i2c1 interface, using the luma.oled library as driver.

import sys
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
import subprocess
from luma.core.interface.serial import i2c
from luma.core.render import canvas
from luma.oled.device import ssd1306, ssd1325, ssd1331, sh1106
from time import sleep

serial = i2c(port=1, address=0x3C)
device = ssd1306(serial, rotate=0)
width=device.width
height=device.height

image = Image.new('1', (device.width, device.height))

# Get drawing object to draw on image.
draw = ImageDraw.Draw(image)

# Draw a black filled box to clear the image.
draw.rectangle((0,0,device.width,device.height), outline=0, fill=0)

padding = 2
top = padding
bottom = device.height-padding
# Move left to right keeping track of the current x position for drawing shapes.
x = 0
while True:

    # Draw a black filled box to clear the image.
    draw.rectangle((0,0,width,height), outline=0, fill=0)

    # Shell scripts for system monitoring from here : https://unix.stackexchange.com/questions/119126/command-to-displa$    cmd = "hostname -I | cut -d\' \' -f1"
    IP = subprocess.check_output(cmd, shell = True )
    cmd = "top -bn1 | grep load | awk '{printf \"CPU Load: %.2f\", $(NF-2)}'"
    CPU = subprocess.check_output(cmd, shell = True )
    cmd = "free -m | awk 'NR==2{printf \"Mem: %s/%sMB %.2f%%\", $3,$2,$3*100/$2 }'"
    MemUsage = subprocess.check_output(cmd, shell = True )
    cmd = "df -h | awk '$NF==\"/\"{printf \"Disk: %d/%dGB %s\", $3,$2,$5}'"
    Disk = subprocess.check_output(cmd, shell = True )

    # Write two lines of text.

    draw.text((x, top),"IP:"+str(IP,encoding = "utf-8"),  font=font, fill=255)
    draw.text((x, top+8),str(CPU,encoding = "utf-8"), font=font, fill=255)
    draw.text((x, top+16),str(MemUsage,encoding = "utf-8"),  font=font, fill=255)
    draw.text((x, top+25),str(Disk,encoding = "utf-8"),  font=font, fill=255)
    device.display(image)
    sleep(0.5)

 

At the kernel version 5.3.9, the display worked perfectly, without any problem.

 

But after updating the kernel version to above 5.4.20, the same code don't work at all.

Traceback (most recent call last):
  File "./test_oled.py", line 12, in <module>
    device = ssd1306(serial, rotate=0)
  File "/usr/local/lib/python3.6/dist-packages/luma/oled/device/__init__.py", line 188, in __init__
    self.clear()
  File "/usr/local/lib/python3.6/dist-packages/luma/core/mixin.py", line 46, in clear
    self.display(Image.new(self.mode, self.size))
  File "/usr/local/lib/python3.6/dist-packages/luma/oled/device/__init__.py", line 220, in display
    self.data(list(buf))
  File "/usr/local/lib/python3.6/dist-packages/luma/core/device.py", line 46, in data
    self._serial_interface.data(data)
  File "/usr/local/lib/python3.6/dist-packages/luma/core/interface/serial.py", line 119, in data
    write(list(data[i:i + block_size]))
  File "/usr/local/lib/python3.6/dist-packages/luma/core/interface/serial.py", line 128, in _write_large_block
    self._bus.i2c_rdwr(self._i2c_msg_write(self._addr, [self._data_mode] + data))
  File "/usr/local/lib/python3.6/dist-packages/smbus2/smbus2.py", line 637, in i2c_rdwr
    ioctl(self.fd, I2C_RDWR, ioctl_data)
TimeoutError: [Errno 110] Connection timed out

Because the luma.oled library just uses the linux kernel i2c interface like the /dev/i2c-1, so it is more likely a bug related to kernel.

 

 

 

 

Share this post


Link to post
Share on other sites
25 minutes ago, hallo1 said:

so it is more likely a bug related to kernel.

Did you checked the presence of the device with "i2cdetect" ?

Did you checked the permissions of /dev/i2c-1 and running your test script under proper user/group ?

Share this post


Link to post
Share on other sites
17 hours ago, martinayotte said:

Did you checked the presence of the device with "i2cdetect" ?

Did you checked the permissions of /dev/i2c-1 and running your test script under proper user/group ?

I2cdetect works properly, showing a device at address 0x3c

I'm using superuser permission to execute the script. If there is a permission issue, it will show a error message "permission denied"

 

Sometimes the display will light up and show proper content, but the script will still run into this error after ~3s.

Share this post


Link to post
Share on other sites
5 hours ago, hallo1 said:

Sometimes the display will light up and show proper content, but the script will still run into this error after ~3s.

Then, maybe it is I2C speed issue ...

Share this post


Link to post
Share on other sites
On 5/11/2020 at 10:06 PM, martinayotte said:

Then, maybe it is I2C speed issue ...

That is not a I2C speed issue.

I examined the i2c data of the OLED using a logic analyzer and found the i2c clock is both 100KHz (maybe a little slow but reasonable)

Share this post


Link to post
Share on other sites
34 minutes ago, hallo1 said:

That is not a I2C speed issue.

I examined the i2c data of the OLED using a logic analyzer and found the i2c clock is both 100KHz (maybe a little slow but reasonable)

Here is the output of the logic analyzer (kernel ~5.4). You can open it using the pulseview software.

under linux mainline 5.4.sr

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
1 1