Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SH1106 display support #846

Merged
merged 9 commits into from
Aug 28, 2023
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
Loading