Creating tools for Developers

DATE 2025-01-18 -- TIME 09:07:07

Tools

Description

Mechy // C++ Mechanical Keyboard Framework

This is a mechanical keyboard library, in the same spirit as QMK but it doesn't share any code with that project. Only supports the Atmega32u4 for now, but support for other microcontrollers was in mind. As other boards become supported I'll make sure to list them here and include examples for them.

Mechy is designed around C++ Plugin classes

Btw I'll make lots of comparisons to QMK here and I'll try not to disparage it. It's a fantastic tool, and is responsible for the rise in interest in mechanical keyboards. I have to make the comparisons because it's the only other keyboard firmware tool that I'm familiar with. I found it a bit clunky and I couldn't get the split code to work on my BFO-9000, so I started this project.

Mechy is built using Arduino but this might change. Arduino does unfortunate things in their USB/HID code (the TX/RXLED on/off "feature") that prevents it from working with some boards, like the XD75. So I'd like to transition away from Arduino and rely instead on a Makefile/CLI. I could use some help on that! I've already ported all the pinMode/digitalRead/digitalWrite code (see Wiring.h/cpp) so that ALL the I/O ports/pins can be utilized, and I have a work-in-progress folder where I copied all the relevant Arduino libaries, I just need to get them to compile and linked. I don't really know how to use avr-gcc/avr-g++.

See the examples first to see if this library appeals to you:

  • Basic.ino - A basic Planck (rev1-5, using the Atmega32u4) with just one layer. Doesn't use the Hardware class, to keep things simple.
  • Numpad.ino - simple 4x5 layout, uses a bunch of plugins
  • Layers.ino - I copied and modified my XD75 layout, uses layers and all my favorite plugins
  • Planck.ino - A port of the Planck default layout, with layers and Hardware object.
  • DZ60.ino - A port of the DZ60 default layout, but with unsupported features and macros removed - a good starting point for a new layout.
  • LeftSplit.ino - left side of a BFO9000 keyboard, uses split feature
  • RightSplit.ino - right side of a BFO9000 keyboard.
  • My Layout - my own personal Mechy layout.

Supported Keyboards

Right now only keyboards that use the Atmega32u4 are supported, but I think it will be easy to add support for other boards that have USB HID support.

I wrote this firmware to support three keyboards that I enjoy: XD75, BFO9000, and the Iris, which all use the 32u4. These boards were not created with Arduino in mind, in particular they use pins B0 (aka RXLED) and D5 (aka TXLED) as digital I/O pins, whereas most Arduino boards wire these to LEDs to show off serial and USB communication.

To solve this, and make these pins available as digital I/O pins, I created a custom board variant that turns RXLED and TXLED into no-ops. You should install this board definition and use it instead of the usual "Leonardo" board. Open preferences and add this URL to "Additional Board Manager URLs". If you have URLs there already, make sure to separate this one with a comma.

https://raw.githubusercontent.com/colinta/grayduino/json/package_colinta_grayduino_index.json

Next you need to install the board, so open the "Board Manager" (Tools → Board: "..." → Boards Manager…) and search for gray, and click the Install button: board manager screenshot showing grayduino search.

Then you'll have a new board "Grayduino Atmega32u4".

Migrating from QMK

If you've been using QMK and want to start using Mechy you'll need to install the Arduino bootloader onto your keyboard. It sounds daunting, but it's not too bad. You'll need either an FTDI progammer or a spare Arduino. Here are instructions on the Arduino ISP method: https://www.arduino.cc/en/Tutorial/ArduinoISP.

The XD75 and other keyboards (e.g. GH60) has the SPI programming headers, but they're vertical instead of in the 2x3 grid. If you have one of these boards look for the headers in the middle or edge of the board, find the one that is a square instead of a circle, that's "Pin 1". Solder some headers in, and wire it up like the instructions say (Keyboard Pin 1 goes to Arduino Pin 12, Pin 2 to 5V, Pin 3 to Pin 13, Pin 4 to Pin 11, Pin 5 to Pin 10, Pin 6 to GND).

Usage

Include the main library (Mechy.h), include your plugins (Mechy/KeyPress.h, Mechy/MediaKey.h), define the pins for your keyboard (better yet use a Hardware header to do this). Then define your layout, create a few plugin objects, and add mechy.begin() and mechy.tick() to setup() and loop(). Easy! (I think.)

If a keyboard is available (in Keyboards.h) the process is even slightly easier: the pins will be defined for you, and you can create a Hardware instance. This will make it easy to use keyboard features like LEDs and sound. The Hardware author needs to write this class to support what that keyboard is capable of, or you can use it as a starting point and do your own thing!

The keyboard header will also define handy LAYOUT macros and a keyboard template that you can use. The macro is nice because it can take into account staggering and keys that span multiple rows & columns.

[G] https://github.com/colinta/Mechy

Video tutorial