The most hackable keyboard in all the land

Related tags

MiscellaneousMiRage
Overview

MiRage Modular Keyboard

© 2021 Zack Freedman of Voidstar Lab

Licensed Creative Commons 4.0 Attribution Noncommercial Share-Alike

The MiRage is a 60% ortholinear keyboard with three clickable OLED displays, intended for Kailh Choc switches and running custom CircuitPython firmware on a Seeedstudio Xiao RP2040.

THIS PROJECT IS INCOMPLETE. DO NOT MAKE IT.

The PCB can be populated as-is for a "plank" keyboard or broken in half for a split board. The right half can be used independently as the Rage Pad numberpad/macro pad/stream deck.

This was designed for a YouTube video on my channel: https://youtu.be/Fg0V5M0llaE It will be improved and sold as a kit, and will form part of a larger project called the Fata Morgana cyberdeck.

Fusion 360 model: https://a360.co/3vEh6YI

The PCB, firmware, keymaps, and models have major issues that need to be fixed before moving forward. This project is not ready to be reproduced. Do not attempt to make it. Keymap instructions, assembly guide, BOM, and other documentation will be provided once the project is ready for release.

My component choices are final. Attempts to change my mind will be roasted in a future video.

Libraries are temporarily included for testing purposes. These will be replaced by references on release.

Keymaps are lists of bindings in the format: R[Row #], K[Key #]: [Key name (optional)] # Comments start with a hash On press: [Command(s) to perform once as soon as user presses key] On click: [Command(s) to perform when user presses and releases key within a few hundred milliseconds] On double-click: [Command(s) to perform when user presses and releases key twice within a few hundred milliseconds. The dash in 'double-click' is not optional.] On hold: [Command(s) to perform when user holds key for more than a few hundred ms. These generally repeat or remain in effect until the key is released.] On release: [Command(s) to perform once when user releases key. This is done after On Click and On Double-Click events are finished, and after ongoing On Hold events are cleaned up.]

Actions you can bind to a key or event:

  • LEFT SHIFT: Specify key bindings by naming them in all caps. You can see all the available key names in keynames.py. Key names must be in all caps. Spaces are optional. If a key is bound inline, it binds all events.
  • Click LEFT SHIFT: This key will be pressed and instantly released a single time, even if this is called by an On Hold event. Clicking a key that's already Pressed will release, press, and release it.
  • Press LEFT SHIFT: This key will be pressed indefinitely. Pressing a key that's already Pressed has no effect. Remember to add a way to release it...
  • Release LEFT SHIFT: This key will be released. No effect if the key is not Pressed.
  • CTRL + ALT + DELETE: Performs an operation on multiple keys simultaneously. You can Click, Press, Release, or straight-up bind key combos as if they were individual keys! Spaces around the plus signs are optional.
  • Switch to Numpad Layer: Invokes specified layer indefinitely. This is case-insensitive. You don't need to include the layer's extension. Make sure to read the Layer Gotchas below!
  • Leave Numpad Layer: If specified layer is currently invoked, dismisses it.
  • Switch to Numpad Layer until released: Invokes the specified layer as long as this key remains held, and dismisses it when released. Cannot be bound to On Press, On Click, On Double-Click, or On Release events. While in effect, layers above the one that defined this action do not apply to this key.
  • Toggle Numpad Layer: Acts as a Switch To action if specified layer is not currently in effect, and a Leave action if it is. Note that this can be blocked by layers above it, so make sure the new layer leaves this key open!
  • Go home: Dismisses all invoked layers.
  • Type "Hello world!": Types the specified string a single time, one letter at a time. Don't put double quotes and commas in the string! Use [DOUBLE QUOTES] and [COMMA] instead! Any necessary keys that are currently Pressed will be released, pressed, and released again.
  • Type "Hello World!" repeatedly: When bound to an On Press or On Hold event, types the string over and over. Extremely annoying.
  • wait 200ms: Blocks everything for that much time. You can specify milliseconds, seconds, or minutes, in full or using ms, msec, sec, s, m, or min. Used in command sequences.
  • Click WIN+R, wait 200ms, type "cmd", click ENTER: Sequence any combination of actions with commas. Each action is performed in its entirety before moving on. The On Hold behavior of a command sequence is not yet defined.
  • Nothing: Allows keys on upper layers to block actions on lower layers without any side effects.
  • Pass through: Sends this operation to the next lowest layer.
  • Reload keymaps: Triggers a Go Home action, then reloads all the keymaps.
  • Reset keyboard: Triggers a software reset - disconnects from PC, reloads keymaps, and reconnects.
  • Bootloader: Enters UF2 bootloader - disconnects from PC, kills CircuitPython, and reconnects as UF2 flash drive. There is no way to return from the bootloader to the code without unplugging the keyboard. This is an inbuilt limit of the bootloader and beyond my control.

Row and key numbers are zero-indexed, and refer to the physical placement of the keys on the keyboard. These have nothing to do with the schematic. It's common sense numbering Row 0, Key 0 is the top-left key.

Whitespace and line terminators are irrelevent. You can even use tabs, you sick bastard. UTF-8 encoding is strongly recommended; not sure how well Python handles bigger characters.

You can actually define the same key and same key action multiple times in the same map. This has the same effect as creating Sequences, and is extremely obnoxious to debug. I can't prevent you from doing it, but I can say "I told you so."

Layer Gotchas!

  • Each layer's name is the same as the filename of the keymap that defined it, and is case- and extension-insensitive. If multiple keymap files have the same name with different capitalization, the keyboard will crash on purpose just to spite you.
  • One layer must be called Base Layer. This is not optional. The keyboard will not boot unless there's an applicable Base Layer.
  • The Base Layer is always in effect. When another layer is invoked, it's "stacked" on top. Invoking another layer stacks it on the other layer, and so on.
  • When a key event happens, it's sent to the topmost layer. If that layer doesn't handle it, the next layer is checked, and so on. If you want the event to fall through anyways, such as in a sequence, use the Pass through action.
  • Layer-related actions DO NOT apply immediately. Instead, the system reads every key, completes every Action fired, then applies any layer actions. This makes the layer switching process more predictable if multiple keys were pressed.
  • When a layer is invoked, if it's already in the stack, it's moved to the top.
  • You cannot invoke or dismiss the Base Layer. Attempting to do so has no effect.
  • The layer(s) selected by Layer Select Widgets have special slots above the Base Layer and just below the layer stack. If multiple clicky displays have Layer Select Widgets, the top screen layer is just below the layer stack and the bottom screen layer just above the Base Layer.
  • If a layer selected by a Layer Select Widget is invoked, it moves from its special slot to the top of the stack. If it's dismissed, it returns to its special slot.
  • Folders are provided for MiRage and Rage keymaps. Only the relevant ones apply.
  • Needs to be implemented: When a layer is dismissed, if one or more keys with On Hold events defined by that layer are held, the On Hold ends. If one or more held keys have an On Release event, it's called. Pass Through actions in these events are ignored.

PCB problems to fix:

  • VDD and VSS supply pins of PCA9505 I/O expanders are reversed
  • RESET pins of PCA9505s must be pulled up
  • Choc footprints will be extended to support Cherry MX switches
  • Cut relief under microcontroller footprint for Adafruit QT PY. This part is NOT currently compatible.
  • Increase size and number of breakaway tabs
  • Right-angle headers are too far apart
  • Add at least 4 keys
  • Bottom screws are blocked by lowest row of keycaps
  • Split is shifted one row to the left from usual typing position

Enclosure problems to fix:

  • Missing holes to access BOOT and RESET buttons
  • Missing holes to view onboard LEDs
  • Cutout for USB cable is too small
  • Rubber foot relief diameter too small and prone to sagging
  • Bottom feet are too far from edges
  • A small amount of PCB text is visible - poor fit and finish
  • Magnetic applique falls off too easily
  • Plank enclosure has header relief on wrong side
  • Display buttons can crack if mashed down very hard

Code problems to fix (that I can remember off the top of my head, there are a lot)

  • Rage board not implemented (not detected or automatically switched)
  • Unplugging left side during runtime causes crash
  • Code needs to be sped up about 200%
  • Widget updating code needs to be sped up about 5000%
  • Rage keymaps are missing layer switches
  • Only key bindings can be defined inline
  • Interactions between key event bindings and inline key bindings are unspecified
  • Hold events lag, as if a click or double-click event were also bound
  • Double-clicking also fires Click event
  • Ongoing Hold events end sloppily if a layer switch overrides that binding
  • No visual feedback for syntax errors, exceptions, layer switches, modal Lock keys, etc
  • We need more widgets
  • Fallback behavior in case of keymap errors
  • Occasional failure to auto-run code on boot
  • Including a comma in a 'Type' command crashes parser
  • If a key down command is sent then a Bootloader command runs, the key is never released
  • Configuration setting is needed to redefine WINDOWS and ALT to GUI and OPTION
  • Poor performance is due to CircuitPython, not I/O expanders. These I/O expanders can be polled over 1,000 times a second. This code would be MASSIVELY slower if a matrix were used instead of I/O expanders.

Additional things to create:

  • Plank enclosure without 3.5mm plug relief
  • Split enclosure with header relief
  • Rage (right hand) enclosure without 3.5mm plug relief
  • Dashboard widget
  • Widget that interacts with desktop
  • Set typing speed
  • Enable/disable NKRO (hardcoded enabled for now due to nature of boot.py)
  • Config file with widget assignments, click/hold timeout, base repeat rate, etc
  • ZIF connectors to attach the MiRage to other Fata Morgana components via ribbon cables
Owner
Zack Freedman
I make projects and then I make YouTube videos about 'em. Sometimes I make streams while making projects. It's honest work.
Zack Freedman
Robotic hamster to give you financial advice

hampp Robotic hamster to give you financial advice. I am not liable for any advice that the hamster gives. Follow at your own peril. Description Hampp

1 Nov 17, 2021
Automatically deletes Capital One Eno virtual cards for when you've made a couple too many.

eno-delete Automatically deletes Capital One Eno virtual cards for when you've made a couple too many. Warning: Program will delete ALL virtual cards

h3x 3 Sep 29, 2022
Function Plotter✨

Function-Plotter Build With : Python PyQt5 unittest matplotlib Getting Started This is an list of needed instructions to set up your project locally,

Ahmed Lotfy 3 Jan 06, 2022
WMIC Serial Checker For Python

WMIC Serial Checker Follow me here: Discord | Github FR: A but éducatif seulement. EN: For educational purposes only. ❓ Informations FR: WMIC Serial C

AkaTool's 0 Apr 25, 2022
A light library to build tiny websites

A light library to build tiny websites

BT.Q 1 Dec 23, 2021
The LiberaPay archive module for the SeanPM life archive project.

By: Top README.md Read this article in a different language Sorted by: A-Z Sorting options unavailable ( af Afrikaans Afrikaans | sq Shqiptare Albania

Sean P. Myrick V19.1.7.2 1 Aug 26, 2022
AHP Calculator - A method for organizing and evaluating complicated decisions, using Maths and Psychology

AHP Calculator - A method for organizing and evaluating complicated decisions, using Maths and Psychology

16 Aug 08, 2022
JD扫码获取Cookie 本地版

JD扫码获取Cookie 本地版 请无视手机上的提示升级京东版本的提示! 下载链接 https://github.com/Zy143L/jd_cookie/releases 使用Python实现 代码很烂 没有做任何异常捕捉 但是能用 请不要将获取到的Cookie发送给任何陌生人 如果打开闪退 请使

Zy143L 420 Dec 11, 2022
🌌 Economics Observatory Visualisation Repository

Economics Observatory Visualisation Repository Website | Visualisations | Data | Here you will find all the data visualisations and infographics attac

Economics Observatory 3 Dec 14, 2022
A project for the Qvault Hackathon, 2022-01-17

musical-octo-engine Steps to run brew install python-tk brew install portaudio

Erik Kristofer Anderson 2 May 17, 2022
Backend/API for the Mumble.dev, an open source social media application.

Welcome to the Mumble Api Repository Getting Started If you are trying to use this project for the first time, you can get up and running by following

Dennis Ivy 189 Dec 27, 2022
Python Control Systems Library

The Python Control Systems Library is a Python module that implements basic operations for analysis and design of feedback control systems.

Control Systems Library for Python 1.3k Jan 06, 2023
AminoAutoRegFxck/AutoReg For AminoApps.com

AminoAutoRegFxck AminoAutoRegFxck/AutoReg For AminoApps.com Termux apt update -y apt upgrade -y pkg install python git clone https://github.com/LilZev

3 Jan 18, 2022
Recreating my first CRUD in python, but now more professional

Recreating my first CRUD in python, but now more professional

Ricardo Deo Sipione Augusto 2 Nov 27, 2021
Get the stats of a (or more) Hypixel player(s)

Hypixel_Stats Get the statistics of a (or more) Hypixel player(s) Who needs this? Everyone who plays a lot of Minecraft and often plays on mc.hypixel.

Finnomator 1 Feb 12, 2022
Empresas do Brasil (CNPJs)

Biblioteca em Python que coleta informações cadastrais de empresas do Brasil (CNPJ) obtidas de fontes oficiais (Receita Federal) e exporta para um formato legível por humanos (CSV ou JSON).

BR-API: Democratizando dados do Brasil. 8 Aug 17, 2022
Install Firefox from Mozilla.org easily, complete with .desktop file creation.

firefox-installer Install Firefox from Mozilla.org easily, complete with .desktop file creation. Dependencies Python 3 Python LXML Debian/Ubuntu: sudo

rany 7 Nov 04, 2022
Hello World in different languages !

Hello World And some Examples in different Programming Languages This repository contains a big list of programming languages and some examples for th

AmirHossein Mohammadi 131 Dec 26, 2022
A Python program for calculating the 95%CI for GNSS-derived site velocities

GNSS_Vel_95%CI A Python program for calculating the 95%CI for GNSS-derived site velocities Function_GNSS_95CI.py is a Python function for calculating

<a href=[email protected]"> 4 Dec 16, 2022
Improving the Transferability of Adversarial Examples with Resized-Diverse-Inputs, Diversity-Ensemble and Region Fitting

Improving the Transferability of Adversarial Examples with Resized-Diverse-Inputs, Diversity-Ensemble and Region Fitting

Junhua Zou 7 Oct 20, 2022