Maker.io main logo

Setting up the Keybow Operating System (OS)

2023-10-06 | By Pimoroni

License: See Original Project

Courtesy of Pimoroni

Guide by Pimoroni

In this tutorial, we'll look a little at how the Keybow OS works (you don't really ‎need to worry about this bit too much, but you might find it interesting and ‎useful), then we'll get onto how to set up a micro-SD card with the software. ‎Last, we'll look at simple examples of how to customise the keys and lights ‎on your Keybow or Keybow MINI.‎

How it all works

The Keybow OS is a custom OS that runs on the Raspberry Pi Zero WH that's ‎included in your Keybow or Keybow MINI kit. It consists of a few different ‎unique parts:

  1. A stripped-down OS based on Raspbian
  2. A ramdisk, into which the entire OS is loaded at boot
  3. Lua files for setting the key mappings, layouts, and lighting
  4. Some C code behind the scenes that sets up and controls the USB HID ‎that Keybow uses to act as a keyboard

The ramdisk means that once the OS is loaded into it during boot, the SD ‎card is no longer accessed or required. This avoids any problems with SD ‎card corruption that can occur when you unplug your Raspberry Pi without ‎safely shutting down first.

‎Lua is a basic but powerful programming language that works really well on ‎embedded and low-power devices. It has a clean, simple syntax and is ideal ‎for the interface to Keybows layouts and lighting.‎

Each of the keys on Keybow and Keybow MINI is linked to a single GPIO pin ‎on the Pi Zero W, and the APA102 LEDs to another two pins (the SPI pins). ‎When a key is pressed, the change on that GPIO pin is detected, translated to ‎a HID keycode by the Lua and C code, then sent out through the USB on-the-‎go port on the Pi Zero W and to the connected computer.‎

The LEDs under each key are addressable and in a single chain, so they can ‎be individually controlled. We've got two different ways of setting the LEDs: ‎individually in the keys.lua file, or by creating a 24-bit PNG file that will be ‎animated across the keys (more on that later).‎

leds_1

Setting up your Keybow OS micro-SD card

Because the Keybow OS is so stripped-down and small, you can get away ‎with using a fairly low-capacity micro-SD card; anything bigger than 1GB will ‎be plenty.‎

Pop your micro-SD card into your computer, and format it in FAT32 format. ‎We recommend using the SD Association's SD Memory Card Formatter app, ‎which is cross-platform and generally very reliable. You can choose "quick ‎format", and call the card whatever you like, e.g., "keybow."‎

Download the zip file with the Keybow OS on by clicking here. Unzip it, then ‎drag all of the files inside the "sdcard" folder (i.e., not the folder itself) across ‎to the micro-SD card.

‎Booting your Keybow or Keybow MINI for the first time!‎

Eject the prepared micro-SD card and pop it into the micro-SD card slot on the ‎Pi Zero WH. Plug the micro-B end of the USB cable into the on-the-go port on ‎the Pi Zero WH; it's the one that lines up with the cut-out in the Keybow ‎baseplate or, if you're using Keybow MINI, it's the one closest to the centre of ‎the Pi Zero W.‎

Assuming you've prepared your SD card properly, after about 10-15 seconds, ‎you should see the lights on your Keybow or Keybow MINI animating through ‎some blue, pink, and orange hues. You might see a few LEDs light randomly ‎when you first plug the power in; this is normal and will disappear once it's ‎fully booted.

‎If you don't see the keys lighting up and animating, then something has gone ‎wrong! Try the following troubleshooting tips:

  • Did you definitely format your micro-SD card with a single FAT32 ‎partition?
  • Make sure that the files on the SD card aren't inside a folder
  • Make sure that you copied all of the files across from the unzipped ‎folder
  • Is the micro-SD card plugged in fully, and is the micro-USB cable ‎plugged in fully?
  • Is the Keybow PCB pushed onto the Pi's pins as far as it will go?‎
  • Is the green activity LED blinking on your Pi Zero WH? If not, then it ‎should be!
  • Try a different micro-SD card, if you have one
  • Remove the baseplate (you won't need to do this on Keybow MINI), ‎and plug a mini-HDMI cable in. When you plug the power into the Pi ‎Zero WH, you should see a bunch of text appearing on the screen.

‎If, after all of those steps, your Keybow or Keybow MINI is still not working, ‎then pop a post on our forums at https://forums.pimoroni.com and we'll do ‎our best to get it working!‎

How the key mappings work

Note that if you're using Keybow MINI then you'll need to add the following ‎bit of code just after the require "keybow" in your layout ‎file, and substitute handle_key_00 for handle_minikey_00 in each of your key ‎mapping functions.

Copy Code
function setup()‎‎ 
keybow.use_mini()
end

By default, Keybow is set up as a number pad with the numbers 0-9, full stop, ‎and enter, but you can easily customise the twelve keys on Keybow to be ‎whatever key you like. To do this, you'll need to unplug the USB cable from ‎your Keybow and pop the micro-SD card out and into your computer.

‎For most users, the only files you'll need to worry about are the keys.lua file ‎and the layout files in the layouts folder. The layouts folder contains some ‎example layouts, with the default.lua layout being the default numberpad.‎

You'll see that there's a line that says require "layouts/default" towards the top of ‎the keys.lua file. This is linking and enabling the default mapping ‎in layouts/default.lua. Let's look at that default.lua file:‎

Copy Code
require "keybow"

‎-- Standard number pad mapping --‎

‎-- Key mappings --‎

function handle_key_00(pressed)‎‎ keybow.set_key("0", pressed)‎
end

function handle_key_01(pressed)‎‎ keybow.set_key(".", pressed)
end

function handle_key_02(pressed)‎‎ keybow.set_key(keybow.ENTER, pressed)‎
end

function handle_key_03(pressed)‎‎ keybow.set_key("1", pressed)‎
end

function handle_key_04(pressed)‎‎ keybow.set_key("2", pressed)‎
end

function handle_key_05(pressed)‎‎ keybow.set_key("3", pressed)‎
end

function handle_key_06(pressed)‎‎ keybow.set_key("4", pressed)
end

function handle_key_07(pressed)‎‎ keybow.set_key("5", pressed)‎
end

function handle_key_08(pressed)‎‎ keybow.set_key("6", pressed)
end

function handle_key_09(pressed)‎‎ keybow.set_key("7", pressed)
end

function handle_key_10(pressed)‎‎ keybow.set_key("8", pressed)‎
end
function handle_key_11(pressed)‎‎ keybow.set_key("9", pressed)‎

end 

You'll see that there are twelve functions, one for each key on Keybow. ‎They're numbered 00, 01, and so on, up to 11. The numberings go from bottom ‎left to top right and start at the bottom left key when Keybow is in portrait ‎orientation with the USB cable at the right hand side.‎

Each function has a single line inside saying e.g., keybow.set_key("0", pressed), ‎which means "set this key to send 0 when pressed". You can change this to ‎any number, letter, punctuation mark, or other character on a standard ‎keyboard (we'll get to special keys like space, control, tab, enter, and so on, in ‎a moment).‎

Changing the pressed at the end of those lines to not pressed, as ‎follows: keybow.set_key("0", not pressed), will cause the 0 to be sent when the key is ‎released rather than pressed. You can have a pressed and not pressed sent by a ‎single key, just by putting two lines within the function, like this, which will ‎send 0 when the key is pressed and 1 when it is released again:

Copy Code
function handle_key_00(pressed)
keybow.set_key("0", pressed)
keybow.set_key("1", not pressed)
end

Take a look at the handle_key_02 function now. You'll see that, rather than ‎having a character like "0" in quote marks, it has keybow.ENTER. There are a ‎number of special keys defined as variables in the keybow.lua file, that you can ‎map to keys on Keybow:‎

Copy Code
keybow.LEFT_CTRL
keybow.LEFT_SHIFT
keybow.LEFT_ALT
keybow.LEFT_META

keybow.RIGHT_CTRL
keybow.RIGHT_SHIFT
keybow.RIGHT_ALT
keybow.RIGHT_META

keybow.ENTER
keybow.ESC
keybow.BACKSPACE
keybow.TAB
keybow.SPACE
keybow.CAPSLOCK

keybow.LEFT_ARROW
keybow.RIGHT_ARROW
keybow.UP_ARROW
keybow.DOWN_ARROW

keybow.F1
keybow.F2
keybow.F3
keybow.F4
keybow.F5
keybow.F6
keybow.F7
keybow.F8
keybow.F9
keybow.F10
keybow.F11
keybow.F12

‎Note that you don't need quote marks around these, as they're variables.‎

Creating a custom key layout

Our recommended way of creating your own custom layout is to create a ‎new lua file inside the layouts folder, for instance mylayout.lua, and then link that ‎layout in the keys.lua, so your keys.lua file would look like this:‎

Copy Code
require "keybow"

-- require "layouts/default" -- Numberpad

-- Custom layouts (uncomment to enable) --

-- require "layouts/boilerplate" -- Handy bits of boilerplate text like Lorem Ipsum
-- require "layouts/lightroom" -- Handy hotkeys for Adobe Lightroom Classic CC
-- require "layouts/pico8" -- Controls for Pico-8

require "layouts/mylayout" -- My custom layout

Notice that we've commented out the line that was linking the default layout ‎by adding two hyphens at the beginning of the line, and that we've left off ‎the .lua from the end of the mylayout.lua filename when linking it on ‎the require... line.

‎It's important that you only have one layout file linked (i.e., uncommented) in ‎your keys.lua file at any one time, or things will get crazy!

‎To see some examples of custom layouts, you can look at the other layout ‎files in the layouts folder, like lightroom.lua and pico8.lua. There's also a blank ‎layout, blank.lua, that you can use as a template.‎

Here are some of the ready-made layouts that we've included with Keybow ‎OS:‎

  • Default numberpad - numbers 0-9, full stop, and enter
  • Boilerplate - example of how to enter whole strings of text like Lorem ‎Ipsum placeholder text, or frequently used code like the Python ‎shebang
  • Lightroom - hotkeys for Adobe Lightroom Classic CC
  • Pico-8 - a Pico-8 gamepad with directional, action, and various function ‎keys
  • Mini volume control - a three-key volume control (vol. down, mute, vol. ‎up) for Keybow MINI
  • Mini playback control - a tiny controller for your media e.g., Spotify with ‎prev. track, play/pause, next track for Keybow MINI

Customising the lighting on Keybow

There are two ways to customise the lighting on Keybow or Keybow MINI.‎

USING A PNG IMAGE

The first, and easiest, way to customise the lighting is with a 24-bit PNG file. ‎If you create a PNG file that is 12 pixels wide, then the colours of those 12 ‎pixels will be mapped to each of the 12 LEDs under Keybow's keys. If you ‎make the PNG file taller than 1 pixel, then this will create an animation on ‎each LED, cycling through the colours in each column of the image from top ‎to bottom, then looping back to the top. The animations are displayed at ‎‎60fps.

‎If you're using Keybow MINI, then you can create an image that's three pixels ‎wide, and it'll span all three keys properly.

‎If you create an image that is just 1 pixel wide and several pixels tall, then the ‎animation will be duplicated to all of the LEDs on Keybow.‎

The pattern that is used by default is default.png on the Keybow micro-SD card, ‎so you can change the pattern simply by replacing that file with another ‎called default.png. We've put a bunch of example patterns in the patterns folder.‎

keys_2

Note that if you want your animation to loop smoothly, then you'll have to ‎make the pixels at the very bottom of you PNG match up with those at the ‎very top.‎

MANUALLY SETTING EACH LED

The second method of customising the LEDs on your Keybow is by setting ‎them manually is the setup function of your layout file. Here's an example ‎from our Pico-8 controller layout:

Copy Code
function setup() -- Set custom lights up
keybow.auto_lights(false)
keybow.clear_lights()
keybow.set_pixel(0, 255, 255, 0) -- Green
keybow.set_pixel(1, 255, 255, 0) -- Green
keybow.set_pixel(2, 0, 255, 255) -- Cyan
keybow.set_pixel(3, 255, 0, 255) -- Magenta
keybow.set_pixel(4, 0, 255, 255) -- Cyan
keybow.set_pixel(5, 0, 255, 255) -- Cyan
keybow.set_pixel(6, 255, 0, 255) -- Magenta
keybow.set_pixel(7, 255, 0, 255) -- Magenta
keybow.set_pixel(8, 0, 255, 255) -- Cyan
keybow.set_pixel(9, 255, 0, 255) -- Magenta
keybow.set_pixel(10, 0, 255, 255) -- Cyan
keybow.set_pixel(11, 0, 255, 255) -- Cyan
end

The setup function is run when the keys.lua file is first loaded. ‎The keybow.auto_lights(false) and keybow.clear_lights() lines disable the PNG animation ‎and clear any LEDs that are lit.‎

The other lines set each of the twelve pixels using keybow.set_pixel(pixel, r, g, ‎b) where pixel is the pixel number and r, g, and b are RGB colour values from 0 ‎to 255. The LED are numbered in the same order as the keys, from bottom ‎left to top right, and start at the bottom left key when Keybow is in portrait ‎orientation.‎

Rather than setting these pixels in the setup function, you can set them in ‎the handle_key function for the keys themselves, meaning that you can have ‎them come on, or change colour, when the keys are pressed and/or released. ‎Here's an example where key 0 is red normally, but changes to green when ‎pressed:‎

Copy Code
function setup() -- Set custom lights up
keybow.auto_lights(false)
keybow.clear_lights()
end

function handle_key_00(pressed)
if pressed then
keybow.set_key("0", pressed)
keybow.set_pixel(0, 0, 255, 0)
else
keybow.set_pixel(0, 255, 0, 0)
end
end

Advanced customisation

We'll cover advanced customisation of Keybow or Keybow MINI with snippets ‎and macros in a further tutorial: Using macros and snippets with Keybow.

‎That tutorial covers binding multiple keypresses to a single key to form ‎macros and the use of our ready-made Windows and Mac snippets. This is ‎where Keybow starts to get really powerful!‎

That's all folks!‎

制造商零件编号 PIM450
KEYBOW MINI MACRO PAD KIT - CLIC
Pimoroni Ltd
Add all DigiKey Parts to Cart
Have questions or comments? Continue the conversation on TechForum, DigiKey's online community and technical resource.