Skip to content

mctechnology17/zmk-nice-oled

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

nice!oled - nice!epaper - nice!custom

nice_oled_demo nice_epaper_demo nice_epaper_demo

Table of Contents

Overview

Warning

TESTED USING ZMK v0.3.0 please see Pin your ZMK version

Vertical widgets for oled and niceview screens using zmk (for split and non-split keyboards)

System Architecture & Implementation Summary

Modular & Submodular Design Strategy

This ZMK module implements a highly decoupled architecture designed for maximum flexibility and extensibility.

  • Modular Widgets: The view layer is fully modular, permitting the runtime selection and composition of any available widget without heavy coupling to the core display logic.
  • Submodular RAW HID: The RAW HID implementation is granular. Submodules such as Temperature, Time, Layout, and Volume can be independently compiled and activated via Kconfig, minimizing flash usage and processing overhead by excluding unused logic.

Abstraction Layer: nice_custom Shield

A dedicated hardware abstraction layer, the nice_custom shield, was developed to decouple driver positioning from physical hardware definitions.

  • Independent Driver Coordinate System: All X/Y rendering coordinates are configurable via the configuration system (runtime/Kconfig) completely independent of the underlying shield definition.
  • Code-Free Customization: Users can reposition drivers and elements to suit non-standard layouts or personal preferences purely through configuration variables, eliminating the need to fork or modify the C source code of the display driver.

Host-Side Integration (Rust)

The companion host application, zmk-hid-host, provides the necessary data bridge for universal Raw HID features (System Time, Volume, Layout) across Linux, Windows, and macOS.

  • Technical Contributions (macOS Enhancements):
    • macOS Temperature Support: Implemented platform-specific temperature monitoring for macOS within the Rust codebase.
    • Spotify Integration: Engineered a native AppleScript/Rust bridge to fetch real-time track metadata from Spotify for display on the peripheral (macOS only).
    • Cross-Architecture Support: Developed a universal macOS application wrapper, bundling native binaries for both Intel (x86_64) and Apple Silicon (arm64) architectures, ensuring seamless deployment across the Apple ecosystem.

Shields supported:

  • nice_oled
  • nice_epaper
  • nice_custom

General characteristics:

General

  • Vertical Layout: Optimized for split keyboard OLED/e-Ink/ePaper screens.
  • Compact Design: Maximizes information density.
  • Modular Widgets: Enable/disable components independently.
  • nice_custom Shield: Position drivers via config, no code required.
  • Neck Strain Reduction: View info on keyboard instead of monitor.
  • Dark Mode Friendly: Optimized for nice!oled.

Central Screen

  • WPM Widgets: Graphs, Speedometer, Luna, Bongo Cat.
  • HID Indicators: CapsLock status with Luna/Bongo Cat animations.
  • Modifiers Widget: Real-time display of Ctrl, Shift, Alt, Gui.
  • Raw HID Integration:
    • Spotify (macOS): Real-time track information.
    • Weather: Current temperature display.
    • System Sync: Volume, Time, and Keyboard Layout.

Peripheral Screen

  • Vertical Animations: Gem, Cat, Head, Pokemon, Spaceman.
  • Smart Battery: Efficient battery status animation.
  • Sleep Art: Custom images during idle/sleep.
  • Static Images: Vim, Custom Logos (low power mode).

Gallery

demo3 demo2 demo1 demo4 Animation Preview preview1

Quick Installation

Tip

All widgets are enabled hid, modifiers, wpm etc., if you want to disable them, look at the configuration section

Installation in 4 simple steps:

  1. Configuration example? You should see this -> zmk-config

  2. Make sure to enable the custom status screen in your *.conf file:

CONFIG_ZMK_DISPLAY=y
CONFIG_ZMK_DISPLAY_STATUS_SCREEN_CUSTOM=y
  1. Copy and paste this into your config/west.yml file:
manifest:
  remotes:
    - name: zmkfirmware
      url-base: https://github.com/zmkfirmware
    # support nice_oled and nice_epaper
    - name: mctechnology17
      url-base: https://github.com/mctechnology17
  projects:
    - name: zmk
      remote: zmkfirmware
      revision: main
      import: app/west.yml
    # support nice_oled and nice_epaper
    - name: zmk-nice-oled
      remote: mctechnology17
      revision: main
  self:
    path: config
  1. In the build.yaml file, add the nice_oled shield (using the corne as an example, but it could be another shield).

For oled screen:

---
include:
  - board: nice_nano_v2
    shield: corne_left nice_oled
  - board: nice_nano_v2
    shield: corne_right nice_oled

For niceview screen:

---
include:
  - board: nice_nano_v2
    shield: corne_left nice_view_adapter nice_epaper
  - board: nice_nano_v2
    shield: corne_right nice_view_adapter nice_epaper
  1. Build the firmware, flash it to your keyboard, and enjoy!

Configuration

Important

Make sure to enable the custom status screen in your ZMK configuration:

Make sure to enable the custom status screen in your ZMK configuration:

CONFIG_ZMK_DISPLAY=y
CONFIG_ZMK_DISPLAY_STATUS_SCREEN_CUSTOM=y

Anatomy of the variables of this repository

This document lists the available configuration options for the nice_oled shield. These variables can be set in your .conf file to customize the behavior of the display widgets.

General Configuration

Variable Type Default Description
CONFIG_NICE_OLED_ON bool y Enable nice oled widget compatibility
CONFIG_NICE_EPAPER_ON bool n Enable nice view widget compatibility
CONFIG_LV_Z_VDB_SIZE int 64 (OLED), 100 (ePaper) Buffer size for LVGL
CONFIG_LV_DPI_DEF int 148 (OLED), 161 (ePaper) Dots per inch (DPI) setting
CONFIG_LV_Z_BITS_PER_PIXEL int 1 Bits per pixel
CONFIG_LV_COLOR_DEPTH choice LV_COLOR_DEPTH_1 Color depth
CONFIG_ZMK_DISPLAY_WORK_QUEUE choice ZMK_DISPLAY_WORK_QUEUE_DEDICATED Work queue type
CONFIG_ZMK_DISPLAY_STATUS_SCREEN choice ZMK_DISPLAY_STATUS_SCREEN_CUSTOM Status screen type
CONFIG_LV_Z_MEM_POOL_SIZE int 8192 Memory pool size
CONFIG_ZMK_DISPLAY_DEDICATED_THREAD_STACK_SIZE int 2560 (3072 with RAW HID) Display thread stack size
CONFIG_ZMK_DISPLAY_DEDICATED_THREAD_PRIORITY int 5 Display thread priority (lower = higher priority)
CONFIG_NICE_OLED_WIDGET_STATUS bool - Custom nice oled status widget (Selects LVGL features)
CONFIG_NICE_OLED_WIDGET_INVERTED bool n Invert display colors
CONFIG_NICE_OLED_WIDGET_OUTPUT_BACKGROUND bool n (OLED), y (ePaper) Enable output background on central and peripheral
CONFIG_NICE_OLED_CUSTOM_CANVAS_WIDTH int 68 (ePaper), 32 (OLED) Custom Canvas Width overwriting default calculation
CONFIG_NICE_OLED_CUSTOM_CANVAS_HEIGHT int 160 (ePaper), 128 (OLED) Custom Canvas Height overwriting default calculation

Sleep & Animation (Central & Peripheral)

Variable Type Default Description
CONFIG_NICE_OLED_SHOW_SLEEP_ART_ON_IDLE bool n Whether the sleep art should be shown on idle
CONFIG_NICE_OLED_SHOW_SLEEP_ART_ON_SLEEP bool n Whether the sleep art should be shown on sleep

Peripheral Specific

Variable Type Default Description
CONFIG_NICE_OLED_WIDGET_ANIMATION_PERIPHERAL_SMART_BATTERY bool n Enable smart battery animation on peripheral
CONFIG_NICE_OLED_WIDGET_ANIMATION_PERIPHERAL_WPM bool n Enable PERIPHERAL WPM widget compatibility
CONFIG_NICE_OLED_WIDGET_ANIMATION_PERIPHERAL bool y Enable animation on peripheral
CONFIG_NICE_OLED_WIDGET_STATIC_IMAGE_PERIPHERAL bool y (if no anim) Enable static image on peripheral
CONFIG_NICE_OLED_WIDGET_ANIMATION_PERIPHERAL_GEM bool n Enable gem animation on peripheral
CONFIG_NICE_OLED_WIDGET_ANIMATION_PERIPHERAL_CAT bool y Enable cat animation on peripheral
CONFIG_NICE_OLED_WIDGET_ANIMATION_PERIPHERAL_HEAD bool n Enable head animation on peripheral
CONFIG_NICE_OLED_WIDGET_ANIMATION_PERIPHERAL_POKEMON bool n Enable pokemon animation on peripheral
CONFIG_NICE_OLED_WIDGET_ANIMATION_PERIPHERAL_SPACEMAN bool n Enable spaceman animation on peripheral
CONFIG_NICE_OLED_WIDGET_ANIMATION_PERIPHERAL_MS int varies Animation length in milliseconds
CONFIG_NICE_OLED_WIDGET_STATIC_IMAGE_PERIPHERAL_VIM bool n Enable static vim on peripheral
CONFIG_NICE_OLED_WIDGET_STATIC_IMAGE_PERIPHERAL_VIP_MARCOS bool n Enable static vim_marcos on peripheral
CONFIG_NICE_OLED_WIDGET_PERIPHERAL bool n Enable test widget on peripheral

Central Specific

Variable Type Default Description
CONFIG_NICE_OLED_WIDGET_WPM bool y Enable Nice OLED WPM Widget
CONFIG_NICE_OLED_WIDGET_WPM_NUMBER bool y Enable NUMBER for WPM
CONFIG_NICE_OLED_WIDGET_WPM_SPEEDOMETER bool y (OLED) Enable SPEEDOMETER for WPM
CONFIG_NICE_OLED_WIDGET_WPM_GRAPH bool n (OLED) Enable GRAPH for WPM gauge/chart
CONFIG_NICE_OLED_WIDGET_WPM_GRAPH_FIXED_RANGE bool y Enable fixed range for WPM gauge/chart
CONFIG_NICE_OLED_WIDGET_WPM_GRAPH_FIXED_RANGE_MAX int 100 Fixed range maximum for WPM gauge/chart
CONFIG_NICE_OLED_WIDGET_WPM_LUNA bool y Enable wpm luna
CONFIG_NICE_OLED_WIDGET_WPM_LUNA_ANIMATION_MS int 300 Luna Animation in ms for WPM Widget
CONFIG_NICE_OLED_WIDGET_WPM_BONGO_CAT bool n Enable wpm bongo cat
CONFIG_NICE_OLED_WIDGET_WPM_BONGO_CAT_ANIMATION_MS int 300 Bongo Cat Animation in ms for WPM Widget

| CONFIG_NICE_OLED_WIDGET_RESPONSIVE | bool | n | Enable widget responsive (overrides stack to 4096, priority to 3) | | CONFIG_NICE_OLED_WIDGET_RESPONSIVE_BONGO_CAT | bool | n | Enable widget responsive bongo cat |

HID Indicators

Variable Type Default Description
CONFIG_NICE_OLED_WIDGET_HID_INDICATORS bool y Enable HID indicators
CONFIG_ZMK_HID_INDICATORS bool y Enable HID indicators (Core ZMK)
CONFIG_NICE_OLED_WIDGET_HID_INDICATORS_LUNA bool n Enable HID indicators luna
CONFIG_NICE_OLED_WIDGET_HID_INDICATORS_LUNA_ONLY_CAPSLOCK bool n Enable HID indicators luna only on CapsLock
CONFIG_NICE_OLED_WIDGET_HID_INDICATORS_LUNA_ANIMATION_MS int 300 Luna Animation in ms for HID Indicators
CONFIG_NICE_OLED_WIDGET_HID_INDICATORS_BONGO_CAT bool n Enable HID indicators bongo cat
CONFIG_NICE_OLED_WIDGET_HID_INDICATORS_BONGO_CAT_ONLY_CAPSLOCK bool n Enable HID indicators bongo cat only on CapsLock
CONFIG_NICE_OLED_WIDGET_HID_INDICATORS_BONGO_CAT_ANIMATION_MS int 300 Luna Animation in ms for HID Indicators bongo cat

Raw HID

Variable Type Default Description
CONFIG_NICE_OLED_WIDGET_RAW_HID bool - Enable RAW HID
CONFIG_NICE_OLED_WIDGET_RAW_HID_DRIVER bool y Enable Raw HID
CONFIG_USB_HID_DEVICE_COUNT int 2 Enable CONFIG USB HID DEVICE COUNT

| CONFIG_NICE_OLED_WIDGET_RAW_HID_TIME | bool | y | Show time | | CONFIG_NICE_OLED_WIDGET_RAW_HID_VOLUME | bool | y | Show volume | | CONFIG_NICE_OLED_WIDGET_RAW_HID_USAGE_PAGE | hex | 0xFF60 | Raw HID Usage Page | | CONFIG_NICE_OLED_WIDGET_RAW_HID_USAGE | hex | 0x61 | Raw HID Usage | | CONFIG_NICE_OLED_WIDGET_RAW_HID_REPORT_SIZE | int | 32 | Raw HID Report Size | | CONFIG_NICE_OLED_WIDGET_RAW_HID_DEVICE | string | HID_1 | Raw HID Device | | CONFIG_NICE_OLED_WIDGET_RAW_HID_LAYOUT | bool | y | Show layout | | CONFIG_NICE_OLED_WIDGET_RAW_HID_LAYOUT_LIST | string | "DE,US,LA,AB" | Comma-separated layout list | | CONFIG_NICE_OLED_WIDGET_RAW_HID_WEATHER | bool | n | nice!OLED Weather Widget | | CONFIG_NICE_OLED_WIDGET_RAW_HID_MEDIA_PLAYER_SPOTIFY_MACOS | bool | n | nice!OLED Spotify MacOS Media Player Widget |

Modifiers Indicators

Variable Type Default Description
CONFIG_NICE_OLED_WIDGET_MODIFIERS_INDICATORS bool y Enable modifiers indicators
CONFIG_NICE_OLED_WIDGET_MODIFIERS_INDICATORS_FIXED bool y Enable modifiers indicators fixed
CONFIG_NICE_OLED_WIDGET_MODIFIERS_INDICATORS_FIXED_LETTER bool n Style: Letters (Text C/S/A/G)
CONFIG_NICE_OLED_WIDGET_MODIFIERS_INDICATORS_FIXED_SYMBOL bool y Style: Real icons (Default)
CONFIG_NICE_OLED_WIDGET_MODIFIERS_INDICATORS_FIXED_HOR bool n Layout: Horizontal
CONFIG_NICE_OLED_WIDGET_MODIFIERS_INDICATORS_FIXED_VER bool n Layout: Vertical
CONFIG_NICE_OLED_WIDGET_MODIFIERS_INDICATORS_FIXED_BOX bool y Layout: Box/Grid (Default)
CONFIG_NICE_OLED_WIDGET_MODIFIERS_INDICATORS_FIXED_VER_ALIGN_LEFT bool n Vertical Align: Left
CONFIG_NICE_OLED_WIDGET_MODIFIERS_INDICATORS_FIXED_VER_ALIGN_CENTER bool y Vertical Align: Center (Default)
CONFIG_NICE_OLED_WIDGET_MODIFIERS_INDICATORS_FIXED_VER_ALIGN_RIGHT bool n Vertical Align: Right
CONFIG_NICE_OLED_WIDGET_MODIFIERS_INDICATORS_FIXED_SYMBOL_MACOS bool y OS Style: macOS (Default)
CONFIG_NICE_OLED_WIDGET_MODIFIERS_INDICATORS_FIXED_SYMBOL_WINDOWS bool n OS Style: Windows
CONFIG_NICE_OLED_WIDGET_MODIFIERS_INDICATORS_LUNA bool n Enable modifiers indicators luna
CONFIG_NICE_OLED_WIDGET_MODIFIERS_INDICATORS_LUNA_ANIMATION_MS int 300 Luna Animation in ms for Modifiers Indicators

Symbol Icons

When using SYMBOL style, the following real icons are displayed:

macOS mode (default):

  • Control: (caret symbol)
  • Shift: (upward arrow)
  • Option: (option key symbol)
  • Command: (command/clover symbol)

Windows mode:

  • Control: (caret symbol)
  • Shift: (upward arrow)
  • Alt: Alt text icon
  • Win: Windows logo

Other Widgets (Central)

Variable Type Default Description
CONFIG_NICE_OLED_WIDGET_LAYER bool y Enable layer widget
CONFIG_NICE_OLED_WIDGET_PROFILE_BIG bool n Enable show widget profile bigger
CONFIG_NICE_OLED_WIDGET_CENTRAL bool n Enable test widget on central

Battery Widget (Experimental)

Variable Type Default Description
CONFIG_NICE_OLED_WIDGET_CENTRAL_SHOW_BATTERY_PERIPHERAL_ALL bool n View all available batteries on the central screen, including the central battery
CONFIG_NICE_OLED_WIDGET_CENTRAL_SHOW_BATTERY_PERIPHERAL_ONLY bool n View all peripheral batteries, but not the central battery
CONFIG_NICE_OLED_WIDGET_CENTRAL_SHOW_BATTERY_PERIPHERAL_AND_CENTRAL bool n View only 1 peripheral batterie and the central battery

Widget Position Coordinates

These variables allow users to customize widget positions. Each widget has X and Y coordinates that can be set in your .conf file. The defaults are set per shield (OLED vs ePaper).

Layer Widget Position

Variable Type Default OLED Default ePaper Description
CONFIG_NICE_OLED_WIDGET_LAYER_CUSTOM_X int 0 0 Layer widget X position
CONFIG_NICE_OLED_WIDGET_LAYER_CUSTOM_Y int 146 146 Layer widget Y position

Battery Widget Position

Variable Type Default OLED Default ePaper Description
CONFIG_NICE_OLED_WIDGET_BATTERY_CUSTOM_X int 0 26 Battery widget X position
CONFIG_NICE_OLED_WIDGET_BATTERY_CUSTOM_Y int 50 19 Battery widget Y position

Profile Widget Position

Variable Type Default OLED Default ePaper Description
CONFIG_NICE_OLED_WIDGET_PROFILE_CUSTOM_X int 0 18 Profile widget X position
CONFIG_NICE_OLED_WIDGET_PROFILE_CUSTOM_Y int 137 129 Profile widget Y position
CONFIG_NICE_OLED_WIDGET_PROFILE_TEXT_CUSTOM_X int 25 25 Profile text X position
CONFIG_NICE_OLED_WIDGET_PROFILE_TEXT_CUSTOM_Y int 32 32 Profile text Y position

Output Widget Position

Variable Type Default OLED Default ePaper Description
CONFIG_NICE_OLED_WIDGET_OUTPUT_USB_CUSTOM_X int 0 45 Output USB icon X position
CONFIG_NICE_OLED_WIDGET_OUTPUT_USB_CUSTOM_Y int 34 2 Output USB icon Y position
CONFIG_NICE_OLED_WIDGET_OUTPUT_BT_CUSTOM_X int 4 49 Output BT icon X position
CONFIG_NICE_OLED_WIDGET_OUTPUT_BT_CUSTOM_Y int 32 0 Output BT icon Y position
CONFIG_NICE_OLED_WIDGET_OUTPUT_BT_UNBONDED_CUSTOM_X int -1 44 Output BT unbonded icon X position
CONFIG_NICE_OLED_WIDGET_OUTPUT_BT_UNBONDED_CUSTOM_Y int 32 0 Output BT unbonded icon Y position

WPM Widget Position

Variable Type Default OLED Default ePaper Description
CONFIG_NICE_OLED_WIDGET_WPM_GAUGE_CUSTOM_X int 0 16 WPM gauge X position
CONFIG_NICE_OLED_WIDGET_WPM_GAUGE_CUSTOM_Y int 70 43 WPM gauge Y position
CONFIG_NICE_OLED_WIDGET_WPM_NEEDLE_CENTER_CUSTOM_X int 12 33 WPM needle center X position
CONFIG_NICE_OLED_WIDGET_WPM_NEEDLE_CENTER_CUSTOM_Y int 90 66 WPM needle center Y position
CONFIG_NICE_OLED_WIDGET_WPM_LABEL_CUSTOM_X int 0 0 WPM label X position
CONFIG_NICE_OLED_WIDGET_WPM_LABEL_CUSTOM_Y int 75 103 WPM label Y position

Luna Widget Position

Variable Type Default OLED Default ePaper Description
CONFIG_NICE_OLED_WIDGET_LUNA_CUSTOM_X int 65 100 Luna widget X position
CONFIG_NICE_OLED_WIDGET_LUNA_CUSTOM_Y int 0 15 Luna widget Y position

Bongo Cat Widget Position

Variable Type Default OLED Default ePaper Description
CONFIG_NICE_OLED_WIDGET_BONGO_CAT_CUSTOM_X int 64 (POS1) / 33 (POS2) 100 Bongo cat widget X position
CONFIG_NICE_OLED_WIDGET_BONGO_CAT_CUSTOM_Y int -9 8 Bongo cat widget Y position

HID Indicators Widget Position

Variable Type Default OLED Default ePaper Description
CONFIG_NICE_OLED_WIDGET_HID_INDICATORS_CUSTOM_X int 36 100 HID indicators widget X position
CONFIG_NICE_OLED_WIDGET_HID_INDICATORS_CUSTOM_Y int 0 15 (Luna) / 8 (Bongo) HID indicators widget Y position

Modifiers Widget Position

Variable Type Default OLED Default ePaper Description
CONFIG_NICE_OLED_WIDGET_MODIFIERS_CUSTOM_X int 0 2 Modifiers widget X position
CONFIG_NICE_OLED_WIDGET_MODIFIERS_CUSTOM_Y int 100 110 Modifiers widget Y position

Animation Peripheral Position

Variable Type Default OLED Default ePaper Description
CONFIG_NICE_OLED_WIDGET_ANIMATION_PERIPHERAL_CUSTOM_X int 18 36 Animation peripheral X position
CONFIG_NICE_OLED_WIDGET_ANIMATION_PERIPHERAL_CUSTOM_Y int -18 0 Animation peripheral Y position

Raw HID Widget Position

The Raw HID widget has multiple submodules that can be positioned independently.

Base Position (fallback for "HID not found" message)

Variable Type Default OLED Default ePaper Description
CONFIG_NICE_OLED_WIDGET_RAW_HID_CUSTOM_X int 0 0 Raw HID base X position
CONFIG_NICE_OLED_WIDGET_RAW_HID_CUSTOM_Y int 62 38 Raw HID base Y position

Weather (Temperature) Submodule

Variable Type Default OLED Default ePaper Description
CONFIG_NICE_OLED_WIDGET_RAW_HID_WEATHER_CUSTOM_X int 0 0 Weather X position
CONFIG_NICE_OLED_WIDGET_RAW_HID_WEATHER_CUSTOM_Y int 62 38 Weather Y position

Time Submodule

Variable Type Default OLED Default ePaper Description
CONFIG_NICE_OLED_WIDGET_RAW_HID_TIME_CUSTOM_X int 0 0 Time X position
CONFIG_NICE_OLED_WIDGET_RAW_HID_TIME_CUSTOM_Y int 74 50 Time Y position

Layout Submodule

Variable Type Default OLED Default ePaper Description
CONFIG_NICE_OLED_WIDGET_RAW_HID_LAYOUT_CUSTOM_X int 0 0 Layout X position
CONFIG_NICE_OLED_WIDGET_RAW_HID_LAYOUT_CUSTOM_Y int 86 62 Layout Y position

Volume Submodule

Variable Type Default OLED Default ePaper Description
CONFIG_NICE_OLED_WIDGET_RAW_HID_VOLUME_CUSTOM_X int 0 0 Volume X position
CONFIG_NICE_OLED_WIDGET_RAW_HID_VOLUME_CUSTOM_Y int 98 74 Volume Y position

Media Player (Spotify) Submodule

Variable Type Default OLED Default ePaper Description
CONFIG_NICE_OLED_WIDGET_RAW_HID_MEDIA_PLAYER_CUSTOM_X int 0 0 Media Player X position
CONFIG_NICE_OLED_WIDGET_RAW_HID_MEDIA_PLAYER_CUSTOM_Y int 110 86 Media Player Y position

Responsive Bongo Cat Widget Position

Variable Type Default OLED Default ePaper Description
CONFIG_NICE_OLED_WIDGET_RESPONSIVE_BONGO_CAT_CUSTOM_X int 64 64 Responsive bongo cat widget X position
CONFIG_NICE_OLED_WIDGET_RESPONSIVE_BONGO_CAT_CUSTOM_Y int -9 -9 Responsive bongo cat widget Y position

Sleep Status Widget Position

Variable Type Default OLED Default ePaper Description
CONFIG_NICE_OLED_WIDGET_SLEEP_STATUS_CUSTOM_X int 0 0 Sleep status widget X position
CONFIG_NICE_OLED_WIDGET_SLEEP_STATUS_CUSTOM_Y int 0 0 Sleep status widget Y position

ZMK RAW HID Implementation

This document describes the RAW HID implementation for the nice!OLED, nice!view and nice!custom.

0. Quick Start

  1. Compile your .uf2 and flash your keyboard including the zmk-nice-oled shield as indicated in the instructions in the README.md
    • don't forget to activate the flag CONFIG_NICE_OLED_WIDGET_RAW_HID=y
  2. Download and install the zmk-hid-host program to your computer and configure it to always start from login
    • zmk-hid-host does not spend much 0% cpu resources!
    • modify the json file if necessary!
    • zmk-hid-host is compatible for intel and apple m series processors, it is a universal binary!
  3. Enjoy your keyboard!!!
    • remember to customize to your liking.
    • TIP: you can activate seeing the weather and seeing your spotify song on macos!

1. Introduction to RAW HID

RAW HID provides a flexible way to send and receive custom data between the keyboard and the host computer. This allows for advanced features that are not covered by standard HID profiles.

To enable RAW HID, you need to set the following options in your Kconfig.defconfig:

CONFIG_NICE_OLED_WIDGET_RAW_HID=y

This will enable the RAW HID interface and the corresponding widgets.

2. Available RAW HID Features

The following features are implemented using RAW HID:

2.1. Layout Switching

This feature allows you to display the current keyboard layout on the OLED screen. The layout can be sent from the host computer.

Kconfig Options:

CONFIG_NICE_OLED_WIDGET_RAW_HID_LAYOUT=y
CONFIG_NICE_OLED_WIDGET_RAW_HID_LAYOUT_LIST="DE,US,LA,AB"
CONFIG_NICE_OLED_WIDGET_RAW_HID_LAYOUT_CUSTOM_X=0
CONFIG_NICE_OLED_WIDGET_RAW_HID_LAYOUT_CUSTOM_Y=86

The LAYOUT_LIST is a comma-separated list of layout names that will be displayed on the screen based on the index received from the host.

2.2. Weather Widget (macOS Only)

This widget displays the current temperature received from the host computer.

Kconfig Options:

CONFIG_NICE_OLED_WIDGET_RAW_HID_WEATHER=y
CONFIG_NICE_OLED_WIDGET_RAW_HID_WEATHER_CUSTOM_X=0
CONFIG_NICE_OLED_WIDGET_RAW_HID_WEATHER_CUSTOM_Y=62

The host application needs to send the temperature value to the keyboard. This feature is currently optimized for macOS.

2.3. Spotify Media Player Widget (macOS Only)

This widget displays the current song playing on Spotify on a macOS computer.

Kconfig Options:

CONFIG_NICE_OLED_WIDGET_RAW_HID_MEDIA_PLAYER_SPOTIFY_MACOS=y
CONFIG_NICE_OLED_WIDGET_RAW_HID_MEDIA_PLAYER_CUSTOM_X=0
CONFIG_NICE_OLED_WIDGET_RAW_HID_MEDIA_PLAYER_CUSTOM_Y=110

A host application is required to read the song information from Spotify and send it to the keyboard. This feature is exclusive to macOS.

2.4. System Time Widget

This widget displays the current system time synchronized with the host computer.

Kconfig Options:

CONFIG_NICE_OLED_WIDGET_RAW_HID_TIME=y
CONFIG_NICE_OLED_WIDGET_RAW_HID_TIME_CUSTOM_X=0
CONFIG_NICE_OLED_WIDGET_RAW_HID_TIME_CUSTOM_Y=74

This feature is compatible with Windows, Linux, and macOS.

2.5. System Volume Widget

This widget displays the current system audio volume.

Kconfig Options:

CONFIG_NICE_OLED_WIDGET_RAW_HID_VOLUME=y
CONFIG_NICE_OLED_WIDGET_RAW_HID_VOLUME_CUSTOM_X=0
CONFIG_NICE_OLED_WIDGET_RAW_HID_VOLUME_CUSTOM_Y=98

This feature is compatible with Windows, Linux, and macOS.

3. Host-side application

The companion host application, qmk-hid-host, provides the necessary data bridge for universal Raw HID features (System Time, Volume, Layout) across Linux, Windows, and macOS.

  • Technical Contributions (macOS Enhancements):
    • macOS Temperature Support: Implemented platform-specific temperature monitoring for macOS within the Rust codebase.
    • Spotify Integration: Engineered a native AppleScript/Rust bridge to fetch real-time track metadata from Spotify for display on the peripheral (macOS only).
    • Cross-Architecture Support: Developed a universal macOS application wrapper, bundling native binaries for both Intel (x86_64) and Apple Silicon (arm64) architectures, ensuring seamless deployment across the Apple ecosystem.

You can compile the application from the source by following these steps:

  1. Clone the original repository:
    git clone https://github.com/zzeneg/qmk-hid-host.git
  2. Navigate to the project directory:
    cd qmk-hid-host
  3. Compile the project in release mode:
    cargo build --release
  4. The binary will be available in target/release/.

Once compiled, you can run the application. It will automatically detect your keyboard and start sending the required data.

4. Creating a .dmg for the macOS application

Once you have your host-side application, you can create a .dmg file for easy distribution and installation.

You can use the create-dmg tool, which can be installed via Homebrew:

brew install create-dmg

Then, you can create the .dmg file with the following command:

create-dmg \
  --volname "ZMK RAW HID Host" \
  --background "path/to/your/background.png" \
  --window-pos 200 120 \
  --window-size 600 400 \
  --icon-size 100 \
  --icon "YourApp.app" 170 200 \
  --hide-extension "YourApp.app" \
  --app-drop-link 430 200 \
  "ZMK_RAW_HID_Host.dmg" \
  "source_folder/"

Replace "YourApp.app" and "source_folder/" with your actual application and source folder.

5. Running the application on startup

To make the host application run automatically every time you start your Mac, you can add it to the "Login Items".

  1. Open System Settings.
  2. Go to General > Login Items.
  3. Click the + button.
  4. Select your application from the /Applications folder.
  5. Click Open.

Now, the application will start automatically when you log in, ensuring that the RAW HID features of your keyboard are always available.

6. Updating the host-side application

If you need to update the host-side application with a new binary or configuration file, you can do so by replacing the files inside the application bundle.

  1. Go to your Applications folder.
  2. Right-click on ZMK HID Runner.app and select "Show Package Contents".
  3. Navigate to Contents/Resources/.
  4. You will see the following structure:
    .
    ├── applet.icns
    ├── applet.rsrc
    ├── description.rtfd
    │   └── TXT.rtf
    ├── Scripts
    │   └── main.scpt
    ├── zmk-hid-host
    └── zmk-hid-host.json
    
  5. You can replace the zmk-hid-host binary and the zmk-hid-host.json configuration file with your new versions. Make sure the new files have the same names.

Note

You can also use the cp command to replace the files. For example, if your new files are in the current directory, you can use the following commands:

cp zmk-hid-host "/Applications/ZMK HID Runner.app/Contents/Resources/zmk-hid-host"
cp zmk-hid-host.json "/Applications/ZMK HID Runner.app/Contents/Resources/zmk-hid-host.json"

If for some reason the application does not work after replacing the files, check the file permissions. The binary should have execution permissions. You can set them with chmod +x.

chmod +x "/Applications/ZMK HID Runner.app/Contents/Resources/zmk-hid-host"

Author and Contributions

The original qmk-hid-host project was created by zzeneg, and you can find the repository here: https://github.com/zzeneg/qmk-hid-host.

The Spotify and Weather functionalities described in this document were added in this pull request: https://github.com/zzeneg/qmk-hid-host/pull/24/files.

The RAW HID functionality in this project is a custom implementation, ported from the great work of @zzeneg in the following repositories:

This implementation is 100% independent and is activated only with the following flags, without needing any other files:

CONFIG_NICE_OLED_WIDGET_RAW_HID=y

Suggestions

If you have any implementation suggestion or something similar opens a discussion

Limitations

While nice_oled offers advanced features, there are hardware and software constraints to consider.

  • Memory Usage (RAM) This shield uses the LVGL graphics library, which can be memory-intensive.
    • High Consumption: Enabling multiple large widgets (WPM Graph, Bongo Cat, Raw HID) can exhaust the available RAM on the microcontroller (nRF52840).
    • Symptoms: If memory is low, you may experience display artifacts, freezing, or Bluetooth instability.
    • Mitigation: Use the "Balanced" or "Minimal" presets described in OPTIMIZE.md if you encounter issues.
  • Battery Life OLED displays and continuous animations consume power.
    • Peripheral Impact: Running complex animations (like Pokemon or Bongo Cat) on the peripheral half (which has a smaller battery in some builds) will significantly reduce battery life.
    • Refresh Rate: Higher animation speeds (lower ms values) increase CPU usage, preventing the processor from sleeping.
    • Mitigation: Use CONFIG_NICE_OLED_WIDGET_STATIC_IMAGE_PERIPHERAL=y for better battery life on split peripherals.
  • Platform Compatibility (Raw HID) The Raw HID features rely on a host-side application to send data to the keyboard.
    • Universal Support (macOS, Linux, Windows): The nice_oled shield and its core Raw HID modules (System Volume, Time, Layout) are fully compatible with macOS, Linux, and Windows.
    • macOS Exclusive Features: The specific integrations for Spotify track info and Weather are currently optimized and available only for macOS.
  • Performance & Latency The display runs on shared hardware resources.
    • Typing Latency: If the display thread priority is set too high (1 or 2), it might interrupt key scanning, causing perceived input lag during heavy animations.
    • Smart Battery: The experimental "Smart Battery" animation uses significant compute resources and is not recommended for stability-focused builds.
    • Mitigation: Keep CONFIG_ZMK_DISPLAY_DEDICATED_THREAD_PRIORITY at default (5) or lower (10).
  • Image Rotation Strategy To maximize efficiency on the nRF52840, real-time image rotation is avoided.
    • Pre-processing: All animated assets are pre-rotated on the host computer during the design phase.
    • Reasoning: Performing geometric transformations (rotation) at runtime is computationally expensive and memory-intensive for this architecture.
    • Implementation: By storing assets as ready-to-render, pre-rotated bitmaps, we offload the processing burden from the MCU, ensuring smooth playback with minimal CPU overhead.

Acknowledgments

This project is built upon the foundation of numerous innovative contributions from the ZMK community. We extend our sincere gratitude to the following developers whose work has been a source of inspiration and whose drivers or methods have been ported or adapted for this module.

Core Inspiration & Drivers

Your contributions have been instrumental in making this modular shield system possible. Thank you for open-sourcing your work and driving the ZMK ecosystem forward.

If you like my contributions, please don't forget the following:

I appreciate if you follow me on GitHub and YouTube !

Star

My other projects:

  • zmk-dongle-display-view: Use your niceview vertical with very beautiful widgets
  • zmk-oled-adapter: This module is an adapter for 128x32, 128x64 and 128x128 OLED screens, to be used on keyboards with ZMK without having to modify the shields of the keyboards.
  • qmk-config will be updated soon
  • qmk_userspace will be updated soon
  • vimtools swiss army knife for vim (features and settings that will make your life easier)
  • gm cross-platform git manager with friendly user interface
  • vim-better-header the best automated template
  • vim-executor multilanguage code executor

If you enjoy my contributions, feel free to donate.

⬆️ back to Table of Contents

Bottom

About

vertical widgets for oled and niceview screens using zmk (for split and non-split keyboards)

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages