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
Account Manager / Nuker with GUI.

Account Manager / Nuker Remove all friends Block all friends Leave all servers Mass create servers Close all dms Mass dm Exit Setup git clone https://

Lodi#0001 1 Oct 23, 2021
Jogo em redes similar ao clássico pedra papel e tesoura

Batalha Tática Tecnologias de Redes de Computadores-A-N-JOGOS DIGITAIS Professor Fabio Henrique Cabrini Alunos: Eric Henrique de Oliveira Silva - RA 1

Eric Henrique de Oliveira Silva 1 Dec 01, 2021
Python requirements.txt Guesser

Python-Requirements-Guesser ⚠️ This is alpha quality software. Work in progress Attempt to guess requirements.txt modules versions based on Git histor

Jerome 9 May 24, 2022
Translation patch for Hololive ERROR

Translation patch for Hololive ERROR How do I install the patch? Grab the Translation.zip file for the latest version from the releases page, and unzi

18 Jul 20, 2022
Python3 Interface to numa Linux library

py-libnuma is python3 interface to numa Linux library so that you can set task affinity and memory affinity in python level for your process which can help you to improve your code's performence.

Dalong 13 Nov 10, 2022
Exercicios de Python do Curso Em Video, apresentado por Gustavo Guanabara.

Exercicios Curso Em Video de Python Exercicios de Python do Curso Em Video, apresentado por Gustavo Guanabara. OBS.: Na data de postagem deste repo já

Lorenzo Ribeiro Varalo 0 Oct 21, 2021
Machine Learning powered app to decide whether a photo is food or not.

Food Not Food dot app ( 🍔 🚫 🍔 ) Code for building a machine Learning powered app to decide whether a photo is of food or not. See it working live a

Daniel Bourke 48 Dec 28, 2022
Code repository for the Pytheas submersible observation platform

Pytheas Main repository for the Pytheas submersible probe system. List of Acronyms/Terms USP - Underwater Sensor Platform - The primary platform in th

UltraChip 2 Nov 19, 2022
MeepoBenchmark - This project aims at providing the scripts, logs, and analytic results for Meepo Blockchain

MeepoBenchmark - This project aims at providing the scripts, logs, and analytic results for Meepo Blockchain

Peilin Zheng 3 Aug 16, 2022
Multiple GNOME terminals in one window

Terminator by Chris Jones [email protected] and others. Description Terminator was

GNOME Terminator 1.5k Jan 01, 2023
Python programs, usually short, of considerable difficulty, to perfect particular skills.

Peter Norvig MIT License 2015-2020 pytudes "An étude (a French word meaning study) is an instrumental musical composition, usually short, of considera

Peter Norvig 19.9k Dec 27, 2022
Hack CMU Go Local Project

GoLocal A submission for the annual HackCMU Hackathon. We built a website which connects shopper with local businesses. The goal is to drive consumers

2 Oct 02, 2021
Automatic and platform-independent unpacker for Windows binaries based on emulation

_ _ __ _ __ _ | | | | / / (_) \ \ | | | | | |_ __ | | _ | | _ __ __ _ ___| | _____ _ __

514 Dec 21, 2022
Backtest framework based on DAGs

MultitaskQueue It's a simple framework based on three composed concepts: Task: A task is the smaller unit of execution or simple a node in the DAG, ev

4 Dec 09, 2021
Um pequeno painel de consulta

Spynel Um pequeno painel com consultas de: IP CEP PLACA CNPJ OBS: caso execute o script pelo termux, recomendo que use o da F-Droid por ser mais atual

Spyware 12 Oct 25, 2022
a bit of my project :) and I use some of them for my school lesson or study for an exam! but some of them just for myself.

Handy Project a bit of my project :) and I use some of them for my school lesson or study for an exam! but some of them just for myself. the handy pro

amirkasra esmaeilian 13 Jul 05, 2021
Aesthetic NFT Generator

A E S T H E T I C Dependencies Pillow numpy OpenCV You can use pip to install any missing dependencies. Basic Usage Vaporwave artwork can be generated

Mentor Elezi 4 Mar 13, 2022
To check my COVID-19 vaccine appointment, I wrote an infinite loop that sends me a Whatsapp message hourly using Twilio and Selenium. It works on my Raspberry Pi computer.

COVID-19_vaccine_appointment To check my COVID-19 vaccine appointment, I wrote an infinite loop that sends me a Whatsapp message hourly using Twilio a

Ayyuce Demirbas 24 Dec 17, 2022
Developed a website to analyze and generate report of students based on the curriculum that represents student’s academic performance.

Developed a website to analyze and generate report of students based on the curriculum that represents student’s academic performance. We have developed the system such that, it will automatically pa

VIJETA CHAVHAN 3 Nov 08, 2022
An ultra fast cross-platform multiple screenshots module in pure Python using ctypes.

Python MSS from mss import mss # The simplest use, save a screen shot of the 1st monitor with mss() as sct: sct.shot() An ultra fast cross-platfo

Mickaël Schoentgen 799 Dec 30, 2022