# Split Ortho Keyboard with TCA8418 Matrix Expanders

## Overview

![](https://cdn-learn.adafruit.com/assets/assets/000/115/984/medium800/3d_printing_sok-9447.jpg?1666156114)

![](https://cdn-learn.adafruit.com/assets/assets/000/116/085/medium800thumb/3d_printing_split2.jpg?1666373500)

Forget about that staggered key layout -- a holdover from mechanical typewriters -- and build your own custom ortholinear keyboard! Honor the angle of your wrists with the split design.

This 60% layout is fast and efficient (once you practice and get used to a new way of working) -- keyboard "layers" allow you to access any key you need by "lowering" or "raising" to whole new sets of keys.

Pick your favorite MX compatible keyswitches and press them into the socketed 6x5 NeoKey PCB. Build a 3D printed or 3D printed/laser cut acrylic combo case.

Two **TCA8418** matrix expanders handle reading the diode key matrices, and a **Kee Boar**  **KB2040** running CircuitPython does the rest, acting as a USB HID keyboard device.

Create and edit your own custom layouts with the **keymaps.py** config file. The layout I used was inspired by [this keyboard project](https://sgotti.dev/post/the-quest-for-the-perfect-keyboard-and-layout/).

![](https://cdn-learn.adafruit.com/assets/assets/000/116/083/medium800/3d_printing_sok-9315.jpg?1666372496)

## Parts
### Adafruit QT Py RP2040

[Adafruit QT Py RP2040](https://www.adafruit.com/product/4900)
What a cutie pie! Or is it... a QT Py?&nbsp;This diminutive dev board comes with one of our new favorite chip, the RP2040. It's been made famous in the new [Raspberry Pi Pico](https://www.adafruit.com/pico) _and_ our [Feather...](http://www.adafruit.com/product/4884)

In Stock
[Buy Now](https://www.adafruit.com/product/4900)
[Related Guides to the Product](https://learn.adafruit.com/products/4900/guides)
![Video of hand holding a QT Py PCB in their hand. An LED glows rainbow colors.](https://cdn-shop.adafruit.com/product-videos/640x480/4900-06.jpg)

### STEMMA QT / Qwiic JST SH 4-Pin Cable - 400mm long

[STEMMA QT / Qwiic JST SH 4-Pin Cable - 400mm long](https://www.adafruit.com/product/5385)
This 4-wire cable is a little over 400mm / 15.7" long and fitted with JST-SH female 4-pin connectors on both ends. Compared with the chunkier JST-PH these are 1mm pitch instead of 2mm, but still have a nice latching feel, while being easy to insert and remove.

<a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/5385)
[Related Guides to the Product](https://learn.adafruit.com/products/5385/guides)
![Angled shot of 400mm long STEMMA QT cable.](https://cdn-shop.adafruit.com/640x480/5385-01.jpg)

### Part: Adafruit TCA8418
quantity: 2
Keypad Matrix and GPIO Expander Breakout
[Adafruit TCA8418](https://www.adafruit.com/product/4918)

### Part: NeoKey 5x6 Ortho Snap-Apart Mechanical Key Switch PCB
quantity: 2
NeoKey 5x6 Ortho Snap-Apart Mechanical Key Switches
[NeoKey 5x6 Ortho Snap-Apart Mechanical Key Switch PCB](https://www.adafruit.com/product/5157)

### Part: Kailh Mechanical Key Switches
quantity: 6
Linear Black 10 pack
[Kailh Mechanical Key Switches](https://www.adafruit.com/product/4953)

You'll want to pick some keycaps. If you are highly elite and need no legends, try one of the choices below. Otherwise, search online for " **MX compatible ortholinear keycap set**". The ones used in this guide are the **Drop MT3 profile Dancer ortho** kit.

### Part: Blue DSA Keycaps
quantity: 6
10 pack
[Blue DSA Keycaps](https://www.adafruit.com/product/5005)

### Part: Dark Blue DSA Keycaps
quantity: 6
10 pack
[Dark Blue DSA Keycaps](https://www.adafruit.com/product/5016)

 **or**

### Part: Cyan MA Keycaps
quantity: 12
5 pack
[Cyan MA Keycaps](https://www.adafruit.com/product/5174)

### Brass Heat-Set Inserts for Plastic - M3 x 4mm - 50 pack

[Brass Heat-Set Inserts for Plastic - M3 x 4mm - 50 pack](https://www.adafruit.com/product/4255)
Wanna improve the connection strength between your project's 3D-printed parts, and also have nice clean surfaces? Instead of gluing bits together, or screwing plastic screws directly into your 3D prints, use strong and reusable machine screws and heat-set inserts. Heat set inserts are only...

In Stock
[Buy Now](https://www.adafruit.com/product/4255)
[Related Guides to the Product](https://learn.adafruit.com/products/4255/guides)
![pile of 50 Brass Heat-Set Inserts for Plastic - M3 x 4mm.](https://cdn-shop.adafruit.com/640x480/4255-02.jpg)

### Black Nylon Machine Screw and Stand-off Set – M3 Thread

[Black Nylon Machine Screw and Stand-off Set – M3 Thread](https://www.adafruit.com/product/4685)
Totaling **420 pieces** , this **M3 Screw Set** &nbsp;is a must-have for your workstation.&nbsp;You'll have enough screws, nuts, and hex standoffs to fuel your maker tendencies&nbsp;for days on end! M3 size screws fit a number of&nbsp;Adafruit breakout/dev board...

In Stock
[Buy Now](https://www.adafruit.com/product/4685)
[Related Guides to the Product](https://learn.adafruit.com/products/4685/guides)
![Opened box showing many nylon screws](https://cdn-shop.adafruit.com/640x480/4685-01.jpg)

### Black Nylon Machine Screw and Stand-off Set – M2.5 Thread

[Black Nylon Machine Screw and Stand-off Set – M2.5 Thread](https://www.adafruit.com/product/3299)
Totaling 380 pieces, this **M2.5 Screw Set** &nbsp;is a must-have for your workstation.&nbsp;You'll have enough screws, nuts, and hex standoffs to fuel your maker tendencies&nbsp;for days on end! M2.5 size screws fit almost all of the Adafruit breakout/dev board mounting holes...

In Stock
[Buy Now](https://www.adafruit.com/product/3299)
[Related Guides to the Product](https://learn.adafruit.com/products/3299/guides)
![Black Nylon Screw and Stand-off Set with M2.5 Threads, kit box](https://cdn-shop.adafruit.com/640x480/3299-00.jpg)

### Part: Little Rubber Bumper Feet
quantity: 2
Pack of 4
[Little Rubber Bumper Feet](https://www.adafruit.com/product/550)

# Split Ortho Keyboard with TCA8418 Matrix Expanders

## Build the Split Ortho Keyboard

![](https://cdn-learn.adafruit.com/assets/assets/000/115/994/medium800/3d_printing_sok_fritz.jpg?1666200260)

## Setup

Both sides of the Split Ortho Keyboard contain their own 6x5 diode matrix keyswitch PCB wired to the column and row pins of a TCA8418 keypad matrix expander.

Each TCA8418 takes care of handling keypress decoding and sends the event queue to the QT Py RP2040 over I2C.

Since only one address is possible on the TCA8418 you'll use the two independent I2C buses of the QT Py RP2040.

## Wire Columns and Rows

Solder a wire to each column and row pad on the 6x5 PCBs.

Run these to their corresponding column and row pins on the TCA8418.

Repeat this for the second side.

![3d_printing_IMG_9470.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/993/medium640/3d_printing_IMG_9470.jpg?1666200016)

![3d_printing_sok-9479.jpg](https://cdn-learn.adafruit.com/assets/assets/000/116/005/medium640/3d_printing_sok-9479.jpg?1666210052)

![3d_printing_sok-9478.jpg](https://cdn-learn.adafruit.com/assets/assets/000/116/006/medium640/3d_printing_sok-9478.jpg?1666210061)

## QT Py Prep

In order to plug the STEMMA QT cable into the second I2C bus, solder the STEMMA QT/Qwiic breakout to the SDA, SCL, 3V, and GND pins as shown here.

Note, both sockets on the breakout run to the same on-board I2C bus, so one TCA8418 will plug into the breakout, while the other will plug into the QT Py's on-board STEMMA QT connector.

![3d_printing_sok-9303.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/996/medium640/3d_printing_sok-9303.jpg?1666200628)

![3d_printing_sok-9302.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/997/medium640/3d_printing_sok-9302.jpg?1666200636)

## Case Build

You have two options for the case build -- fully 3D printed or mixed 3D printed with laser cut/CNC acrylic (or other materials). I laser cut my faceplates on an [Epilog](https://www.epiloglaser.com/) Zing 16 machine.

Download the files from the link below.

[3D and 2D fabrication files](https://www.thingiverse.com/thing:5575052)
## 3D Files

If you go with the fully 3D build, print the following files in PLA at ~0.2mm layer height and ~10% infill:

- **sok\_plate x2**
- **sok\_top x2**
- **sok\_base\_L**
- **sok\_baseR**

![](https://cdn-learn.adafruit.com/assets/assets/000/116/002/medium800/3d_printing_sok_3d.jpg?1666202472)

## 3D/2D Mix Files

If you opt for a mix of 3D printed and 2D, here are the files you'll use:

### 3D Printed

- **sok\_qt** 
- **sok\_mid x2**

2D Laser Cut/CNC Milled

- **sok\_curves x2**

![](https://cdn-learn.adafruit.com/assets/assets/000/116/003/medium800/3d_printing_sok_fab.jpg?1666203049)

## Frame Prep

Use your soldering iron to press a threaded M3 brass heat set insert into each of the six mounting holes of the base walls. You use these to screw on the top plate later.

If doing the 3D + laser cut frame, insert a second set of inserts on the back side as well so you can screw on the top plate and the back plate.

![3d_printing_sok-9304.jpg](https://cdn-learn.adafruit.com/assets/assets/000/116/007/medium640/3d_printing_sok-9304.jpg?1666210115)

![3d_printing_sok-9305.jpg](https://cdn-learn.adafruit.com/assets/assets/000/116/008/medium640/3d_printing_sok-9305.jpg?1666210141)

![3d_printing_sok-9306.jpg](https://cdn-learn.adafruit.com/assets/assets/000/116/009/medium640/3d_printing_sok-9306.jpg?1666210149)

![](https://cdn-learn.adafruit.com/assets/assets/000/116/010/medium800/3d_printing_sok-9307.jpg?1666210376)

## Base Prep

Screw in M2.5 stand-offs to support the PCB and breakout board as shown.

You can also add rubber bumper feet.

Then, screw the back plate on using M3 screws (only necessary for the hybrid case build).

![3d_printing_sok-9476.jpg](https://cdn-learn.adafruit.com/assets/assets/000/116/011/medium640/3d_printing_sok-9476.jpg?1666210422)

![3d_printing_sok-9475.jpg](https://cdn-learn.adafruit.com/assets/assets/000/116/012/medium640/3d_printing_sok-9475.jpg?1666210445)

![3d_printing_sok-9473.jpg](https://cdn-learn.adafruit.com/assets/assets/000/116/013/medium640/3d_printing_sok-9473.jpg?1666210452)

![3d_printing_sok-9477.jpg](https://cdn-learn.adafruit.com/assets/assets/000/116/014/medium640/3d_printing_sok-9477.jpg?1666210469)

![](https://cdn-learn.adafruit.com/assets/assets/000/116/015/medium800/3d_printing_sok-9472.jpg?1666210577)

## Switch Plate

To stabilize the keyswitches, snap them into the switch plate. Be sure their header pins are all oriented in the same direction as shown here.

![3d_printing_sok-9290.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/998/medium640/3d_printing_sok-9290.jpg?1666200941)

![3d_printing_sok-9291.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/999/medium640/3d_printing_sok-9291.jpg?1666200948)

![3d_printing_sok-9292.jpg](https://cdn-learn.adafruit.com/assets/assets/000/116/000/medium640/3d_printing_sok-9292.jpg?1666200956)

![3d_printing_sok-9293.jpg](https://cdn-learn.adafruit.com/assets/assets/000/116/001/medium640/3d_printing_sok-9293.jpg?1666200963)

## Attach Keys To PCBs

Carefully align all the pins to the sockets and gently, slowly press the keys into place.

This takes patience and massaging, so maybe put on some soothing music and light a good candle first.

Then add your keycaps. (Ignore the photo that shows the caps already in place during the first step.)

![3d_printing_sok-9295.jpg](https://cdn-learn.adafruit.com/assets/assets/000/116/022/medium640/3d_printing_sok-9295.jpg?1666216046)

![3d_printing_sok-9294.jpg](https://cdn-learn.adafruit.com/assets/assets/000/116/023/medium640/3d_printing_sok-9294.jpg?1666216054)

## Right Side Mounting

On the right side, mount just the TCA8418 and the keyswitch PCB as shown.

![3d_printing_sok-9483.jpg](https://cdn-learn.adafruit.com/assets/assets/000/116/024/medium640/3d_printing_sok-9483.jpg?1666216415)

![3d_printing_sok-9484.jpg](https://cdn-learn.adafruit.com/assets/assets/000/116/025/medium640/3d_printing_sok-9484.jpg?1666216423)

![3d_printing_sok-9485.jpg](https://cdn-learn.adafruit.com/assets/assets/000/116/026/medium640/3d_printing_sok-9485.jpg?1666216435)

![](https://cdn-learn.adafruit.com/assets/assets/000/116/027/medium800/3d_printing_sok-9486.jpg?1666216494)

## Stemma QT Cable Right Side

If you don't think you want to fully disconnect the halves, plug in the STEMMA QT cable as shown. This provides a neater appearance and allows you to push the cable in to adjust the slack.

![3d_printing_sok-9492.jpg](https://cdn-learn.adafruit.com/assets/assets/000/116/028/medium640/3d_printing_sok-9492.jpg?1666216529)

## QT Py Mount

Click the QT Py into its mount, facing the base. This will allow access to the reset and boot buttons through the case bottom's holes.

![3d_printing_sok-9308.jpg](https://cdn-learn.adafruit.com/assets/assets/000/116/016/medium640/3d_printing_sok-9308.jpg?1666214236)

## STEMMA QT Connection

Connect the long STEMMA QT cable for the right half keyboard to the STEMMA QT/Qwiic breakout, using the standoff hardware as routing/strain relief.

![3d_printing_sok-9312.jpg](https://cdn-learn.adafruit.com/assets/assets/000/116/018/medium640/3d_printing_sok-9312.jpg?1666214362)

Plug the short STEMMA QT cable from the QT Py to the TCA8418.

![](https://cdn-learn.adafruit.com/assets/assets/000/116/021/medium800/3d_printing_sok-9314.jpg?1666214581)

![](https://cdn-learn.adafruit.com/assets/assets/000/116/064/medium800/3d_printing_sok-9315.jpg?1666368053)

## Case Top

Add the case top and screw it down using M3 screws into the treaded inserts.

![3d_printing_sok-9487.jpg](https://cdn-learn.adafruit.com/assets/assets/000/116/065/medium640/3d_printing_sok-9487.jpg?1666368092)

![3d_printing_sok-9488.jpg](https://cdn-learn.adafruit.com/assets/assets/000/116/066/medium640/3d_printing_sok-9488.jpg?1666369925)

![3d_printing_sok-9489.jpg](https://cdn-learn.adafruit.com/assets/assets/000/116/067/medium640/3d_printing_sok-9489.jpg?1666369935)

## Connect the Halves

If you didn't connect the right half STEMMA QT cable before closing the case, do so at this time.

![3d_printing_sok-9490.jpg](https://cdn-learn.adafruit.com/assets/assets/000/116/069/medium640/3d_printing_sok-9490.jpg?1666370557)

![3d_printing_sok-9491.jpg](https://cdn-learn.adafruit.com/assets/assets/000/116/070/medium640/3d_printing_sok-9491.jpg?1666370572)

![3d_printing_sok-9466.jpg](https://cdn-learn.adafruit.com/assets/assets/000/116/081/medium640/3d_printing_sok-9466.jpg?1666371427)

![3d_printing_sok-9467.jpg](https://cdn-learn.adafruit.com/assets/assets/000/116/094/medium640/3d_printing_sok-9467.jpg?1666374766)

![](https://cdn-learn.adafruit.com/assets/assets/000/116/073/medium800/3d_printing_sok-9493.jpg?1666370746)

![](https://cdn-learn.adafruit.com/assets/assets/000/116/074/medium800/3d_printing_sok-9494.jpg?1666370759)

![](https://cdn-learn.adafruit.com/assets/assets/000/116/079/medium800/3d_printing_sok-9495.jpg?1666370769)

## USB Cable

Plug in a USB-C cable and you're ready to code and use the keyboard.

![3d_printing_sok-9464.jpg](https://cdn-learn.adafruit.com/assets/assets/000/116/082/medium640/3d_printing_sok-9464.jpg?1666371490)

# Split Ortho Keyboard with TCA8418 Matrix Expanders

## CircuitPython

[CircuitPython](https://github.com/adafruit/circuitpython) is a derivative of [MicroPython](https://micropython.org) designed to simplify experimentation and education on low-cost microcontrollers. It makes it easier than ever to get prototyping by requiring no upfront desktop software downloads. Simply copy and edit files on the **CIRCUITPY** drive to iterate.

## CircuitPython Quickstart

Follow this step-by-step to quickly get CircuitPython running on your board.

[Download the latest version of CircuitPython for this board via circuitpython.org](https://circuitpython.org/board/adafruit_qtpy_rp2040/)
 **Click the link above to download the latest CircuitPython UF2 file.**

Save it wherever is convenient for you.

![install_circuitpython_on_rp2040_RP2040_UF2_downloaded.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/655/medium640/install_circuitpython_on_rp2040_RP2040_UF2_downloaded.jpg?1618943202)

![](https://cdn-learn.adafruit.com/assets/assets/000/101/680/medium800/adafruit_products_QTRP_buttons.jpg?1618956837)

To enter the bootloader, hold down the **BOOT/**** BOOTSEL button**(highlighted in red above), and while continuing to hold it (don't let go!), press and release the**reset button**(highlighted in red or blue above).&nbsp;**Continue to hold the BOOT/BOOTSEL button until the RPI-RP2 drive appears!**

If the drive does not appear, release all the buttons, and then repeat the process above.

You can also start with your board unplugged from USB, press and hold the BOOTSEL button (highlighted in red above), continue to hold it while plugging it into USB, and wait for the drive to appear before releasing the button.

A lot of people end up using charge-only USB cables and it is very frustrating! **Make sure you have a USB cable you know is good for data sync.**

You will see a new disk drive appear called **RPI-RP2**.

&nbsp;

Drag the **adafruit\_circuitpython\_etc.uf2** file to **RPI-RP2.**

![install_circuitpython_on_rp2040_RP2040_bootloader_drive.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/656/medium640/install_circuitpython_on_rp2040_RP2040_bootloader_drive.jpg?1618943666)

![install_circuitpython_on_rp2040_RP2040_drag_UF2.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/657/medium640/install_circuitpython_on_rp2040_RP2040_drag_UF2.jpg?1618943674)

The **RPI-RP2** drive will disappear and a new disk drive called **CIRCUITPY** will appear.

That's it, you're done! :)

![install_circuitpython_on_rp2040_RP2040_CIRCUITPY.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/658/medium640/install_circuitpython_on_rp2040_RP2040_CIRCUITPY.jpg?1618943864)

## Safe Mode

You want to edit your **code.py** or modify the files on your **CIRCUITPY** drive, but find that you can't. Perhaps your board has gotten into a state where **CIRCUITPY** is read-only. You may have turned off the **CIRCUITPY** drive altogether. Whatever the reason, safe mode can help.

Safe mode in CircuitPython does not run any user code on startup, and disables auto-reload. This means a few things. First, safe mode _bypasses any code in_ **boot.py** (where you can set **CIRCUITPY** read-only or turn it off completely). Second, _it does not run the code in_ **code.py**. And finally, _it does not automatically soft-reload when data is written to the_ **CIRCUITPY** _drive_.

Therefore, whatever you may have done to put your board in a non-interactive state, safe mode gives you the opportunity to correct it without losing all of the data on the **CIRCUITPY** drive.

### Entering Safe Mode
To enter safe mode when using CircuitPython, plug in your board or hit reset (highlighted in red above). Immediately after the board starts up or resets, it waits 1000ms. On some boards, the onboard status LED (highlighted in green above) will blink yellow during that time. If you press reset during that 1000ms, the board will start up in safe mode. It can be difficult to react to the yellow LED, so you may want to think of it simply as a slow double click of the reset button. (Remember, a fast double click of reset enters the bootloader.)

### In Safe Mode

If you successfully enter safe mode on CircuitPython, the LED will intermittently blink yellow three times.

If you connect to the serial console, you'll find the following message.

```terminal
Auto-reload is off.
Running in safe mode! Not running saved code.

CircuitPython is in safe mode because you pressed the reset button during boot. Press again to exit safe mode.

Press any key to enter the REPL. Use CTRL-D to reload.
```

You can now edit the contents of the **CIRCUITPY** drive. Remember, _your code will not run until you press the reset button, or unplug and plug in your board, to get out of safe mode._

## Flash Resetting UF2

If your board ever gets into a really _weird_ state and CIRCUITPY doesn't show up as a disk drive after installing CircuitPython, try loading this 'nuke' UF2 to RPI-RP2. which will do a 'deep clean' on your Flash Memory. **You will lose all the files on the board** , but at least you'll be able to revive it! After loading this UF2, follow the steps above to re-install CircuitPython.

[Download flash erasing "nuke" UF2](https://cdn-learn.adafruit.com/assets/assets/000/101/659/original/flash_nuke.uf2?1618945856)
# Split Ortho Keyboard with TCA8418 Matrix Expanders

## Code the Split Ortho Keyboard

## Text Editor

Adafruit recommends using the **Mu** editor for editing your CircuitPython code. You can get more info in [this guide](https://learn.adafruit.com/welcome-to-circuitpython/installing-mu-editor).

Alternatively, you can use any text editor that saves simple text files.

## Download the Project Bundle

Your project will use a specific set of CircuitPython libraries, the&nbsp; **code.py** &nbsp;file and the **keymaps.py** file. To get everything you need, click on the&nbsp; **Download Project Bundle** &nbsp;link below, and uncompress the .zip file.

Drag the contents of the uncompressed bundle directory onto your board's **CIRCUITPY** &nbsp;drive, replacing any existing files or directories with the same names, and adding any new ones that are necessary.

![](https://cdn-learn.adafruit.com/assets/assets/000/116/095/medium800/3d_printing_sok-9447.jpg?1666374809)

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Split_Ortho_Keyboard/code.py

## How It Works

The keyboard uses two **TCA8418** expanders to read the matrix columns and rows of the keyboard halves. The events are queued up and sent over I2C to the **QT Py RP2040** &nbsp;which then correlates each keypress with a keycode from the **keymaps.py** file. These keypresses are then sent to the computer as USB HID keys.

## Libraries

You'll import libraries to provide functionality in the code:

- **time**
- **board**
- **adafruit\_tca8418**
- **usb\_hid**
- **adafruit\_hid.keyboard**
- **adafruit\_hid.keycode**

The `keymaps` **&nbsp;** file is imported as well so that the `layer_keymaps` can be accessed inside of **code.py**

```auto
import time
import board
from adafruit_tca8418 import TCA8418
import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode
from keymaps import layer_keymaps
```

## HID Setup

The USB HID keyboard is set up along with variables for the key layers.

```auto
kbd = Keyboard(usb_hid.devices)
num_layers = len(layer_keymaps)
current_layer = 1
```

## I2C Setup

You'll use both I2C channels on the **QT Py RP2040** to connect to the two **TCA8418** boards. Since they share the same address which cannot be changed, they can't be on the same I2C bus.

```auto
i2c_left = board.STEMMA_I2C()  # uses QT Py RP2040 STEMMA QT port
i2c_right = board.I2C()  # I2C channel on the QT Py RP2040 pads broken out on board
tca_left = TCA8418(i2c_left)
tca_right = TCA8418(i2c_right)
tcas = (tca_left, tca_right)  # put the TCA objects in a list for easy iteration later
```

## Matrix Pins

The column and row pins of the TCA8418 are fixed, so we'll specify the ones we're using for the six columns and five rows of the keyboard halves.

Then, each pin is set to `keypad_mode` with `enable` and `fifo` (first in, first out) set.

```auto
KEYPADPINS = (
                TCA8418.R0, TCA8418.R1, TCA8418.R2, TCA8418.R3, TCA8418.R4,
                TCA8418.C0, TCA8418.C1, TCA8418.C2, TCA8418.C3, TCA8418.C4, TCA8418.C5
)

for tca in tcas:
    for pin in KEYPADPINS:
        tca.keypad_mode[pin] = True
        tca.enable_int[pin] = True
        tca.event_mode_fifo[pin] = True
    tca.key_intenable = True
```

## Main Loop

The main loop of the program checks each TCA8418 for events in the queue. If a key has been pressed or released it is checked against the keymap file to see which keycode to press or release. These can vary depending on modifiers and layers as well.

```auto
while True:
    for i in range(len(tcas)):
        tca = tcas[i]  # get the TCA we're working with
        keymap = layer_keymaps[current_layer][i]  # get the corresponding keymap for it
        if tca.key_int:
            events = tca.events_count
            for _ in range(events):
                keyevent = tca.next_event
                keymap_number = (keyevent &amp; 0x7F)
                (modifier, keycode) = keymap[keymap_number]  # get keycode &amp; modifer from keymap
                #  print("\tKey event: 0x%02X - key #%d " % (keyevent, keyevent &amp; 0x7F))
                if keycode is None:
                    pass

                else:
                    if keyevent &amp; 0x80:  # if key is pressed
                        if modifier == 0:  # normal keypress
                            kbd.press(keycode)
                        elif modifier == 1:  # lower
                            current_layer = min(max((current_layer-1), 0), num_layers-1)
                        elif modifier == 2:  # raise
                            current_layer = min(max((current_layer+1), 0), num_layers-1)
                        elif modifier == 7:  # cap mod
                            kbd.press(Keycode.SHIFT, keycode)

                    else:  # key released
                        if modifier == 7:  # capped shifted key requires special handling
                            kbd.release(Keycode.SHIFT, keycode)
                        else:
                            kbd.release(keycode)

            tca.key_int = True  # clear the IRQ by writing 1 to it
            time.sleep(0.01)
```

## keymaps.py
https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Split_Ortho_Keyboard/keymaps.py

The keymaps.py file first imports the `adafruit_hid.keycode` library.

`from adafruit_hid.keycode import Keycode`

The file is organized by keymap sides (left/right), layers (0, 1, 2), and row clusters (1-6, 11-16, 21-26, etc.) These are dictionaries which have a "key" which corresponds to the key number as reported by the TCA8418, and a value tuple which tells the code two things: which **modifier** , and which **keycode&nbsp;** to use.

The modifier is usually 0 which means the keycode is sent as a normal keypress/release.

Modifer 1 means the "lower" key has been pressed, so a different keymap set is to be used until the "raise" key is pressed.

Modifier 2 means "raise"

Modifier 7 means a `Keycode.SHIFT` + the keycode are pressed at the same time. Normally you use the shift key to get this effect, but in some cases you may want to assign a key that is normally only invoked via shift. For example, a `{` key is usually shift + `Keycode.LEFT_BRACKET`, but if you want a key to press `{` all on its own, use modifier 7.


## Featured Products

### Adafruit QT Py RP2040

[Adafruit QT Py RP2040](https://www.adafruit.com/product/4900)
What a cutie pie! Or is it... a QT Py?&nbsp;This diminutive dev board comes with one of our new favorite chip, the RP2040. It's been made famous in the new [Raspberry Pi Pico](https://www.adafruit.com/pico) _and_ our [Feather...](http://www.adafruit.com/product/4884)

In Stock
[Buy Now](https://www.adafruit.com/product/4900)
[Related Guides to the Product](https://learn.adafruit.com/products/4900/guides)
### Adafruit TCA8418 Keypad Matrix and GPIO Expander Breakout

[Adafruit TCA8418 Keypad Matrix and GPIO Expander Breakout](https://www.adafruit.com/product/4918)
It's a GPIO expander, it's a keypad matrix driver... its the **Adafruit TCA8418 Keypad Matrix and GPIO Expander Breakout** - a cute and powerful I2C GPIO expander&nbsp;_and_ keypad matrix driver! This chip is quite fancy, with the ability to act as your I2C...

In Stock
[Buy Now](https://www.adafruit.com/product/4918)
[Related Guides to the Product](https://learn.adafruit.com/products/4918/guides)
### STEMMA QT / Qwiic JST SH 4-Pin Cable - 400mm long

[STEMMA QT / Qwiic JST SH 4-Pin Cable - 400mm long](https://www.adafruit.com/product/5385)
This 4-wire cable is a little over 400mm / 15.7" long and fitted with JST-SH female 4-pin connectors on both ends. Compared with the chunkier JST-PH these are 1mm pitch instead of 2mm, but still have a nice latching feel, while being easy to insert and remove.

<a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/5385)
[Related Guides to the Product](https://learn.adafruit.com/products/5385/guides)
### NeoKey 5x6 Ortho Snap-Apart Mechanical Key Switches w/ NeoPixel

[NeoKey 5x6 Ortho Snap-Apart Mechanical Key Switches w/ NeoPixel](https://www.adafruit.com/product/5157)
For folks who want ready-to-go keeb action, we've got the lovely [Adafruit Macropad with a 3x4 grid of MX+NeoPixel key switches](https://www.adafruit.com/product/5100) - but for those who like to forge their own path, we now present the easiest way of creating custom ortholinear...

Out of Stock
[Buy Now](https://www.adafruit.com/product/5157)
[Related Guides to the Product](https://learn.adafruit.com/products/5157/guides)
### Kailh Mechanical Key Switches - Linear Black - 10 pack

[Kailh Mechanical Key Switches - Linear Black - 10 pack](https://www.adafruit.com/product/4953)
For crafting your very own custom keyboard, these **&nbsp;Kailh Black&nbsp;Linear mechanical key switches** &nbsp;are deeee-luxe! With smooth actuation and Cherry MX compatibility, they're lovely when you want a&nbsp; **smooth linear&nbsp;** keystroke with a...

In Stock
[Buy Now](https://www.adafruit.com/product/4953)
[Related Guides to the Product](https://learn.adafruit.com/products/4953/guides)
### Brass Heat-Set Inserts for Plastic - M3 x 4mm - 50 pack

[Brass Heat-Set Inserts for Plastic - M3 x 4mm - 50 pack](https://www.adafruit.com/product/4255)
Wanna improve the connection strength between your project's 3D-printed parts, and also have nice clean surfaces? Instead of gluing bits together, or screwing plastic screws directly into your 3D prints, use strong and reusable machine screws and heat-set inserts. Heat set inserts are only...

In Stock
[Buy Now](https://www.adafruit.com/product/4255)
[Related Guides to the Product](https://learn.adafruit.com/products/4255/guides)
### Black Nylon Machine Screw and Stand-off Set – M2.5 Thread

[Black Nylon Machine Screw and Stand-off Set – M2.5 Thread](https://www.adafruit.com/product/3299)
Totaling 380 pieces, this **M2.5 Screw Set** &nbsp;is a must-have for your workstation.&nbsp;You'll have enough screws, nuts, and hex standoffs to fuel your maker tendencies&nbsp;for days on end! M2.5 size screws fit almost all of the Adafruit breakout/dev board mounting holes...

In Stock
[Buy Now](https://www.adafruit.com/product/3299)
[Related Guides to the Product](https://learn.adafruit.com/products/3299/guides)
### Black Nylon Machine Screw and Stand-off Set – M3 Thread

[Black Nylon Machine Screw and Stand-off Set – M3 Thread](https://www.adafruit.com/product/4685)
Totaling **420 pieces** , this **M3 Screw Set** &nbsp;is a must-have for your workstation.&nbsp;You'll have enough screws, nuts, and hex standoffs to fuel your maker tendencies&nbsp;for days on end! M3 size screws fit a number of&nbsp;Adafruit breakout/dev board...

In Stock
[Buy Now](https://www.adafruit.com/product/4685)
[Related Guides to the Product](https://learn.adafruit.com/products/4685/guides)

## Related Guides

- [Adafruit QT Py RP2040](https://learn.adafruit.com/adafruit-qt-py-2040.md)
- [Adafruit NeoKey 5x6 Ortho Snap-Apart](https://learn.adafruit.com/adafruit-neokey-5x6-ortho-snap-apart.md)
- [Adafruit TCA8418 Keypad Matrix and GPIO Expander Breakout](https://learn.adafruit.com/adafruit-tca8418-keypad-matrix-and-gpio-expander-breakout.md)
- [Solderless Robot Toy Xylophone](https://learn.adafruit.com/solderless-robot-toy-xylophone.md)
- [Deluxe 4x4 NeoPixel Keypad](https://learn.adafruit.com/deluxe-4x4-neopixel-neokey-keypad.md)
- [NFC Raspberry Pi Media Player](https://learn.adafruit.com/nfc-raspberry-pi-media-player.md)
- [Qualia S3 Compass](https://learn.adafruit.com/qualia-s3-compass.md)
- [Servo Boss](https://learn.adafruit.com/servo-boss.md)
- [Ambient Color Control Pad](https://learn.adafruit.com/ambient-color-controller.md)
- [CircuitPython OctoPrint Controller and Monitor](https://learn.adafruit.com/circuitpython-octoprint-controller-and-monitor.md)
- [Pi SSD Media Server](https://learn.adafruit.com/pi-ssd-media-server.md)
- [Customizing USB Devices in CircuitPython](https://learn.adafruit.com/customizing-usb-devices-in-circuitpython.md)
- [Party Parrot Zoetrope](https://learn.adafruit.com/party-parrot-zoetrope.md)
- [Severance Portable Macrodata Refinement Terminal](https://learn.adafruit.com/portable-macrodata-refinement-terminal.md)
- [LED Matrix Scoreboard](https://learn.adafruit.com/led-matrix-scoreboard.md)
- [NeXT Computer Keyboard to USB HID with CircuitPython](https://learn.adafruit.com/next-computer-keyboard-to-usb-hid-with-circuitpython.md)
- [Mystery Box: Crypto Countdown Case](https://learn.adafruit.com/mystery-box-crypto-countdown-case.md)
