The KB2040 sports a Stemma QT connector, which is handy for connecting OLED displays. This is supported by QMK, though to make it even easier the author of this guide also contributed a pull request to provide a ready-to-use example with the KB2040.
- Connect pins D3 and D4 to diagonally opposite pins of the tactile switch
- Use a cable to connect the STEMMA QT connectors of the KB2040 and OLED display.
You can follow the instructions on GitHub to fetch the pull request to your computer and build it for yourself, or just use the pre-built version below, it's ready to be copied to the RPI-RP2 bootloader drive of a KB2040:
The build steps similar to for the other firmware we've followed in this guide. The keyboard is handwired/onekey/kb2040 (note it is now kb2040 and not rp2040 to indicate the use of the kb2040's Stemma QT connector) and the keymap is oled.
cd ~/qmk_firmware git fetch origin refs/pull/17786/merge git checkout FETCH_HEAD qmk flash -kb handwired/onekey/kb2040 -km oled
In either case, you should get a build log displayed in the terminal, and at the end a .uf2 file is created:
Ψ Compiling keymap with gmake --jobs=19 --output-sync=target handwired/onekey/kb2040:oled:flash QMK Firmware 0.17.5 Making handwired/onekey/kb2040 with keymap oled and target flash arm-none-eabi-gcc (GNU Arm Embedded Toolchain 10-2020-q4-major) 10.2.1 20201103 (release) Copyright (C) 2020 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Generating: .build/obj_handwired_onekey_kb2040/src/layouts.h [OK] [Many lines deleted] Creating binary load file for flashing: .build/handwired_onekey_kb2040_oled.bin [OK] Size after: text data bss dec hex filename 0 38284 0 38284 958c handwired_onekey_kb2040_oled.uf2 Creating UF2 file for deployment: .build/handwired_onekey_kb2040_oled.uf2 [OK] Copying handwired_onekey_kb2040_oled.uf2 to qmk_firmware folder [OK] Flashing /media/jepler/RPI-RP2 (RPI-RP2) Wrote 64512 bytes to /media/jepler/RPI-RP2/NEW.UF2
Operating the demo
Rather than working as a keyboard, the one button is used to control the demo.
Click the button a short time to switch the mode.
Hold down the button to rotate the display by 90 degree increments.
After a short time, the OLED display will be set to all-black to prevent burn-in.
STEMMA QT Configuration in QMK
The following settings are needed in the appropriate config.h file to use the I2C port on the STEMMA QT connector:
#define I2C_DRIVER I2CD1 #define I2C1_SDA_PIN GP12 #define I2C1_SCL_PIN GP13
The following settings are needed in the appropriate mcuconf.h file:
#pragma once #include_next <mcuconf.h> #undef RP_I2C_USE_I2C0 #define RP_I2C_USE_I2C0 TRUE #undef RP_I2C_USE_I2C1 #define RP_I2C_USE_I2C1 FALSE
If your board has a different pinout, first determine the GP or GPIO number of the pins, and use that instead of GP12/13 in config.h for SDA_PIN
and SCL_PIN
. Then, determine whether they are on I2C peripheral 0 or 1 according to the pinout of the RP2040, and set the appropriate USE_I2C
line to TRUE
and the other to FALSE
in mcuconf.h.
QMK numbers the I2C peripherals differently when it comes to defining the I2C_DRIVER
so add 1 (I2C0 is I2CD1 and I2C1 is I2CD2). This way, you can use any appropriate pair of pins that are capable of I2C on the RP2040.
To enable the I2C driver and the OLED display, you place lines in rules.mk:
OLED_ENABLE = yes OLED_DRIVER = SSD1306 OPT_DEFS += -DHAL_USE_I2C=TRUE
The function oled_task_user
contains code to actually draw to the screen. In the oled example, this is in the file keyboards/handwired/onekey/keymaps/oled/keymap.c. The code can draw letters or work by individual pixels. For full info, check out the documentation from QMK's website. Here's a snippet of the code that fills the screen with a test pattern made out of ASCII characters:
static void test_characters(void) { uint8_t cols = oled_max_chars(); uint8_t rows = oled_max_lines(); bool invert = false; uint8_t char_index = 0; for (uint8_t row = 0; row < rows; ++row) { for (uint8_t col = 0; col < cols; ++col) { oled_write_char(get_test_char(char_index), invert); if (++char_index >= TEST_CHAR_COUNT) { char_index = 0; invert = !invert; } } } }