Import the Libraries

First, the libraries are imported.

import time
import board
import busio
from adafruit_neokey.neokey1x4 import NeoKey1x4
import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode

Setup the Objects

Objects are setup for I2C, the NeoKey 1x4 and USB HID so that the QT Py RP2040 can be used as an HID keyboard over USB.

Since you're using the NeoKey with a STEMMA QT cable, the QT Py RP2040's board.SCL1 and board.SDA1 pins are used for I2C.

# use STEMMA I2C bus on RP2040 QT Py
i2c_bus = busio.I2C(board.SCL1, board.SDA1)

# Create a NeoKey object
neokey = NeoKey1x4(i2c_bus, addr=0x30)

#  create a keyboard object
keyboard = Keyboard(usb_hid.devices)

Check the Version of the Code

A quick debugging message prints to the REPL that denotes whether you are using the version of the code for macOS or Windows. This will let you know that you've loaded up the correct version of the code for your chosen operating system.

#  for Windows
print("NeoKey Emoji keyboard - Windows")

#  for macOS
print("NeoKey Emoji keyboard - macOS")

Debouncing States

For debouncing, each of the four switches on the NeoKey have a state that will be tracked in the loop.

#  states for key presses
key_0_state = False
key_1_state = False
key_2_state = False
key_3_state = False

Emoji Arrays

The last portion of the code before the loop are the emoji arrays. The way that the emojis are being sent is by searching for them by name in your operating system's default emoji menu. 

Each array has a sequence of keycodes that searches for the name of the emoji, selects the emoji and then exits the emoji menu. These arrays are iterated through in the loop so that each keycode is sent one at a time.

The reason that there are different versions of the code for macOS and Windows since both operating systems have different ways to navigate the emoji menu.

#  Windows emoji arrays

#  update these arrays to customize your emojis
#  cat face emoji
emoji_0 = [Keycode.C, Keycode.A, Keycode.T, Keycode.SPACE, Keycode.F, Keycode.ENTER, Keycode.ESCAPE]
#  lightning bolt emoji
emoji_1 = [Keycode.V, Keycode.O, Keycode.L, Keycode.T, Keycode.ENTER, Keycode.ESCAPE]
#  control panel emoji
emoji_2 = [Keycode.K, Keycode.N, Keycode.O, Keycode.ENTER, Keycode.ESCAPE]
#  guitar emoji
emoji_3 = [Keycode.G, Keycode.U, Keycode.I, Keycode.T, Keycode.ENTER, Keycode.ESCAPE]
#  macOS emoji arrays

#  update these arrays to customize your emojis
#  cat face emoji
emoji_0 = [Keycode.C, Keycode.A, Keycode.T, Keycode.DOWN_ARROW, Keycode.ENTER]
#  lightning bolt emoji
emoji_1 = [Keycode.V, Keycode.O, Keycode.L, Keycode.T, Keycode.DOWN_ARROW, Keycode.ENTER]
#  control panel emoji
emoji_2 = [Keycode.C, Keycode.O, Keycode.N, Keycode.T, Keycode.R, Keycode.O,
           Keycode.DOWN_ARROW, Keycode.ENTER]
#  guitar emoji
emoji_3 = [Keycode.G, Keycode.U, Keycode.I, Keycode.T, Keycode.DOWN_ARROW, Keycode.ENTER]

Customize Your Emojis

If you wanted to change the emojis, you would need to open your operating system's emoji menu, find the official name of your desired emoji and update an emoji array with the needed keycodes.

Most emojis can be brought up by entering a portion of its name, which can help you to keep the length of your arrays fairly short.

The Loop

Switch Debouncing and Turning Off NeoPixels

The loop begins with debouncing for the four neokey inputs. Additionally, logic is setup so that when a neokey is released, its corresponding NeoPixel is turned off.

#  switch debouncing
    #  also turns off NeoPixel on release
    if not neokey[0] and key_0_state:
        key_0_state = False
        neokey.pixels[0] = 0x0
    if not neokey[1] and key_1_state:
        key_1_state = False
        neokey.pixels[1] = 0x0
    if not neokey[2] and key_2_state:
        key_2_state = False
        neokey.pixels[2] = 0x0
    if not neokey[3] and key_3_state:
        key_3_state = False
        neokey.pixels[3] = 0x0

Open the Emoji Menu

The rest of the loop contains if statements for each neokey. If a neokey is pressed, then its corresponding NeoPixel is turned on with its assigned color.  Then, depending on your operating system, the keyboard macro to open the emoji menu is opened. 

For Windows, this key sequence is Windows Key + Period and for macOS, it is Control + Command + Space.

A longer than normal pause is required after sending the macro to open the menu. This differs between operating systems, with Windows requiring almost a full second to fully open.

#  Windows version of the code

#  if 1st neokey is pressed...
    if neokey[0] and not key_0_state:
        print("Button A")
        #  turn on NeoPixel
        neokey.pixels[0] = 0xFF0000
        #  open windows emoji menu
        keyboard.send(Keycode.WINDOWS, Keycode.PERIOD)
        #  delay for opening menu
        time.sleep(0.75)
#  macOS version of the code

    #  if 1st neokey is pressed...
    if neokey[0] and not key_0_state:
        print("Button A")
        #  turn on NeoPixel
        neokey.pixels[0] = 0xFF0000
        #  open macOS emoji menu
        keyboard.send(Keycode.CONTROL, Keycode.COMMAND, Keycode.SPACE)
        #  delay for opening menu
        time.sleep(.2)

Send the Emoji

After this, a for statement is setup to iterate through the corresponding emoji array. keyboard.send() is used to send each individual keycode in the emoji array with a slight delay between each message.

keyboard.send() has the benefit of both pressing and releasing the keycode compared to keyboard.press() and keyboard.release().

Finally, the state of the neokey is updated for debouncing.

#  send key presses for emoji_0
        for i in emoji_0:
            keyboard.send(i)
            time.sleep(0.05)
        #  update key state
        key_0_state = True

This guide was first published on Jul 27, 2021. It was last updated on Jul 27, 2021.

This page (CircuitPython Code Walkthrough) was last updated on Jul 14, 2021.

Text editor powered by tinymce.