1.12 SPI OLED . > Micropython?

I have the 1.12 SPi OLED Breakout

Plugged into Pico Breakout Garden Pack.

Wich I’m trying to get working in Micro Python. There is no Pimoroni support for this setup so I hunted around online and found this.

I have the sh1107.py downloaded and saved to the Pico.
And I’m attempting to modify this file to work with the Breakout garden setup.

from machine import Pin, SPI
import sh1107
import time

# 1. Setup SPI (adjust baudrate and pins for your board)
# Example for Raspberry Pi Pico
spi = SPI(0, baudrate=1000000, polarity=0, phase=0,
          sck=Pin(2), mosi=Pin(3), miso=Pin(4))

# 2. Setup Control Pins
reset_pin = Pin(14, Pin.OUT)
dc_pin = Pin(13, Pin.OUT)
cs_pin = Pin(15, Pin.OUT)

# 3. Initialize Display Driver
display = sh1107.SH1107_SPI(128, 128, spi, dc=dc_pin, res=reset_pin, cs=cs_pin)

# 4. Draw to Display
display.fill(0) # Clear screen
display.text('Hello MicroPython!', 0, 0, 1)
display.show()

The dc_pin = Pin(13, Pin.OUT) and cs_pin = Pin(15, Pin.OUT) don’t make sense to me?
GP 2 is SCK SPIO 0
GP 3 is TX SPIO 0
GP 4 is RX SPIO 0
But GP 13 is SPI 1 CSn?
And GP 15 is SPI 1 TX?

So this is what I have so far.

from machine import Pin, SPI
import sh1107
import time

# 1. Setup SPI (adjust baudrate and pins for your board)
# Example for Raspberry Pi Pico
spi = SPI(0, baudrate=1000000, polarity=0, phase=0,
          sck=Pin(18), mosi=Pin(19), miso=Pin(16))

# 2. Setup Control Pins
#reset_pin = Pin(14, Pin.OUT)
dc_pin = Pin(22, Pin.OUT)
cs_pin = Pin(17, Pin.OUT)

# 3. Initialize Display Driver
display = sh1107.SH1107_SPI(128, 128, spi, dc=dc_pin, cs=cs_pin)

# 4. Draw to Display
display.fill(0) # Clear screen
display.text('Hello MicroPython!', 0, 0, 1)
display.show()

All I get is a flash to all black, and then snow.

The SPI slot on the pack uses the following
GP 22 - Pin 29 - GPIO (DC)
GP 19 - Pin 25 - MOSI (TX)
GP 18 - Pin 24 - SCLK
GP 17 - Pin 22 - CS
GP 16 - Pin 21 - MISO (RX)

DC and CS are normal GPIOs, they are not related to the hardware SPI units and can be any pins. So your choice is fine, but 13 and 15 are also ok unless you need SPI1 for something else.

The demo example from the Git-repo you linked to has an additional method call:

display.sleep(False)

directly after the display is created. Maybe that is the reason it does not work.

Added that and it made no difference. I’m trying to set my pin assignments to work with the Breakout Garden Pack.
I did a forum search, and a few others here have used this driver with that display. I didn’t see any posted working code though?
Pimoroni have working Micro Python code for the i2c version, but nothing listed for the SPI version. I hadn’t noticed that at time of purchase.
I don’t need a color display but I may just swap in a 0.96" SPI Colour LCD (160x80) Breakout. I have a couple of those in my parts box.

They recommend a different library on the shop page. Maybe that is worth a try.

Ah, I Don’t see any link to a Micro Python driver?
Just the Python Luma stuff?

Thanks for trying.
I’m going to go poke around on the Authers site of the driver i’m trying to use.

Oh yes, sorry. Another thing to try: play arround with polarity and phase. I don’t really think this is the problem, since your explicit values are the defaults and the author does not pass these parameters in his examples (so using the defaults).

Also worth trying: since this is a square display, you don’t know how it is physically mounted. Try passing rotate=90 to the constructor. The rotation parameter defines how the pixels in the underlying framebuffer are encoded.

I think today I’ll do some hardware checks. The Breakout Garden Pack and OLED are brand new, never been used before. First i’m going to put a known good color SPI LCD in place of the OLED and make sure that the SPI works on the Pack.
Then plug the OLED into a Pi and make sure it works.
I also have this to use if i have to, for testing. Old school solder-less breadboard etc.

OK, I swapped in one of these,

And the balls demo ran just fine. Now I know there are no issues with the Pico Breakout Garden Pack. I have two Encoder Breakouts in the two i2c slots that are both working just fine. I did an address change on one of them. ;)

I’m going to just add to this post as i check things out.

Oh my god, could they have made this any more tedious, and complicated. =(
Went here,
Software — Luma.OLED: Display drivers for SSD1305, SSD1306, SSD1309, SSD1315, SSD1316, SSD1322, SSD1322_NHD, SSD1325, SSD1327, SSD1331, SSD1351, SSD1362, SH1106, SH1107, WS0010, WINSTAR_WEH, CH1115 3.15.0 documentation
and did all the install stuff.
Then went here,
GitHub - rm-hull/luma.examples: Companion repo for running examples against the luma.oled, luma.lcd, luma.led_matrix and luma.emulator display drivers. · GitHub
and did all that. That got me this and a blank display?

kyrie@raspberrypi:~ $ git clone https://github.com/rm-hull/luma.examples.git
Cloning into 'luma.examples'...
remote: Enumerating objects: 1124, done.
remote: Counting objects: 100% (378/378), done.
remote: Compressing objects: 100% (100/100), done.
remote: Total 1124 (delta 317), reused 278 (delta 276), pack-reused 746 (from 1)
Receiving objects: 100% (1124/1124), 5.61 MiB | 2.80 MiB/s, done.
Resolving deltas: 100% (728/728), done.
kyrie@raspberrypi:~ $ cd luma.examples
kyrie@raspberrypi:~/luma.examples $ python3 -m venv ~/luma-env
kyrie@raspberrypi:~/luma.examples $ ~/luma-env/bin/python -m pip install -e .
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Obtaining file:///home/kyrie/luma.examples
  Installing build dependencies ... done
  Checking if build backend supports build_editable ... done
  Getting requirements to build editable ... done
  Preparing editable metadata (pyproject.toml) ... done
Requirement already satisfied: luma.core>=2.4.0 in /home/kyrie/luma-env/lib/python3.13/site-packages (from luma.examples==0.0.0) (2.5.3)
Collecting luma.emulator>=1.3.0 (from luma.examples==0.0.0)
  Downloading https://www.piwheels.org/simple/luma-emulator/luma_emulator-1.7.0-py2.py3-none-any.whl.metadata (9.7 kB)
Requirement already satisfied: luma.oled>=3.6.0 in /home/kyrie/luma-env/lib/python3.13/site-packages (from luma.examples==0.0.0) (3.15.0)
Collecting luma.lcd>=2.5.0 (from luma.examples==0.0.0)
  Downloading https://www.piwheels.org/simple/luma-lcd/luma_lcd-2.13.0-py2.py3-none-any.whl.metadata (15 kB)
Collecting luma.led_matrix>=1.5.0 (from luma.examples==0.0.0)
  Downloading https://www.piwheels.org/simple/luma-led-matrix/luma_led_matrix-1.9.0-py2.py3-none-any.whl.metadata (17 kB)
Collecting argcomplete (from luma.examples==0.0.0)
  Downloading https://www.piwheels.org/simple/argcomplete/argcomplete-3.7.0-py3-none-any.whl.metadata (16 kB)
Collecting psutil (from luma.examples==0.0.0)
  Downloading psutil-7.2.2-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.metadata (22 kB)
Requirement already satisfied: pillow>=9.2.0 in /home/kyrie/luma-env/lib/python3.13/site-packages (from luma.core>=2.4.0->luma.examples==0.0.0) (12.3.0)
Requirement already satisfied: smbus2 in /home/kyrie/luma-env/lib/python3.13/site-packages (from luma.core>=2.4.0->luma.examples==0.0.0) (0.6.1)
Requirement already satisfied: cbor2 in /home/kyrie/luma-env/lib/python3.13/site-packages (from luma.core>=2.4.0->luma.examples==0.0.0) (6.1.3)
Collecting pygame (from luma.emulator>=1.3.0->luma.examples==0.0.0)
  Downloading pygame-2.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.metadata (12 kB)
Downloading https://www.piwheels.org/simple/luma-emulator/luma_emulator-1.7.0-py2.py3-none-any.whl (27 kB)
Downloading https://www.piwheels.org/simple/luma-lcd/luma_lcd-2.13.0-py2.py3-none-any.whl (34 kB)
Downloading https://www.piwheels.org/simple/luma-led-matrix/luma_led_matrix-1.9.0-py2.py3-none-any.whl (14 kB)
Downloading https://www.piwheels.org/simple/argcomplete/argcomplete-3.7.0-py3-none-any.whl (42 kB)
Downloading psutil-7.2.2-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (156 kB)
Downloading pygame-2.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (13.6 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 13.6/13.6 MB 2.8 MB/s eta 0:00:00
Building wheels for collected packages: luma.examples
  Building editable for luma.examples (pyproject.toml) ... done
  Created wheel for luma.examples: filename=luma_examples-0.0.0-0.editable-py3-none-any.whl size=9244 sha256=d4d33071d01132d37818f6c76fa1938b97d5e605b628e87714edb6bf31d86df1
  Stored in directory: /tmp/pip-ephem-wheel-cache-zy6kvq0o/wheels/74/74/7c/13dcf0ca90af68d5c920fe7f99d5a32da75464ecd13503c16b
Successfully built luma.examples
Installing collected packages: pygame, psutil, argcomplete, luma.led_matrix, luma.lcd, luma.emulator, luma.examples
Successfully installed argcomplete-3.7.0 luma.emulator-1.7.0 luma.examples-0.0.0 luma.lcd-2.13.0 luma.led_matrix-1.9.0 psutil-7.2.2 pygame-2.6.1
kyrie@raspberrypi:~/luma.examples $ ~/luma-env/bin/python 3d_box.py
/home/kyrie/luma-env/bin/python: can't open file '/home/kyrie/luma.examples/3d_box.py': [Errno 2] No such file or directory
kyrie@raspberrypi:~/luma.examples $ cd examples
kyrie@raspberrypi:~/luma.examples/examples $ ~/luma-env/bin/python 3d_box.py
usage: 3d_box.py [-h] [--config CONFIG] [--display DISPLAY] [--width WIDTH] [--height HEIGHT] [--rotate ROTATION] [--interface INTERFACE] [--i2c-port I2C_PORT] [--i2c-address I2C_ADDRESS] [--spi-port SPI_PORT] [--spi-device SPI_DEVICE]
                 [--spi-bus-speed SPI_BUS_SPEED] [--spi-transfer-size SPI_TRANSFER_SIZE] [--spi-mode SPI_MODE] [--spi-cs-high SPI_CS_HIGH] [--ftdi-device FTDI_DEVICE] [--framebuffer-device FRAMEBUFFER_DEVICE] [--gpio GPIO]
                 [--gpio-mode GPIO_MODE] [--gpio-data-command GPIO_DATA_COMMAND] [--gpio-chip-select GPIO_CHIP_SELECT] [--gpio-reset GPIO_RESET] [--gpio-backlight GPIO_BACKLIGHT] [--gpio-reset-hold-time GPIO_RESET_HOLD_TIME]
                 [--gpio-reset-release-time GPIO_RESET_RELEASE_TIME] [--block-orientation ORIENTATION] [--mode MODE] [--framebuffer FRAMEBUFFER] [--num-segments NUM_SEGMENTS] [--bgr] [--inverse] [--h-offset H_OFFSET]
                 [--v-offset V_OFFSET] [--backlight-active VALUE] [--debug] [--transform TRANSFORM] [--scale SCALE] [--duration DURATION] [--loop LOOP] [--max-frames MAX_FRAMES]
3d_box.py: error: I2C device not found on address: 0x3C
kyrie@raspberrypi:~/luma.examples/examples $ 

V_V

EDIT: Apologies if I sound cranky. Just a bit frustrated. I wasn’t expecting this to be this complicated.

I think you have to tell the example program which interface to use. In your case this is spi. No idea on how exactly you have to pass this information, but there are a number of program options printed out (--interface INTERFACE).

This is one of the extremely big advantages of running CircuitPython instead of MicroPython: library management is so much simpler. Ok, doesn’t help you in this case, but there are regular comments in the forums here on how complicated CircuitPython is. But it really depends on what you are doing.

Ok, thanks for that interface info. I have chronic pain issues, and it acts up a bit after long stints at the keyboard. Then I get frustrated and make mistakes. I’ll give it another try but pace myself this time.

I have several of the i2c version of that OLED Breakout, and it was relatively easy getting them going. My Bad for not looking closer at the difference in setup etc for the SPI version.
On the plus side, the 0.96" colour LCD (160x80 pixels) breakout is a nice fit, and looks better. And I think I’ll be able to fit the info I want in there. The two encoders will move two servo’s. Pan and Tilt. The LCD is going to display the position form +90 to -90 for each one. That’s the plan anyway. Basically 7 characters of text.

I tinkered with Circuit Python. I had an Adafruit LED Matrix Panel controller. I can’t remember what they called it, it was RP2040 based. I struggled quite badly with Adafruits graphics software. I switched to an Interstate 75 W.

I just recently built this Pan Tilt Camera setup.

The Pi is running Motion Eye OS. And the Pan Tilt Servos are controlled by the Encoders via a Tiny 2040. I had an Idea of splitting up the Pan Tilt setup for remote control. The Encoders to a Pico W, then another Pico W controlling the servo’s. One talking to the other over WIFI, or maybe BlueTooth.

As a starting point I built this.

The Pico Breakout garden Pack is i2c SPI i2c. Minimal soldering and running wires etc with the Omnibus. Which is why I went with the SPI OLED. I went OLED because I don’t need a color display, and I figured it would give me good viewing, even in bright light conditions.

Right now I’m just relaxing, sipping a coffee, contemplating my next move.

Doah, if I had read just the little bit futer, I would have spotted that.

kyrie@raspberrypi:~/luma.examples/examples $ ~/luma-env/bin/python demo.py --interface gpio_cs_spi
Traceback (most recent call last):
  File "/home/kyrie/luma.examples/examples/demo.py", line 107, in <module>
    main()
    ~~~~^^
  File "/home/kyrie/luma.examples/examples/demo.py", line 62, in main
    device = get_device()
  File "/home/kyrie/luma.examples/examples/demo_opts.py", line 59, in get_device
    device = cmdline.create_device(args)
  File "/home/kyrie/luma-env/lib/python3.13/site-packages/luma/core/cmdline.py", line 240, in create_device
    device = Device(serial_interface=interface(), **params)
                                     ~~~~~~~~~^^
  File "/home/kyrie/luma-env/lib/python3.13/site-packages/luma/core/cmdline.py", line 164, in gpio_cs_spi
    return gpio_cs_spi(port=self.opts.spi_port,
                       device=self.opts.spi_device,
    ...<8 lines>...
                       gpio_CS=self.opts.gpio_chip_select,
                       gpio=self.gpio or GPIO)
  File "/home/kyrie/luma-env/lib/python3.13/site-packages/luma/core/interface/serial.py", line 346, in __init__
    super(gpio_cs_spi, self).__init__(*args, **kwargs)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/home/kyrie/luma-env/lib/python3.13/site-packages/luma/core/interface/serial.py", line 302, in __init__
    bitbang.__init__(self, gpio, transfer_size, reset_hold_time, reset_release_time, DC=gpio_DC, RST=gpio_RST)
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/kyrie/luma-env/lib/python3.13/site-packages/luma/core/interface/serial.py", line 185, in __init__
    self._gpio = gpio or self.__rpi_gpio__()
                         ~~~~~~~~~~~~~~~~~^^
  File "/home/kyrie/luma-env/lib/python3.13/site-packages/luma/core/lib.py", line 23, in __rpi_gpio__
    import RPi.GPIO as GPIO
ModuleNotFoundError: No module named 'RPi'
kyrie@raspberrypi:~/luma.examples/examples $ 

kyrie@raspberrypi:~/luma.examples/examples $ ~/luma-env/bin/python demo.py --interface spi
Traceback (most recent call last):
  File "/home/kyrie/luma.examples/examples/demo.py", line 107, in <module>
    main()
    ~~~~^^
  File "/home/kyrie/luma.examples/examples/demo.py", line 62, in main
    device = get_device()
  File "/home/kyrie/luma.examples/examples/demo_opts.py", line 59, in get_device
    device = cmdline.create_device(args)
  File "/home/kyrie/luma-env/lib/python3.13/site-packages/luma/core/cmdline.py", line 240, in create_device
    device = Device(serial_interface=interface(), **params)
                                     ~~~~~~~~~^^
  File "/home/kyrie/luma-env/lib/python3.13/site-packages/luma/core/cmdline.py", line 150, in spi
    return spi(port=self.opts.spi_port,
               device=self.opts.spi_device,
    ...<6 lines>...
               gpio_RST=self.opts.gpio_reset,
               gpio=self.gpio or GPIO)
  File "/home/kyrie/luma-env/lib/python3.13/site-packages/luma/core/interface/serial.py", line 302, in __init__
    bitbang.__init__(self, gpio, transfer_size, reset_hold_time, reset_release_time, DC=gpio_DC, RST=gpio_RST)
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/kyrie/luma-env/lib/python3.13/site-packages/luma/core/interface/serial.py", line 185, in __init__
    self._gpio = gpio or self.__rpi_gpio__()
                         ~~~~~~~~~~~~~~~~~^^
  File "/home/kyrie/luma-env/lib/python3.13/site-packages/luma/core/lib.py", line 23, in __rpi_gpio__
    import RPi.GPIO as GPIO
ModuleNotFoundError: No module named 'RPi'
kyrie@raspberrypi:~/luma.examples/examples $ 


This seems to be one of the old drivers that still use this old RPi-module.

Have you tried the rotation parameter on the MicroPython lib you tried first? Maybe that got lost.

The information in the notes section on the shop page suggests you need to supply quite a few of those parameters:

With the SPI version, you can run an example like so: python3 bounce.py --display sh1106 --height 128 --rotate 2 --interface spi --gpio-data-command 9 (add --spi-device 0 for the back slot, or --spi-device 1 for the front slot)

If you’re still getting the error about RPi.GPIO then pip install rpi-lgpio might help perhaps, assuming you’re running a recent version of Pi OS?

(you might to activate the virtual environment first - source ~/luma_env/bin/activate)

@hel Apologies, ops, I got as far as the git clone part, and started trying to run the examples and missed the rest of the info on the shop page. I was following this and didn’t go back to the shop page.

I am activating the virtual environment, and it’s the most recent Pi OS.

@bablokb I will revisit that and try the rotate. I have it plugged into my Pi 400 and I’m plugging away in Python at the moement.

kyrie@raspberrypi:~/luma.examples/examples $ ~/luma-env/bin/python demo.py --display sh1106 --height 128 --rotate 2 --interface spi --gpio-data-command 9
Traceback (most recent call last):
  File "/home/kyrie/luma.examples/examples/demo.py", line 107, in <module>
    main()
    ~~~~^^
  File "/home/kyrie/luma.examples/examples/demo.py", line 62, in main
    device = get_device()
  File "/home/kyrie/luma.examples/examples/demo_opts.py", line 59, in get_device
    device = cmdline.create_device(args)
  File "/home/kyrie/luma-env/lib/python3.13/site-packages/luma/core/cmdline.py", line 240, in create_device
    device = Device(serial_interface=interface(), **params)
                                     ~~~~~~~~~^^
  File "/home/kyrie/luma-env/lib/python3.13/site-packages/luma/core/cmdline.py", line 150, in spi
    return spi(port=self.opts.spi_port,
               device=self.opts.spi_device,
    ...<6 lines>...
               gpio_RST=self.opts.gpio_reset,
               gpio=self.gpio or GPIO)
  File "/home/kyrie/luma-env/lib/python3.13/site-packages/luma/core/interface/serial.py", line 302, in __init__
    bitbang.__init__(self, gpio, transfer_size, reset_hold_time, reset_release_time, DC=gpio_DC, RST=gpio_RST)
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/kyrie/luma-env/lib/python3.13/site-packages/luma/core/interface/serial.py", line 185, in __init__
    self._gpio = gpio or self.__rpi_gpio__()
                         ~~~~~~~~~~~~~~~~~^^
  File "/home/kyrie/luma-env/lib/python3.13/site-packages/luma/core/lib.py", line 23, in __rpi_gpio__
    import RPi.GPIO as GPIO
ModuleNotFoundError: No module named 'RPi'

kyrie@raspberrypi:~/luma.examples/examples $ pip install rpi-lgpio
error: externally-managed-environment

× This environment is externally managed
╰─> To install Python packages system-wide, try apt install
python3-xyz, where xyz is the package you are trying to
install.

If you wish to install a non-Debian-packaged Python package,
create a virtual environment using python3 -m venv path/to/venv.
Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make
sure you have python3-full installed.

For more information visit http://rptl.io/venv

I don’t think you have your venv active there?

I didn’t clip and past that part. First thing after opening the terminal window I did

kyrie@raspberrypi:~ $ python3 -m venv ~/luma-env
kyrie@raspberrypi:~ $ cd luma.examples
kyrie@raspberrypi:~/luma.examples $ cd examples
kyrie@raspberrypi:~/luma.examples/examples $ ~/luma-env/bin/python demo.py --display sh1106 --height 128 --rotate 2 --interface spi --gpio-data-command 9
Traceback (most recent call last):
  File "/home/kyrie/luma.examples/examples/demo.py", line 107, in <module>
    main()
    ~~~~^^
  File "/home/kyrie/luma.examples/examples/demo.py", line 62, in main
    device = get_device()
  File "/home/kyrie/luma.examples/examples/demo_opts.py", line 59, in get_device
    device = cmdline.create_device(args)
  File "/home/kyrie/luma-env/lib/python3.13/site-packages/luma/core/cmdline.py", line 240, in create_device
    device = Device(serial_interface=interface(), **params)
                                     ~~~~~~~~~^^
  File "/home/kyrie/luma-env/lib/python3.13/site-packages/luma/core/cmdline.py", line 150, in spi
    return spi(port=self.opts.spi_port,
               device=self.opts.spi_device,
    ...<6 lines>...
               gpio_RST=self.opts.gpio_reset,
               gpio=self.gpio or GPIO)
  File "/home/kyrie/luma-env/lib/python3.13/site-packages/luma/core/interface/serial.py", line 302, in __init__
    bitbang.__init__(self, gpio, transfer_size, reset_hold_time, reset_release_time, DC=gpio_DC, RST=gpio_RST)
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/kyrie/luma-env/lib/python3.13/site-packages/luma/core/interface/serial.py", line 185, in __init__
    self._gpio = gpio or self.__rpi_gpio__()
                         ~~~~~~~~~~~~~~~~~^^
  File "/home/kyrie/luma-env/lib/python3.13/site-packages/luma/core/lib.py", line 23, in __rpi_gpio__
    import RPi.GPIO as GPIO
ModuleNotFoundError: No module named 'RPi'
kyrie@raspberrypi:~/luma.examples/examples $ 

kyrie@raspberrypi:~/luma.examples/examples $ python3 pip install - rpi-lgpioe 
python3: can't open file '/home/kyrie/luma.examples/examples/pip': [Errno 2] No such file or directory
kyrie@raspberrypi:~/luma.examples/examples $ cd
kyrie@raspberrypi:~ $ python3 pip install - rpi-lgpioe 
python3: can't open file '/home/kyrie/pip': [Errno 2] No such file or directory
kyrie@raspberrypi:~ $ 

kyrie@raspberrypi:~ $ python3 pip install rpi-lgpioe 
python3: can't open file '/home/kyrie/pip': [Errno 2] No such file or directory
kyrie@raspberrypi:~ $ 

Sorry for being such a nube, I such at this command line stuff.

display = sh1107.SH1107_SPI(128, 128, spi, dc=dc_pin, cs=cs_pin, rotate=90)

made no difference. Time to revisit the pins he used versus what I’m using? Maybe one or two want a GP number not a Pin number?

No, he wants pins. But I found something spurios: sh1107.SH1107_SPI() calls sh1107.SH1107() with the default delay_ms=0. Note that this is the SPI-default, the default for I2C is 200ms. This delay is only used for the poweron command and it seems strange that the device does not need a delay when using the SPI-interface.

So another thing to try: pass an explicit delay_ms=200 to the constructor.