Display Troubleshooting
This guide provides steps for identifying and resolving common issues with various displays (OLED, Low Power Display, nice!view, etc.) on custom keyboards running QMK or ZMK firmware. These displays typically communicate via either I2C or SPI protocols.
If your display isn't showing anything, is showing garbage, or isn't behaving as expected, work through these steps to pinpoint the problem.
1. Initial Checks (Hardware & Basic Connectivity)â
Before diving into firmware, let's rule out simple physical issues.
1.1 Visual Inspectionâ
- Physical Damage: Carefully inspect the display itself. Look for cracks, bent pins, or any visible damage. If the display came with a protective film, ensure it's removed.
- Soldering Joints:
- Display Pins: Check all pins connecting the display to the PCB (typically 4-5 pins: VCC, GND, and data/clock lines). Ensure they have clean, solid solder joints. Cold joints or bridges can prevent communication. Reflow them if they look suspicious.
- MCU Pins: If your display connects directly to the microcontroller (MCU), inspect the solder joints for the corresponding communication pins (SDA/SCL for I2C; CS/SCL/MOSI for SPI) on the MCU.
- Resistors/Jumpers: Some boards require pull-up resistors, specific jumpers, or bodge wires for display functionality. Consult your keyboard's build guide. Ensure any required jumpers are correctly soldered or bridged. For instance, some I2C displays have configurable address jumpers.
1.2 Cables and Connections (Split Keyboards)â
- TRRS/USB-C Cable (Split Keyboards): If you have a split keyboard, the display often relies on communication between the two halves.
- Ensure your TRRS/USB-C cable is fully seated and functional. Try swapping it with a known good cable.
- Check the TRRS/USB-C jacks on both halves for bent pins or debris.
- Controller Connections: For modular designs (e.g., Pro Micro, Mikoto, nice!nano), ensure the controller is seated correctly and firmly in its sockets. Remove and re-seat it.
1.3 Power Checkâ
- Is the keyboard powered on? For wireless ZMK keyboards, ensure the battery is charged and the power switch is in the "on" position.
- Display Glow/Backlight: Does the display show any signs of life?
- For OLEDs: A faint glow, even if black, or random pixels lighting up indicates it's at least receiving power. No glow often points to a power issue (VCC/GND, bad solder, or dead display).
- For nice!view: These are very low-power Memory-in-Pixel displays and may not have an obvious "glow." If you see static images or partial images, it indicates some power and communication.
2. Firmware Configuration (QMK & ZMK)â
Incorrect firmware configuration is a very common cause of display issues.
2.1 Enable Display Support in Firmwareâ
Both QMK and ZMK require you to explicitly enable display support and specify the correct driver.
- QMK:
- Navigate to your keyboard's
rules.mk
file (e.g.,qmk_firmware/keyboards/your_keyboard/rules.mk
). - Ensure you have
OLED_ENABLE = yes
(for OLEDs) or a similar_ENABLE
flag for other display types. - Specify the correct display driver:
OLED_DRIVER = SSD1306
(common for OLEDs) or other specific drivers if your display uses one. - Check your
config.h
for macros defining the display resolution, e.g.,OLED_DISPLAY_128X64
orOLED_DISPLAY_160X68
.
- Navigate to your keyboard's
- ZMK:
- Display support is enabled via
Kconfig
options. Look in yourconfig/boards/arm/<your_board>/Kconfig.defconfig
or similar file. - Ensure
CONFIG_ZMK_DISPLAY=y
is present. - Enable the specific display driver:
- For I2C OLEDs:
CONFIG_ZMK_DISPLAY_SSD1306=y
- For nice!view:
CONFIG_ZMK_DISPLAY_SHARP_LS011B7DH03=y
ANDCONFIG_ZMK_DISPLAY_SSD1306_SPI=y
(the nice!view uses the SSD1306 SPI protocol).
- For I2C OLEDs:
- Verify the correct communication bus (I2C or SPI) is referenced in your board's devicetree file (e.g.,
boards/arm/<your_board>/<your_board>.dts
or.dtsi
) or your shield's overlay file.
- Display support is enabled via
2.2 Correct Communication Protocol Configuration (Address or Pin Assignments)â
This is a critical step as I2C and SPI displays have different configuration requirements.
-
For I2C Displays (e.g., many OLEDs):
- I2C displays use a specific address. The most common I2C addresses are
0x3C
and0x3D
. - QMK: In your
config.h
orrules.mk
, ensureOLED_I2C_ADDRESS
is set correctly if not using the default (usually0x3C
). For example:#define OLED_I2C_ADDRESS 0x3D
. - ZMK: Check the
reg = <0x3c>;
line (or0x3d
) in thessd1306
node within your.dts
or.dtsi
file.infoIf you have access to an Arduino or another microcontroller, you can run a simple I2C scanner sketch to detect the actual address of your display. This is invaluable for debugging.
- I2C displays use a specific address. The most common I2C addresses are
-
For SPI Displays (e.g., nice!view):
- SPI displays use specific pins for Chip Select (CS), Clock (SCL), and Master Out Slave In (MOSI).
- Pin Assignments: The physical wiring of these pins must match the firmware configuration. For example, if you're using a nice!view on a PCB designed for a 4-pin OLED, you might need a "bodge wire" to connect the nice!view's 5th (CS) pin to an available GPIO pin on your microcontroller. Consult your display's documentation or your keyboard's build guide for correct pin assignments.
- ZMK Devicetree Configuration (example for nice!view):
- You'll define an SPI bus and then the display device on that bus, often in a shield overlay (
.overlay
file). - Look for an
&spi<N>
node (e.g.,&spi0
or&spi1
). - The display will be a child node under the SPI bus. Crucially, the
cs-gpios
property defines the Chip Select pin and must match your physical wiring. Thereg
property here defines the chip select line number (<0>
for the first).&spi0 { // Or &spi1 depending on your MCU
status = "okay";
cs-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; // Example: P0.06 for CS
nice_view: sharp_ls011b7dh03@0 {
compatible = "sharp,ls011b7dh03";
label = "NICEVIEW";
reg = <0>; // Chip Select line number
spi-max-frequency = <4000000>;
width = <160>;
height = <68>;
};
}; - If adapting a nice!view to an OLED-compatible shield, ensure you include
nice_view_adapter nice_view
in yourbuild.yaml
's shield definition.- board: nice_nano_v2
shield: <your_shield_name> nice_view_adapter nice_view
- You'll define an SPI bus and then the display device on that bus, often in a shield overlay (
2.3 Firmware Specifics (Split Keyboards)â
- QMK:
- Ensure
MASTER_LEFT
,MASTER_RIGHT
, orMASTER_AUTO_DETECT
is defined in yourconfig.h
for split keyboards. - If using
MASTER_AUTO_DETECT
, ensureSPLIT_KEYBOARD_ENABLE = yes
is also inrules.mk
. - Confirm that the relevant
_ENABLE
flag for your display is in therules.mk
for both halves if both are supposed to have displays.
- Ensure
- ZMK:
- Both halves of a split keyboard need their respective firmware flashed.
- For displays on a split keyboard, ensure the display is correctly defined in the devicetree (or shield overlay) for the specific half it's on.
2.4 Flash Firmwareâ
After making any configuration changes in your firmware files, you will need to re-flash your microcontroller(s).
- Download Precompiled Firmware:
- For pre-tested and compatible firmware, please visit the official KEEBD firmware repository:
https://docs.keebd.com/firmware - Download the appropriate
.hex
(for QMK) or.uf2
(for ZMK) file for your specific keyboard model and desired configuration.
- For pre-tested and compatible firmware, please visit the official KEEBD firmware repository:
- Flash Firmware to Microcontroller:
- Use a flashing tool (e.g., QMK Toolbox for QMK, or simply drag-and-drop the
.uf2
file for ZMK on Mikoto or nice!nanos) to flash the downloaded firmware. - Ensure you are flashing the correct file to the correct half (if you have a split keyboard, e.g., left and right halves).
- Use a flashing tool (e.g., QMK Toolbox for QMK, or simply drag-and-drop the
3. Advanced Troubleshootingâ
If the above steps haven't resolved the issue, consider these more in-depth checks.
3.1 Verify Communication Bus Operation (Advanced - Requires Multimeter)â
- For I2C Displays (SDA & SCL):
- With the keyboard powered on, use a multimeter to check the voltage on the SDA (Data) and SCL (Clock) pins of the display. You should see a voltage close to VCC (e.g., 3.3V or 5V, depending on your board's logic level).
- While the keyboard is active (typing, or if the display is configured to show constant info), you might see slight fluctuations in voltage as data is transmitted. If both are stuck at 0V or VCC, there's a problem with the I2C bus or the MCU's I2C peripheral.
- For SPI Displays (CS, SCL, MOSI):
- With the keyboard powered on, check VCC and GND.
- Check SCL (clock) and MOSI (data out from MCU to display). Similar to I2C, you should see appropriate voltage levels and potentially fluctuations during data transfer.
- Check CS (Chip Select). This pin is typically high and goes low when the MCU wants to communicate with the display.
- Continuity Check (Power Off): With the keyboard unplugged, use a multimeter in continuity mode to check continuity between the display's communication pins and the corresponding MCU pins. Also, check for shorts between any of the communication pins or between these pins and VCC/GND.
3.2 Sleep Mode / Power Saving (ZMK Specific)â
ZMK is optimized for wireless and power efficiency, which can sometimes lead to displays turning off or freezing. This is especially relevant for low-power displays like nice!view.
- ZMK Sleep Behavior: By default, ZMK displays may turn off after a period of inactivity to save power. Try pressing a key to wake the keyboard and see if the display activates.
- Troubleshooting Sleep-Related Freezes: Some users have reported displays freezing after waking from deep sleep.
- Check the ZMK GitHub issues or Discord for solutions specific to your board or display type.
- Temporarily disabling deep sleep in your ZMK configuration (
Kconfig.defconfig
) might help diagnose if this is the cause, though it will impact battery life. Look forCONFIG_ZMK_SLEEP=n
or related options.
3.3 Default Firmware Testâ
- Flash Default Firmware: If your keyboard has a known good default firmware (either from the manufacturer or a widely used QMK/ZMK setup for your board) that should enable the display, try flashing that.
- If the display works with the default firmware, your issue is definitely in your custom keymap or configuration files. You can then carefully compare your custom files to the working default ones to find the discrepancy.
- If it still doesn't work, it points more strongly to a hardware issue (display, soldering, MCU).
3.4 Isolate the Display Codeâ
- QMK Debugging:
- Use QMK's debugging features to see if the display driver is initializing. You can add
xprintf
statements to youroled_task_user
function or other display-related code to print messages to the serial console (viewable viaQMK Toolbox
or a serial terminal). - Enable
CONSOLE_ENABLE = yes
andDEBUGS_ENABLE = yes
in yourrules.mk
and relevantDEBUG_
flags inconfig.h
.
- Use QMK's debugging features to see if the display driver is initializing. You can add
- ZMK Logging:
- ZMK also has logging capabilities. You can enable
CONFIG_LOG=y
andCONFIG_ZMK_DEBUG_DISPLAY=y
(or similar) in yourKconfig
to get more verbose output during runtime, which can be viewed via a serial terminal.
- ZMK also has logging capabilities. You can enable
3.5 Consider a Defective Display or MCUâ
- Swap Components: If you have a spare display or microcontroller, try swapping it out. This is often the quickest way to confirm if a component is faulty.
- Purchase from Reputable Sources: Always buy components from trusted vendors to minimize the risk of receiving faulty parts.
By systematically working through these troubleshooting steps, you should be able to identify and resolve most issues with your custom keyboard display. Good luck!