The goal of today’s workshop is to provide an introduction to soldering and programming through building a small mechanical keyboard. By the end of the workshop you should have a keyboard consisting off three keys and a rotary encoder that you can program to perform any task you can imagine. This could span from a simple volume knob, to dedicated copy / paste keys, or even typing the entire bee movie script with one keypress.
We will be using the below components during today’s workshop, and will be handed out as you get to each step.
- 1 x Sea-Picro (1)
- 1 x PCB (2)
- 2 x 12 pin headers (3)
- 4 x Diodes (through hole (4) or surface mount (5))
- 3 x Keyswitches (6) and keycaps (7)
- 1 x Rotary encoder (8) and knob (9)
The LEDs (10) will be pre soldered, and the reset switch (11) is not required.
You will also require the following tools.
- Soldering iron
- Flush cut side cutters
The most important thing to remember with soldering is that the solder flows to wherever is hot. As such it’s important to heat up the components you are trying to solder before feeding solder into the joint. A rough rule of thumb is to hold your iron against the components for a second before feeding solder into the component being soldered, not the iron. This will ensure the solder sticks to the parts you are trying to attach to the circuit board, and not just pool up on the iron.
Here is a short video showing how to solder, with the first 15 seconds demoing the above instructions.
On a normal keyboard, diodes are used to prevent an effect known as “ghosting”, where the microcontroller thinks more keys are pressed than actually are when specific key combinations are pressed. You will see diodes in two different package types, a glass tube with leads (through hole) and a black rectangle with small pads (surface mount). If you’ve never soldered before I’d suggest using the through hole diodes, however if you are after a challenge the surface mount option is also available.
Through Hole Diodes
We first need to bend the leads on the diode to be the same width as the holes in the PCB.
Then insert it, ensuring the black bar on the diode is aligned with the white bar on the PCB.
To hold it in place whilst soldering, flip the board over and bend the leads outwards.
Solder one of the leads.
Flip the board back over and check the diode is still flush with the PCB, if not heat up the joint and move into position.
With the diode in place, solder the remaining lead.
Finally, trim the leads using the flush cut side cutters. Please point the side cutters towards the desk when cutting so the leads don’t go flying around the room.
Surface Mount Diodes
Like through hole diodes, surface mount diodes are directional and won’t work if installed backwards. They have a horizontal line on one end of the package which lines up with the line on the PCB. This can sometimes be hard to see, but shining light from the side of the package will help reveal the marking.
As we have done previously, add solder to one pad.
Then ensuring the component is in the correct orientation, tack one pin in place.
Then solder the remaining pin in place.
Finish soldering all four diodes, and you’ll have a board that looks like the below. (You can pick and choose through hole vs surface mount depending on how much of a challenge you are seeking.)
The microcontroller is the brains of any keyboard, with it scanning for key presses, figuring out what key was pressed, then sending the relavent keypress up to the computer all in a fraction of a second. A RP2040 based board, Sea-Picro, was chosen for this project as it can be programmed in python without installing a toolchain and has good supply even during the chip shortage.
We first need to solder the pin headers to the microcontroller, and can use the PCB to keep the pins aligned as shown below. The pin header is one pin shorter than the IO on Sea-Picro, please leave the empty pin at the USB connector end as shown in red. Solder the pins at the end of each header.
With the headers tacked in place, confirm the pins are square to the microcontroller. If they are not, heat up one of the solder joints, and gently push the connector into alignment. Make sure you don’t touch the pin you are heating up otherwise you’ll burn yourself!
Once the pins are square solder all of the pins. (sorry for the blurry photo)
With all the pins soldered on Sea-Picro, ensure it’s placed on the same side as the diodes with the USB connector facing towards the edge of PCB as per the above photo.
Please ask a mentor to confirm the orientation is correct, as if it’s incorrect your board will not work!
With Sea-Picro oriented correctly, flip the board upside down and tack two opposing corners in place on the PCB.
If Sea-Picro isn’t sitting flush to the PCB, heat up a pin and adjust as necessary.
With the microcontroller sitting flush to the PCB, solder the remaining pins. (forgot to photograph this step)
With all the pins soldered, snip off the legs so they don’t stick out. Please take care so the pins don’t go flying around the room.
Switches are arguably the most important part of a keyboard, as without them you wouldn’t be able to type anything! They come in a variety of options with different force profiles, but regardless of what switch you pick the install process is the same.
First, grab a switch and place it in the position you want. Remember we are fitting a rotary encoder as well so consider where you want that to live as it’s much taller than a switch. In this case, I’m installing switches in 1,2,3, and an encoder in 0.
With the switch pressed into place, flip the board over and solder the pins in. Repeat for the other two switches.
In addition to the push button/switch in the encoder that shorts two pins when pressed, the encoder has two additional outputs that go high / low as the knob is turned, sending the direction of rotation to the microcontroller. As such you can turn the encoder for as many revolutions as you’d like, so they are a great way to control continuous values such as volume or opacity.
The first step is to snip both mounting legs off the encoder with the side cutters.
With the legs removed, insert the encoder into the PCB and tack opposing pins in place. Don’t solder all the pins yet.
With the pins tacked into place, ensure the encoder is sitting flush / square on the board, and adjust as necessary. When square, solder the remaining pins.
With all of the encoder pins soldered, install the keycaps and knob, and celebrate finishing the soldering of your new keyboard!
Out of the box, Sea-Picro (and the RP2040 microcontroller within) has no idea what it’s purpose in life is, so we need to configure it to not only be a keyboard, but one which works with our custom made PCB, and your custom keycodes. To do this, we will be using KMK, a CircuitPython based keyboard firmware framework, due to it’s ease of programming - all you need to do it edit a text file and when you save the code it will run.
To make programming easier, please install Mu, which is the recommended editor for CircuitPython and has an inbuilt serial terminal which allows us to talk to your keyboard for debugging purposes.
Sea-Picro comes flashed with CircuitPython out of the box, but we need to load KMK and the
code.py file with our keyboard configuration. The steps are below:
- Download a copy of KMK.
- Unzip it and copy the KMK folder and the
boot.pyfile at the root of the USB drive corresponding to your board (often appearing as CIRCUITPY).
- Unplug and replug your device to force the
boot.pychanges to be implemented.
- Using Mu, open the existing
code.pyfile on the CIRCUITPY drive and replace it with the below code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 # Sea-Picro pinout import board # KMK drivers from kmk.kmk_keyboard import KMKKeyboard from kmk.scanners.keypad import KeysScanner from kmk.modules.encoder import EncoderHandler from kmk.extensions.RGB import RGB, AnimationModes # Different keycodes that can be sent from kmk.keys import KC from kmk.extensions.media_keys import MediaKeys from kmk.handlers.sequences import send_string from kmk.handlers.sequences import unicode_string_sequence from kmk.handlers.sequences import simple_key_sequence # Init keyboard keyboard = KMKKeyboard() # Mapping IO pin to position in matrix # Comment lines in / out depending if you are using diodes or not # keyboard.matrix = KeysScanner([board.D21, board.D23, board.D20, board.D22,]) # Without diodes keyboard.matrix = KeysScanner([board.D29, board.D28, board.D27, board.D26,]) # With diodes # Add encoders, RGB, and media key support to keyboard encoder_handler = EncoderHandler() rgb_ext = RGB(pixel_pin=board.D7, num_pixels=3, val_limit=255, val_default=64, animation_mode=AnimationModes.RAINBOW,) media_keys = MediaKeys() keyboard.modules = [encoder_handler, media_keys, rgb_ext] # Configure encoder pins # As the encoder can be placed in multiple spots we don't define which IO the # push button is mapped to, and instead leave that for the switch matrix definition encoder_handler.pins = ((board.D9, board.D8, None, False),) # Examples of different keys that can be sent # All valid keys: https://github.com/KMKfw/kmk_firmware/blob/master/docs/keycodes.md#keys-overview # Strings: https://github.com/KMKfw/kmk_firmware/blob/master/docs/sequences.md#sending-strings EG_STRING = send_string("According to all known laws of aviation, there is no way a bee should be able to fly. Its wings are too small to get its fat little body off the ground.") # Unicode (requires config on your PC first) https://github.com/KMKfw/kmk_firmware/blob/master/docs/sequences.md#unicode EG_UNICODE = unicode_string_sequence('(っ◔◡◔)っ ❤') # Chains of key presses EG_COPY = KC.LCTL(KC.C) EG_PASTE = KC.LCTL(KC.V) # This is where we control what keys are sent when a switch is pressed keyboard.keymap = [ [ KC.MPLY, EG_STRING, EG_COPY, EG_PASTE ] ] # Below configures what happens when the encoder is turned encoder_handler.map = (((KC.VOLD, KC.VOLU, None),),) # With everything configured, time to become a keyboard! if __name__ == '__main__': keyboard.go()
Press the keys / turn the encoder on your keyboard and see if they all work. By default they will work as below.
- SW0 / Encoder: Media Play / Pause
- SW3: Prints the first line of the Bee movie script.
- SW2: Copy
- SW3: Paste
- Encoder Clockwise: Volume Up
- Encoder Anticlockwise: Volume Down
If you have issues, check the diodes are installed in the correct orientation and all pins are soldered. Just incase you have issues with the diodes, there is a “no diode” IO configuration on line 22 that can be commented in to check if the diodes are the issue or if it exists somewhere else.
Assuming everything is working, it’s time to jump to mechanical assembly and attach the base before returning here to configure the keyboard to send whatever keycodes you want. Below are a few links to KMK documentation to help guide you.
- There’s a reference of the available keycodes.
- International extension adds keys for non US layouts and Media Keys adds keys for … media.
And to go even further:
- Sequences are used for sending multiple keystrokes in a single action.
- Layers can transform the whole way your keyboard is behaving with a single touch.
- ModTap allow you to customize the way a key behaves whether it is tapped or hold, and TapDance depending on the number of times it is pressed.
- RGB allows you to control addressable LEDs.
If you make a change and notice your board is no longer working, there is a good chance there is a bug somewhere that is preventing the code from running. If this is the case, the onboard RGB LED will blink a error code that corresponds to the below.
- 1 GREEN blink: Code finished without error.
- 2 RED blinks: Code ended due to an exception. Check the serial console for details.
- 3 YELLOW blinks: CircuitPython is in safe mode. No user code was run. Check the serial console for safe mode reason.
With the electronics done, it’s time to assemble the case. Check you have the below before continuing.
- 1 x Acrylic base
- 4 x M2 standoffs
- 8 x M2 bolts
- 4 x Bumpons
- 1.5mm hex/allen key
Start by removing the protective paper off the acrylic base.
Grab a screw and standoff, and screw into one of the holes in the acrylic.
Repeat for all four corners.
Using a 1.5mm allen key, screw the PCB to the standoffs with the remaining screws.
Finally, add the bumpons to four corners of the acrylic.
Now it’s time to sit back and enjoy all of your hard work, as you’ve successfully assembled your new keyboard and can begin programming it.
With all the above done, you should have a fully functioning keyboard whose function is only limited by your imagination (and the rules of physics). If there is time left in the workshop, please play around with the code and configure it’s functionality to things you find interesting.
If you’d like some ideas, give the below a go:
- Configure keys to change the colour of the RGB LEDs. Hint, Answer.
- Set the encoder to change the LED brightness when you turn it. Hint, Answer.
- Configure one key to press
CTRL + L, another to type the RoboCats website URL, and a third to press enter, allowing you to visit the RoboCats website quickly (when pressed within a web browser). Hint, Answer.
- Combine the above into a single key press. Hint, Answer.
- Write a function that types
3, waits a second,
2, waits a second,
1, waits a second, then types
Liftoff!. Hint, Answer.
- Use a tool such as TextKool to generate fancy
RoboCatstext and type it with one key press. Hint, Answer.
- Print the below ASCII art of Shrek to the Mu serial terminal with a single key press. Hint, Answer.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
⢀⡴⠑⡄⠀⠀⠀⠀⠀⠀⠀⣀⣀⣤⣤⣤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠸⡇⠀⠿⡀⠀⠀⠀⣀⡴⢿⣿⣿⣿⣿⣿⣿⣿⣷⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠑⢄⣠⠾⠁⣀⣄⡈⠙⣿⣿⣿⣿⣿⣿⣿⣿⣆⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⢀⡀⠁⠀⠀⠈⠙⠛⠂⠈⣿⣿⣿⣿⣿⠿⡿⢿⣆⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⢀⡾⣁⣀⠀⠴⠂⠙⣗⡀⠀⢻⣿⣿⠭⢤⣴⣦⣤⣹⠀⠀⠀⢀⢴⣶⣆ ⠀⠀⢀⣾⣿⣿⣿⣷⣮⣽⣾⣿⣥⣴⣿⣿⡿⢂⠔⢚⡿⢿⣿⣦⣴⣾⠁⠸⣼⡿ ⠀⢀⡞⠁⠙⠻⠿⠟⠉⠀⠛⢹⣿⣿⣿⣿⣿⣌⢤⣼⣿⣾⣿⡟⠉⠀⠀⠀⠀⠀ ⠀⣾⣷⣶⠇⠀⠀⣤⣄⣀⡀⠈⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀ ⠀⠉⠈⠉⠀⠀⢦⡈⢻⣿⣿⣿⣶⣶⣶⣶⣤⣽⡹⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠉⠲⣽⡻⢿⣿⣿⣿⣿⣿⣿⣷⣜⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣷⣶⣮⣭⣽⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⣀⣀⣈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠻⠿⠿⠿⠿⠛⠉
Hint: Change Colour RGB
- Check out the RGB Key Codes.
- You’ll need to put the board into plain mode, then use Hue to adjust the colour. This can be done by altering the keymap.
Hint: Encoder Brightness Change
- This is very similar to the colour change problem above, except you want to change the brightness (Value) and map those keycodes to the encoder.
Hint: Visit RoboCats Website
- In the example code we have this keycode
EG_COPY = KC.LCTL(KC.C), which presses
CTRL + Cto copy.
- Try modifying this to press
CTRL + Linstead, and update the name from
EG_COPYto something more relevant.
- Then try modifying the
send_stringexample to print the RoboCats URL
- You might notice that after the URL is typed we need to press enter, so add that to your keymap as well.
Hint: RoboCats Website Single Key
- We will use Key Sequences to press keys in sequence.
- Look at the example
simple_key_pressesat the above link and modify it to use the keycodes we made earlier.
- You’ll need to define this sequence below the keycodes you want to use.
Hint: 3 2 1 Liftoff!
- We can use the
simple_key_pressesper the previous challenge, but will need to add
KC.MACRO_SLEEP_MS(1000)in between steps to delay by 1 second.
- To make the text appear on a new line each time, you can either use
KC.ENTERas a keycode, or add a newline
\nto the end of a string.
Hint: Fancy RoboCats Text
- As we’ve seen in the previous challenge, we can use
send_stringin a sequence to print multiple lines of text.
- We need to ensure we only use a font that uses standard keycodes, for example the one I’ve generated below:
1 2 3 4 5 6
_____ ____ ____ ____ _____ _______ _____ | __ \ / __ \| _ \ / __ \ / ____| /\|__ __/ ____| | |__) | | | | |_) | | | | | / \ | | | (___ | _ /| | | | _ <| | | | | / /\ \ | | \___ \ | | \ \| |__| | |_) | |__| | |____ / ____ \| | ____) | |_| \_\\____/|____/ \____/ \_____/_/ \_\_| |_____/
- If we copy and paste each line of the above text into a separate
send_stringcommand, we should be able to print the text one line at a time.
- We’ll either need to add a newline
KC.ENTERat the end of each string to ensure it prints on multiple lines.
Hint: Shrek Print
- This problem is a challenging one, as the picture of Shrek uses characters that you can’t type on a keyboard, so we can’t send keycodes as we’ve done above.
- We can however send it over the serial terminal to Mu, where we can then copy and paste it to a text editor on your PC.
- The KMK developers have this as an example, so scroll to the bottom of this page and give it a go.
- You’ll need to open the Mu serial terminal to see the work of art be printed out.
Answer: Change Colour RGB
- We will use the RGB Key Codes to adjust the LEDs.
- Once we find the keycodes we want to use, we can update the keymap with the new codes.
KC.RGB_MODE_PLAINwill be used to change the animation mode from rainbow to plain, as otherwise the Hue codes are not acted upon.
- KMK uses HSV (Hue, Saturation, Value) for colour control, and Hue is how we adjust colour. Add the
KC.HUI(Hue Increase) and
KC.HUD(Hue Decrease) keycodes into the keymap.
- With the keymap updated (see below), tap the
PLAINkey, then you can use the
HUDkeys to adjust the colour.
1 2 3 4 5 6 keyboard.keymap = [ [ KC.MPLY, KC.RGB_MODE_PLAIN, KC.RGB_HUI, KC.RGB_HUD ] ]
Answer: Encoder Brightness Change
- As above, we will use the RGB Key Codes, but update the encoder keymap instead of the keyboard switch keymap.
- Value is the HSV equivalent of Brightness, so
KC.RGB_VADare the keycodes we will use.
- Updating the encoder keymap with these for clockwise / anticlockwise as shown below should get us the desired result.
- If the value increases when you turn anticlockwise (and you want it to decrease), swap the location of the two keycodes.
1 encoder_handler.map = (((KC.RGB_VAD, KC.RGB_VAI, None),),)
Answer: Visit RoboCats Website
- We can modify the
EG_COPY = KC.LCTL(KC.C)line to
URL = KC.LCTL(KC.L), which will move your cursor to the URL bar in your browser.
- Similarly, editing the string example
EG_STRING = send_string("According ...")to
ROBO_URL = send_string("https://www.melbournerobocats.com/")will type out the URL.
- We then need to add
KC.ENTERto our keymap so we can press enter after typing out the URL.
1 2 3 4 5 6 7 8 9 URL = KC.LCTL(KC.L) ROBO_URL = send_string("https://www.melbournerobocats.com/") # This is where we control what keys are sent when a switch is pressed keyboard.keymap = [ [ KC.MPLY, URL, ROBO_URL, KC.ENTER ] ]
Answer: RoboCats Website Single Key
- Using Key Sequences we can press the keys we defined in the last challenge all in one go.
- If we enter the keycodes we made in the previous challenge into the example linked above, it will look something like the below.
ROBO_URL_SINGLEto our keymap will then allow us to trigger this sequence.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 URL = KC.LCTL(KC.L) ROBO_URL = send_string("https://www.melbournerobocats.com/") ROBO_URL_SINGLE = simple_key_sequence( ( URL, ROBO_URL, KC.ENTER, ) ) # This is where we control what keys are sent when a switch is pressed keyboard.keymap = [ [ ROBO_URL_SINGLE, URL, ROBO_URL, KC.ENTER ] ]
Answer: 3 2 1 Liftoff!
- We will use Key Sequences as we did in the previous challenge to solve this.
- You can either type
1 2 3using the keycodes, or send them as a string, but will need to type
Liftoff!as a string.
- We will press
KC.ENTERafter typing each key, and append a newline to the
- Between each step
KC.MACRO_SLEEP_MS(1000)will be called to create a delay. The function accepts a time in milliseconds (thousandths of a second) so we will pass 1000 to get a one second delay.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 LIFTOFF = simple_key_sequence( ( KC.N3, KC.ENTER, KC.MACRO_SLEEP_MS(1000), KC.N2, KC.ENTER, KC.MACRO_SLEEP_MS(1000), send_string("1\n"), KC.MACRO_SLEEP_MS(1000), send_string("LIFTOFF!\n"), ) ) # This is where we control what keys are sent when a switch is pressed keyboard.keymap = [ [ LIFTOFF, URL, ROBO_URL, KC.ENTER ] ]
Answer: Fancy RoboCats Text
- As explained in the hint, we will use multiple
send_stringfunctions to print each line of the text.
- We need to append a
KC.ENTERto the end of each line to ensure they print on a new line each time.
- One possible solution is shown below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 FANCY_ROBO = simple_key_sequence( ( send_string(" _____ ____ ____ ____ _____ _______ _____ \n"), send_string("| __ \ / __ \| _ \ / __ \ / ____| /\|__ __/ ____|\n"), send_string("| |__) | | | | |_) | | | | | / \ | | | (___ \n"), send_string("| _ /| | | | _ <| | | | | / /\ \ | | \___ \ \n"), send_string("| | \ \| |__| | |_) | |__| | |____ / ____ \| | ____) |\n"), send_string("|_| \_\\____/|____/ \____/ \_____/_/ \_\_| |_____/ \n"), ) ) # This is where we control what keys are sent when a switch is pressed keyboard.keymap = [ [ FANCY_ROBO, URL, ROBO_URL, KC.ENTER ] ]
Answer: Shrek Print
- First, we copy and paste the example code from the KMK example to our code. Place above the keymap.
- Looking at the code, we can see when we press
LALTit will call the
shrekfunction that prints the image.
- As such, if we add the
KC.LALTkeycode to our keymap, it should print Shrek whenever Left Alt is pressed.
- We then need to open Mu and go to the serial terminal to see the picture be printed.
- Once it’s been printed, you can copy and paste it in whatever text editor / messaging platform you like.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 def shrek(*args, **kwargs): print('⢀⡴⠑⡄⠀⠀⠀⠀⠀⠀⠀⣀⣀⣤⣤⣤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀') print('⠸⡇⠀⠿⡀⠀⠀⠀⣀⡴⢿⣿⣿⣿⣿⣿⣿⣿⣷⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀') print('⠀⠀⠀⠀⠑⢄⣠⠾⠁⣀⣄⡈⠙⣿⣿⣿⣿⣿⣿⣿⣿⣆⠀⠀⠀⠀⠀⠀⠀⠀') print('⠀⠀⠀⠀⢀⡀⠁⠀⠀⠈⠙⠛⠂⠈⣿⣿⣿⣿⣿⠿⡿⢿⣆⠀⠀⠀⠀⠀⠀⠀') print('⠀⠀⠀⢀⡾⣁⣀⠀⠴⠂⠙⣗⡀⠀⢻⣿⣿⠭⢤⣴⣦⣤⣹⠀⠀⠀⢀⢴⣶⣆') print('⠀⠀⢀⣾⣿⣿⣿⣷⣮⣽⣾⣿⣥⣴⣿⣿⡿⢂⠔⢚⡿⢿⣿⣦⣴⣾⠁⠸⣼⡿') print('⠀⢀⡞⠁⠙⠻⠿⠟⠉⠀⠛⢹⣿⣿⣿⣿⣿⣌⢤⣼⣿⣾⣿⡟⠉⠀⠀⠀⠀⠀') print('⠀⣾⣷⣶⠇⠀⠀⣤⣄⣀⡀⠈⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀') print('⠀⠉⠈⠉⠀⠀⢦⡈⢻⣿⣿⣿⣶⣶⣶⣶⣤⣽⡹⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀') print('⠀⠀⠀⠀⠀⠀⠀⠉⠲⣽⡻⢿⣿⣿⣿⣿⣿⣿⣷⣜⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀') print('⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣷⣶⣮⣭⣽⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀') print('⠀⠀⠀⠀⠀⠀⣀⣀⣈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⠀⠀⠀⠀⠀⠀⠀') print('⠀⠀⠀⠀⠀⠀⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀') print('⠀⠀⠀⠀⠀⠀⠀⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀') print('⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠻⠿⠿⠿⠿⠛⠉') return False # Returning True will follow thru the normal handlers sending the ALT key to the OS KC.LALT.before_press_handler(shrek) # This is where we control what keys are sent when a switch is pressed keyboard.keymap = [ [ KC.LALT, KC.RGB_MODE_PLAIN, KC.RGB_HUI, KC.RGB_HUD ] ]