Skip to content

Commit

Permalink
Add SH1106 display support (#846)
Browse files Browse the repository at this point in the history
* add support for sh1106 oled displays
* replace 'oled' with 'display'

---------

Co-authored-by: xs5871 <60395129+xs5871@users.noreply.github.com>
  • Loading branch information
Anomalocaridid and xs5871 committed Aug 28, 2023
1 parent 10bc63a commit 61eabf5
Show file tree
Hide file tree
Showing 2 changed files with 212 additions and 60 deletions.
104 changes: 74 additions & 30 deletions docs/en/OLED_Display.md → docs/en/Display.md
Original file line number Diff line number Diff line change
@@ -1,48 +1,90 @@
# OLED Display
# Display
Not enough screen space? Add a display to your keyboard!

This documentation concerns the recommended OLED extension.
This documentation concerns the recommended Display extension.

*Note:*
Driving an OLED display can bind up a considerable amount of CPU time and RAM.
Driving a display can bind up a considerable amount of CPU time and RAM.
Be aware of the performance degradation that can occur.

## Preparation
First of all you need to download a few libraries that will make it possible for your OLED to work.
First of all you need to download a few libraries that will make it possible for your display to work.
You can get them with the [Adafruit CircuitPython Libraries bundle](https://circuitpython.org/libraries).
Make sure you to choose the one that matches your version of CircuitPython.

Create a `lib` directory under the CircuitPython drive and copy the following
from the library bundle there:
* `adafruit_display_text/`
* `adafruit_displayio_ssd1306.mpy`

Depending on which kind of display your keyboard has, you may also need a display-specific library. See the below table:

| Display Type | Library to use |
| ------------------------------------------------------------ | -------------------------------- |
| SSD1306 | `adafruit_displayio_ssd1306.mpy` |
| SH1106 | `adafruit_displayio_sh1106.mpy` |
| Already initialized (e.g. available through `board.DISPLAY`) | None |

## Configuration
Here's how you may initialize the extension:
Here's how you may initialize the extension. Note that this includes examples of all currently supported display types and you only need the one that corresponds to your display:

```python
import board
import busio
from kmk.extensions.oled import Oled, TextEntry, ImageEntry

# For SSD1306
from kmk.extensions.display import Display, SSD1306, TextEntry, ImageEntry

# Replace SCL and SDA according to your hardware configuration.
i2c_bus = busio.I2C(board.GP_SCL, board.GP_SDA)

oled = Oled(
driver = SSD1306(
# Mandatory:
i2c=i2c_bus,
# Optional:
device_address=0x3C,
)

# For SH1106
from kmk.extensions.display import Display, SH1106, TextEntry, ImageEntry

# Replace SCK and MOSI according to your hardware configuration.
spi_bus = busio.SPI(board.GP_SCK, board.GP_MOSI)

# Replace command, chip_select, and reset according to your hardware configuration.
driver = SH1106(
# Mandatory:
spi=spi_bus,
command=board.GP_DC,
chip_select=board.GP_CS,
reset=board.GP_RESET,
)

# For displays initialized by CircuitPython by default
from kmk.extensions.display import Display, BuiltInDisplay, TextEntry, ImageEntry

# Replace display, sleep_command, and wake_command according to your hardware configuration.
driver = BuiltInDisplay(
# Mandatory:
display=board.DISPLAY
sleep_command=0xAE
wake_command=0xAF
)

# For all display types
display = Display(
# Mandatory:
display=driver,
# Optional:
width=128, # screen size
height=64, # screen size
height=32, # screen size
flip = False, # flips your display content
flip_left = False, # flips your display content on left side split
flip_right = False, # flips your display content on right side split
dim_time=10, # time in seconds to reduce screen brightness
dim_target=0.1, # set level for brightness decrease
off_time=0, # time in seconds to turn off screen
brightness=1, # initial screen brightness level
brightness=0.8, # initial screen brightness level
brightness_step=0.1, # used for brightness increase/decrease keycodes
dim_time=20, # time in seconds to reduce screen brightness
dim_target=0.1, # set level for brightness decrease
off_time=60, # time in seconds to turn off screen
powersave_dim_time=10, # time in seconds to reduce screen brightness
powersave_dim_target=0.1, # set level for brightness decrease
powersave_off_time=30, # time in seconds to turn off screen
Expand All @@ -58,42 +100,42 @@ have to be placed in the root of the CircuitPython drive.
**Placing it in separate a seperate directory may cause issues.**

```python
oled.entries = [
display.entries = [
ImageEntry(image="1.bmp", x=0, y=0),
]
keyboard.extensions.append(oled)
keyboard.extensions.append(display)
```

You can also make your images appear only on specific layers,

```python
oled.entries = [
display.entries = [
ImageEntry(image="1.bmp", x=0, y=0, layer=0),
ImageEntry(image="2.bmp", x=0, y=0, layer=1),
]
keyboard.extensions.append(oled)
keyboard.extensions.append(display)
```

and/or side of your split keyboard.

```python
oled.entries = [
display.entries = [
ImageEntry(image="L1.bmp", x=0, y=0, side="L"),
ImageEntry(image="R1.bmp", x=0, y=0, side="R"),
]
keyboard.extensions.append(oled)
keyboard.extensions.append(display)
```

## Text
You're able to freely positon your text to place it wherever you want just by changing x and y values.

```python
oled.entries = [
display.entries = [
TextEntry(text="Layer = 1", x=0, y=0),
TextEntry(text="Macros", x=0, y=12),
TextEntry(text="Hey there!", x=0, y=24),
]
keyboard.extensions.append(oled)
keyboard.extensions.append(display)
```

### X and Y anchors
Expand All @@ -106,31 +148,31 @@ For more infos about anchors check the [Adafruit docs](https://learn.adafruit.co
Notable difference: KMK uses strings ("T", "M","B" and "L", "M", "R") instead of numbers.

```python
oled.entries = [
display.entries = [
TextEntry(text="Layer = 1", x=128, y=0, x_anchor="R", y_anchor="T"), # text in Top Right corner
TextEntry(text="Macros", x=128, y=64, x_anchor="R", y_anchor="B"), # text in Bottom Right corner
TextEntry(text="Hey there!", x=64, y=32, x_anchor="M", y_anchor="M"), # text in the Middle of screen
]
keyboard.extensions.append(oled)
keyboard.extensions.append(display)
```

### Split
Same as with images you can change displaying according to current layer or side of split keyboard.

```python
oled.entries = [
display.entries = [
TextEntry(text="Longer text that", x=0, y=0, layer=0),
TextEntry(text="has been divided", x=0, y=12, layer=0, side="L"),
TextEntry(text="for an example", x=0, y=24, layer=0, side="R"),
]
keyboard.extensions.append(oled)
keyboard.extensions.append(display)
```

### Inverting
Inverts colours of your text. Comes in handy, for example, as a good layer indicator.

```python
oled_ext = Oled(
display_ext = Display(
entries=[
TextEntry(text='0 1 2 4', x=0, y=0),
TextEntry(text='0', x=0, y=0, inverted=True, layer=0),
Expand All @@ -148,14 +190,17 @@ from kmk.kmk_keyboard import KMKKeyboard
from kmk.keys import KC
from kmk.scanners import DiodeOrientation
from kmk.modules.layers import Layers
from kmk.extensions.oled import Oled, TextEntry, ImageEntry
from kmk.extensions.display import Display, SSD1306, TextEntry, ImageEntry

keyboard = KMKKeyboard()
layers = Layers()
keyboard.modules.append(layers)

i2c_bus = busio.I2C(board.GP21, board.GP20)
oled = Oled(
display_driver = SSD1306(i2c=i2c_bus)

display = Display(
display=display_driver
entries=[
TextEntry(text='Layer: ', x=0, y=32, y_anchor='B'),
TextEntry(text='BASE', x=40, y=32, y_anchor='B', layer=0),
Expand All @@ -166,7 +211,6 @@ oled = Oled(
TextEntry(text='1', x=12, y=4, inverted=True, layer=1),
TextEntry(text='2', x=24, y=4, inverted=True, layer=2),
],
i2c=i2c_bus,
device_address=0x3C,
width=128,
height=64,
Expand All @@ -176,5 +220,5 @@ oled = Oled(
brightness=1,
)

keyboard.extensions.append(oled)
keyboard.extensions.append(display)
```
Loading

0 comments on commit 61eabf5

Please sign in to comment.