Trouble using the SH1106 OLED

Hi folks, finally getting on with my RasPi projects, with some success, but having some difficulty with the OLED when it comes to doing my own thing with it.

For reference, this is what Im trying to recreate https://www.raspberrypi-spy.co.uk/2019/10/pi-hole-oled-status-screen/ but with an SPI interface OLED instead.

Everything is working, the OLED is running on SPI0 as device 1, and I can run the bounce example perfectly fine - however, when I try to use the luma library I get nothing, zip, nada :(

heres what I do to run bounce
python3 bounce.py --display sh1106 --height 128 --rotate 2 --interface spi --spi-port 0 --spi-device 1 --gpio-data-command 9

heres the relevant snippet of my code, based on the example in the docu, the led blinks so I know the code and subsequent loop is running, but the screen stays blank. (Nothing changes about the wiring or settings in between running this, and bounce.)

#!/usr/bin/python3

Graphics libraries

from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
from luma.core.interface.serial import i2c,spi
from luma.core.render import canvas
from luma.oled.device import sh1106
serial = spi(device=0, port=1)
device = sh1106(serial, width=128, height=128, rotate=2, mode=1)

led.value=1

with canvas(device) as draw:
draw.rectangle(device.bounding_box, outline=“white”, fill=“black”)
draw.text((10, 40), “Hello World”, fill=“white”)
device.display # ??

led.value=0

with canvas(device) as draw:
draw.rectangle(device.bounding_box, outline=“white”, fill=“white”)
draw.text((10,40), “Hello World”, fill=“black”)
device.display # ??

It’s obviously something I’m missing or doing wrong but I’m not familiar with this library and it’s eluding me, any pointers please? TIA

I’ve not used the Luma module but I’d take a wild guess that this is the problem:

It should probably be device.display()

These modules tend to work the same way: you spend time putting together an image, but nothing gets passed to the screen until you call some sort of display or show function. However, to call a function you need round brackets after the name. If you don’t have those you’re actually asking “does device have something called display?” Python will go and check and then say “Yes, device does, here’s some information about it” and then carry on. That’s why your script wasn’t actually failing, device.display is a valid command, it’s just not the command you want.

Solved it, my own fault for trying to enable it on spi1 bus first. I had put the following in /boot/config.txt and rebooted, so originally was targeting /dev/spidev1.0.

dtoverlay=spi1-1cs,cs0_pin=16 # BCM 16 = gpio pin 36
# MISO - pin 35
# CE0 - pin 36 (default 12?)
# MOSI - pin 38
# CLK - pin 40

When that didnt work I reverted to /dev/spidev0.1 - updated my settings to run bounce, but didn’t properly reconfigure my own program to match the pinout (port 0, device 1 and gpio pin 9) - here is a minimal working example for this device https://shop.pimoroni.com/?q=PIM473

#!/usr/bin/python3

import time

from luma.core.interface.serial import i2c,spi
from luma.core.render import canvas
from luma.oled.device import sh1106

serial = spi(device=1, port=0, gpio_DC=9)

device = sh1106(serial, width=128, height=128, rotate=2)

with canvas(device) as draw:
    draw.rectangle(device.bounding_box, outline="white", fill="black")
    draw.text((10, 40), "Hello World", fill="white")

time.sleep(5)

with canvas(device) as draw:
    draw.rectangle(device.bounding_box, outline="black", fill="white")
    draw.text((10, 40), "Hello World", fill="black")

time.sleep(5)

p.s. Thanks to Shoe for the helpful comments regarding syntax - that line was a complete red herring however, as the canvas object automatically flushes the image when the with block completes, and took me down the wrong path. I think it was the ordering of the parameters and tired eyes that made me think (device 0, port 1) was targeting spidev0.1 - plus I omitted the gpio pin. Sadly, even with this now working code, I still could not get spi1 to work yet, even with the demos, however I guess those pins can now be used for something else.

that line was a complete red herring however, as the canvas object automatically flushes the image when the with block completes

Ah, interesting. Glad you got it working anyway.