{"id":9612,"date":"2021-03-18T12:24:24","date_gmt":"2021-03-18T12:24:24","guid":{"rendered":"https:\/\/www.adambowie.com\/?p=9612"},"modified":"2021-03-24T15:37:15","modified_gmt":"2021-03-24T15:37:15","slug":"pimoroni-keybow-zoom-controller","status":"publish","type":"post","link":"https:\/\/www.adambowie.com\/blog\/2021\/03\/pimoroni-keybow-zoom-controller\/","title":{"rendered":"Pimoroni Keybow Zoom Controller"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Pimoroni makes a wonderful little package called the Keybow which comes in <a rel=\"noreferrer noopener\" href=\"https:\/\/shop.pimoroni.com\/products\/keybow-mini-3-key-macro-pad-kit?variant=27890390696019\" target=\"_blank\">3 key<\/a> and <a rel=\"noreferrer noopener\" href=\"https:\/\/shop.pimoroni.com\/products\/keybow?variant=21246333419603\" target=\"_blank\">12 key<\/a> options. It uses a Raspberry Pi Zero on top of which sit some LED keys (there are both clicky or quiet). You can then program the whole thing to allow you to use keyboard shortcuts to do various regular tasks.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I wanted to make a<em> Zoom<\/em> controller for the video conferencing software so many of us have been using so much in the last year. In essence, I wanted to have one-button access to muting or unmuting myself, turning on and off my camera, and quitting <em>Zoom <\/em>altogether.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Sure, there are already <a href=\"https:\/\/support.zoom.us\/hc\/en-us\/articles\/205683899-hot-keys-and-keyboard-for-zoom\">keyboard shortcuts for all things <em>Zoom<\/em><\/a>. But can you remember them all? And some nice illuminated buttons makes things a bit easier. Plus, nobody enjoys the double red button press you need to leave a meeting (although I appreciate it&#8217;s to stop you accidentally leaving when you didn&#8217;t really want to).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I bought the 12 key option with the clicky keys, because they give you a very certain feeling that you&#8217;ve pressed the buttons. And who doesn&#8217;t like clicky keys? (OK &#8211; they&#8217;re not much fun if you sit near someone hammering away on a keyboard near you all day.)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pimoroni supplies everything you need in the kit with the exception of a microSD card which you&#8217;ll need to add.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Assembling the Keybow is straightforward, and Pimoroni has <a href=\"https:\/\/learn.pimoroni.com\/tutorial\/sandyj\/assembling-keybow\">a comprehensive guide<\/a> which includes details on both assembling your device and getting your software up and running. If you&#8217;re used to playing with Raspberry Pis already, the one thing you need to know is that you format the microSD card as <em>Fat32<\/em> rather than in the usual Linux format that the card creator software that the Raspberry Pi Foundation offers, or something like <em>balenaEtcher<\/em> would do normally. I used the links to the software Pimoroni suggests for formatting your microSD card.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There is <em>no soldering required<\/em> for this assembly, which might make life easier for some! <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Once you&#8217;re up and running you find that it takes about 10-15 seconds to boot if you plug your Keybow into your PC (or Mac). Of course, if you leave it plugged in, this will happen pretty much in lock-step with your PC booting up. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Out of the box, the Keybow is set up as a number pad with the numbers zero through to nine, a full stop\/decimal point and &#8220;Enter&#8221; matched to the 12 keys.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The default set-up also has each of the LEDs under the keys cycling through a set of colours. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now I knew the hardware was working, I needed to work out how to re-program  the Keybow to give specific operations for Zoom. I decided that I wanted the following functionality:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Set all the keys I <em>wasn&#8217;t<\/em> using to <strong>white<\/strong>. Keys in use would be <strong>green<\/strong> by default. My big &#8220;Leave&#8221; button would be <strong>red<\/strong>.<\/li><li>Have one key to <strong>Mute\/Unmute<\/strong> myself &#8211; Alt+A on a PC<\/li><li>Have one key to <strong>turn my Video on and off<\/strong> &#8211; Alt+V on a a PC<\/li><li>Have one key to switch to <strong>Speaker View<\/strong> &#8211; Alt+F1 on a PC<\/li><li>Have one key to switch to <strong>Gallery View<\/strong> &#8211; Alt+F2 on a PC<\/li><li>Have one key to <strong>Quit or Leave<\/strong> a meeting &#8211; Alt+Q, followed by Enter on a PC<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">When changing to either Speaker View or Gallery View, I&#8217;d get the buttons to briefly show blue when they were pressed.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Furthermore, for the audio and video &#8220;toggling&#8221;, I wanted the button to change colour completely. In other words, Green for the default unmute\/video on; blue for muted\/video off.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Note: Actually, your default state will very much depend on the one you&#8217;re in when you&#8217;re invited into or create a meeting. Some invites will set you to mute by default. In which case, the button colours will be reversed. But a &#8220;dumb&#8221; keyboard controller can&#8217;t really take account of that.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pimoroni provide some sample codes, including a set-up that might be useful for <em>Lightroom<\/em>. But I quickly found that while some things were simple, others were more complicated.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The way the code works is that a file placed in the root folder of the microSD card called <strong>keys.lua<\/strong> runs everything. In essence, it tells the Keybow which &#8220;layout&#8221; it should be using. Lua is a macro programming language &#8211; although I knew nothing of it when I got my Keybow.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Following Pimoroni&#8217;s file structure, the layouts were all stored in a folder called <strong>layouts<\/strong>. I created a new one and called it <strong>zoom.lua<\/strong>. I did all my editing in Notepad on a PC, which I know is a terrible coding environment, but then I&#8217;m not really a coder!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Note: I&#8217;m going to reference PC keyboard controls throughout this piece, but it&#8217;s simple to instead change things to a Mac keyboard controller. Pimoroni provides all the details<\/em>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The first thing I did was setup all the lights. Remember, that I wanted useable keys to be Green, by big bailout button to be Red, and the rest White. You can choose any colours in the RGB spectrum, and just need to come up with the numbers to determine the colours. You can use something like <em>Photoshop<\/em> for this, but there are also plenty of free tools. <a href=\"https:\/\/www.google.com\/search?q=color+picker\">Here&#8217;s Google&#8217;s own one<\/a>. It&#8217;s the three RGB colour numbers, each between 0 and 255 that you need.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The 12 key version of Keybow numbers its keys from bottom left to top right, 0 to 11, in a portrait orientation with the &#8220;Keybow&#8221; name at the top. But I wanted to use the controller orientated 90 degrees to a landscape form-factor. So &#8220;bottom left&#8221; for me would be key 9 and &#8220;bottom right&#8221; key 0.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It&#8217;s also worth noting at this point that Lua uses two dashes &#8220;&#8211;&#8221; to mean comments. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Anyway, here&#8217;s the first bit of code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>require \"keybow\"\n\n-- Set lights to white except those keys with Zoom controls\n\nfunction setup()\n    keybow.auto_lights(false)\n    keybow.clear_lights()\n    keybow.set_pixel(0, 255, 15, 15) -- Red    \n    keybow.set_pixel(1, 255, 255, 255) -- White\n    keybow.set_pixel(2, 255, 255, 255) -- White\n\n    keybow.set_pixel(3, 255, 255, 255) -- White\n    keybow.set_pixel(4, 255, 255, 255) -- White\n    keybow.set_pixel(5, 255, 255, 255) -- White\n    keybow.set_pixel(6, 15, 255, 15) -- Green\n    keybow.set_pixel(7, 255, 255, 255) -- White\n    keybow.set_pixel(8, 15, 255, 15) -- Green\n\n    keybow.set_pixel(9, 15, 255, 15) -- Green\n    keybow.set_pixel(10, 255, 255, 255) -- White\n    keybow.set_pixel(11, 15, 255, 15) -- Green\nend<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The first line is required to program the Keybow, and then the <strong>setup()<\/strong> function&#8217;s first two lines turn off any other default lighting set-up. Without them, the Keybow uses a file named <strong>default.png<\/strong> which controls the colour scheme. Indeed, I found that if my code went wrong at any stage, it was then completely ignored and the default rainbow keys would light up because it had reverted back to the <strong>default.png<\/strong> colour scheme. Useful for bug hunting, since broken code meant that it kind of &#8220;gave up&#8221; and just gave me a rainbow!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So my keys were coloured correctly, but they don&#8217;t do anything yet.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The simplest coding was for the Gallery and Speaker views in Zoom. Here&#8217;s the code for them:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>-- Switch to Speaker View (Alt + F1)\n\nfunction handle_key_11(pressed)\n\n    if pressed then\n\n            keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_DOWN)\n            keybow.tap_key(keybow.F1, pressed)\n            keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_UP)\n            keybow.set_pixel(11, 0, 50, 255) -- Set the light to blue\n\n    else\n        keybow.set_pixel(11, 15, 255, 15)\n    end\nend\n\n-- Switch to Gallery View (Alt + F2)\n\nfunction handle_key_08(pressed)\n\n    if pressed then\n\n            keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_DOWN)\n            keybow.tap_key(keybow.F2, pressed)\n            keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_UP)\n            keybow.set_pixel(8, 0, 50, 255) -- Set the light to blue\n\n    else\n        keybow.set_pixel(8, 15, 255, 15)\n    end\nend<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Basically it&#8217;s the same bit of code twice, but referring to keys 11 and 8, the two top left keys on the Keybow in the orientation I was using. The <strong>function handle_key<\/strong><em>nn<\/em><strong>(pressed)<\/strong> command tells the Keybow to run the code within that section if key number <em>nn<\/em> is pressed. Note that you need to include a leading &#8220;0&#8221; for keys 0-9 (ie. they&#8217;re keys 00-09). I learned that the hard way. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then if the key is pressed, the first bit of code runs. It essentially sets the left Alt key (on a PC keyboard) to &#8220;down&#8221; with the <strong>keybow.KEY_DOWN<\/strong> expression, then &#8220;taps&#8221; the second key &#8211; F1 or F2 &#8211; before releasing the Alt key, putting it back in the <strong>keybow.KEY_UP<\/strong> position. Finally, it changes the key&#8217;s colour to blue.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However, as soon as the key is released, the &#8220;else&#8221; bit of the code will turn the key&#8217;s colour back to green.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In practice it means as soon as the key is pushed down, it turns it sends the computer an <em>Alt+F1<\/em> or <em>Alt+F2<\/em> command, and the key will stay blue while it&#8217;s depressed. As soon as it&#8217;s released, no further keyboard command is sent, but the key will revert to its green colour.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">One other thing to note is that if you have something like Nvidia&#8217;s <em>In-Game Overlay<\/em> program running on your PC, which is very possible if you have an Nvidia graphics card, by default that application uses <em>Alt+F1<\/em> and <em>Alt+F2<\/em> for grabbing screenshots. I had to disable that functionality in the Nvidia program as otherwise I couldn&#8217;t get the keyboard shortcuts to work in Zoom at all for these two views. This of course is regardless of the Keybow being there. Similarly, you might want to check that other &#8220;global&#8221; applications aren&#8217;t duplicating Zoom&#8217;s keyboard shortcuts if you run into any strange issues.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The next bit of code is harder. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For the audio and video controls, I wanted the keys to start green, then turn blue on the first press, before turning back to green on the subsequent press. In other words &#8220;toggle&#8221; between green and blue. I&#8217;m sure regular coders quickly know what to do, but I had to go hunting and eventually I found the logic that I needed. So here&#8217;s the code for that bit:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>-- Toggle variables setup for audio and video controls\n\nkey6pressed = false\nkey9pressed = false\n\n-- Mute\/Unmute Audio Toggle\n\nfunction handle_key_09(pressed)\n    if pressed then\n\n        key9pressed = not(key9pressed) -- Reverse boolean value\n\n        if key9pressed then\n\n                keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_DOWN)\n                keybow.tap_key(\"a\", pressed)\n                keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_UP)\n                keybow.set_pixel(9, 0, 50, 255) -- Set the light to blue\n        else\n                keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_DOWN)\n                keybow.tap_key(\"a\", pressed)\n                keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_UP)\n                keybow.set_pixel(9, 15, 255, 15) -- Set the light to green\n        end\n    end\nend\n\n\n-- Video On\/Off Toggle\n\nfunction handle_key_06(pressed)\n\n    if pressed then\n\n        key6pressed = not(key6pressed) -- Reverse boolean value\n\n        if key6pressed then\n\n                keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_DOWN)\n                keybow.tap_key(\"v\", pressed)\n                keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_UP)\n                keybow.set_pixel(6, 0, 50, 255) -- Set the light to blue\n        else\n                keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_DOWN)\n                keybow.tap_key(\"v\", pressed)\n                keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_UP)\n                keybow.set_pixel(6, 15, 255, 15) -- Set the light to green\n        end\n    end\nend<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Again, this code snippet has essentially the same code twice &#8211; once for audio and once for video toggling.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">First of all, I set up two &#8220;Boolean variables&#8221; &#8211; which I called <em>key6pressed<\/em> and <em>key9pressed<\/em>. Their initial state was FALSE. Boolean variables can only be <strong>true<\/strong> or <strong>false<\/strong>. What I needed to do was switch the state of them each time the key was pressed. Then depending on that state, change the button colour.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So if we look at the audio section where we mute or unmute ourselves, that&#8217;s on Key 9. If that key is pressed, the first thing we do is reverse the Boolean value. The code <strong>not(key9pressed)<\/strong> means that the value is now &#8220;true&#8221;. But next time the key is pressed it&#8217;ll revert to &#8220;false&#8221; and so on.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then there&#8217;s an if statement. It&#8217;s checking to see if <em>key9pressed<\/em> is &#8220;true&#8221; &#8211; which it is at the moment. In which case, as before, we have code for <strong>Alt+A<\/strong>, and then the colour of the key is turned <strong>blue<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If the value of <em>key9pressed <\/em>is &#8220;false&#8221;, then the <strong>else <\/strong>code is run &#8211; again mimicking pressing &#8220;Alt+A&#8221;, but this time turning the key colour <strong>green<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There might be neater coding to do this, but this works!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The next section of code toggles video in exactly the same, but with <strong>Alt+V<\/strong> on Key 6.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The final bit of code needed is to exit out of Zoom. It&#8217;s a two-stage process unless you&#8217;re thrown out by the host (Don&#8217;t mess with <a href=\"https:\/\/www.theguardian.com\/commentisfree\/2021\/feb\/07\/dont-mess-with-jackie-weaver-boys-shes-got-a-mute-button-and-knows-how-to-use-it\">Jackie Weaver<\/a>!). But I wanted one key-press to do both things. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Alt+Q<\/strong> is the Zoom quit shortcut. But then you need to confirm it by pressing <strong>Enter<\/strong>. So here&#8217;s the code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>-- Leave meeting\n\nfunction handle_key_00(pressed)\n    if pressed then\n        keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_DOWN)\n        keybow.tap_key(\"q\", pressed)\n        keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_UP)\n        keybow.sleep(500)\n        keybow.tap_enter()\n    end\nend<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For me, this is mapped to Key 0. The code is similar to that for other keys, replicating holding down the Alt key (the left-alt key in particular), and pressing<strong> q<\/strong>. But when that&#8217;s done it pauses for <strong>500 milliseconds<\/strong> (half a second) before the <strong>Enter<\/strong> key is &#8220;tapped.&#8221;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In other words, the code strings together various key presses &#8211; quite powerful in itself if you have sequences of keys that you need to replicate.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.adambowie.com\/wp-content\/uploads\/2021\/03\/Keybow.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"683\" src=\"https:\/\/www.adambowie.com\/wp-content\/uploads\/2021\/03\/Keybow-1024x683.jpg\" alt=\"\" class=\"wp-image-9619\" srcset=\"https:\/\/www.adambowie.com\/wp-content\/uploads\/2021\/03\/Keybow-1024x683.jpg 1024w, https:\/\/www.adambowie.com\/wp-content\/uploads\/2021\/03\/Keybow-300x200.jpg 300w, https:\/\/www.adambowie.com\/wp-content\/uploads\/2021\/03\/Keybow-768x512.jpg 768w, https:\/\/www.adambowie.com\/wp-content\/uploads\/2021\/03\/Keybow-437x291.jpg 437w, https:\/\/www.adambowie.com\/wp-content\/uploads\/2021\/03\/Keybow-150x100.jpg 150w, https:\/\/www.adambowie.com\/wp-content\/uploads\/2021\/03\/Keybow.jpg 1200w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Put everything together, and here&#8217;s my complete code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>require \"keybow\"\n\n-- Toggle variables setup for audio and video controls\n\nkey6pressed = false\nkey9pressed = false\n\n-- Set lights to white except those keys with Zoom controls\n\nfunction setup()\n    keybow.auto_lights(false)\n    keybow.clear_lights()\n    keybow.set_pixel(0, 255, 15, 15) -- Red    \n    keybow.set_pixel(1, 255, 255, 255) -- White\n    keybow.set_pixel(2, 255, 255, 255) -- White\n\n    keybow.set_pixel(3, 255, 255, 255) -- White\n    keybow.set_pixel(4, 255, 255, 255) -- White\n    keybow.set_pixel(5, 255, 255, 255) -- White\n    keybow.set_pixel(6, 15, 255, 15) -- Green\n    keybow.set_pixel(7, 255, 255, 255) -- White\n    keybow.set_pixel(8, 15, 255, 15) -- Green\n\n    keybow.set_pixel(9, 15, 255, 15) -- Green\n    keybow.set_pixel(10, 255, 255, 255) -- White\n    keybow.set_pixel(11, 15, 255, 15) -- Green\nend\n\n-- Zoom controls\n\n-- Mute\/Unmute Audio Toggle\n\nfunction handle_key_09(pressed)\n    if pressed then\n\n        key9pressed = not(key9pressed) -- Reverse boolean value\n\n        if key9pressed then\n\n                keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_DOWN)\n                keybow.tap_key(\"a\", pressed)\n                keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_UP)\n                keybow.set_pixel(9, 0, 50, 255) -- Set the light to blue\n        else\n                keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_DOWN)\n                keybow.tap_key(\"a\", pressed)\n                keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_UP)\n                keybow.set_pixel(9, 15, 255, 15) -- Set the light to green\n        end\n    end\nend\n\n\n-- Video On\/Off Toggle\n\nfunction handle_key_06(pressed)\n\n    if pressed then\n\n        key6pressed = not(key6pressed) -- Reverse boolean value\n\n        if key6pressed then\n\n                keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_DOWN)\n                keybow.tap_key(\"v\", pressed)\n                keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_UP)\n                keybow.set_pixel(6, 0, 50, 255) -- Set the light to blue\n        else\n                keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_DOWN)\n                keybow.tap_key(\"v\", pressed)\n                keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_UP)\n                keybow.set_pixel(6, 15, 255, 15) -- Set the light to green\n        end\n    end\nend\n\n-- Switch to Speaker View (Alt + F1)\n\nfunction handle_key_11(pressed)\n\n    if pressed then\n\n            keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_DOWN)\n            keybow.tap_key(keybow.F1, pressed)\n            keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_UP)\n            keybow.set_pixel(11, 0, 50, 255) -- Set the light to blue\n\n    else\n        keybow.set_pixel(11, 15, 255, 15)\n    end\nend\n\n-- Switch to Gallery View (Alt + F2)\n\nfunction handle_key_08(pressed)\n\n    if pressed then\n\n            keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_DOWN)\n            keybow.tap_key(keybow.F2, pressed)\n            keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_UP)\n            keybow.set_pixel(8, 0, 50, 255) -- Set the light to blue\n\n    else\n        keybow.set_pixel(8, 15, 255, 15)\n    end\nend\n\n-- Leave meeting\n\nfunction handle_key_00(pressed)\n    if pressed then\n        keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_DOWN)\n        keybow.tap_key(\"q\", pressed)\n        keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_UP)\n        keybow.sleep(500)\n        keybow.tap_enter()\n    end\nend<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Save that as <strong>zoom.lua<\/strong> and make sure that <strong>keys.lua<\/strong> in the root directory has something like this in it, with everything else commented out:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>require \"keybow\"\nrequire \"layouts\/zoom\" <\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Note you refer to the file name as <em>zoom<\/em> and not <em>zoom.lua<\/em> in that code.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Save everything to the microSD card, load it onto the Keybow and plug it into your PC!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Obviously there are lots more keyboard shortcuts for Zoom you might want to replicate. And for the Keybow there are more complex coding options that let you map multiple sets of shortcuts to the same device. In essence, you could use a row of keys to change &#8220;pages&#8221; and use the remaining keys to act as shortcuts for each &#8220;page&#8221;. That way, you could use your Keybow to control Zoom, Lightroom, OBS or whatever else you want.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The other thing to note is that more recently Pimoroni released <a rel=\"noreferrer noopener\" href=\"https:\/\/shop.pimoroni.com\/products\/pico-rgb-keypad-base\" target=\"_blank\">a cutdown version of the Keybow which is based around the new Raspberry Pi Pico<\/a>. This is a much simpler offering, and theoretically could be very good. But I wasn&#8217;t able to master controlling it as well as the Keybow. Also, the rubberised keys have something of a ZX Spectrum controller about them. While some <em>have<\/em> worked out how to make it a USB controller, I think a bit more dev work is required before it&#8217;s easy for us users. You will want to know how to solder too, unless you buy a pre-soldered Pico. However, if you&#8217;re willing to play, it&#8217;s a much cheaper option. The Raspberry Pi Pico is less than \u00a34!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Good luck, and hopefully this is all useful for some.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">(And yes, in its default state, my Keybow does have something of an Italian flag about it)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Update: One small thing to note is that I did try to add a micro USB cable with an on\/off switch between my computer&#8217;s USB and the Keybow &#8211; <a href=\"https:\/\/thepihut.com\/products\/micro-usb-cable-with-on-off-switch?variant=37626933772483\">one of these<\/a>. It was mainly because the Keybow&#8217;s lights are reasonably bright, and I have my Keybow plumbed into my computer via a USB host in my monitor. If I leave the computer either on, or in sleep mode, the lights stay on, although they do turn off if you shut down. So I thought it might be nice to have a simple on\/off switch. Sadly, the switch seems to interfere with the computer recognising the Pi as a &#8220;keyboard&#8221; so it didn&#8217;t work, in that the computer no longer recognised the key presses at all. To be fair, this was always a possibility as the retailer does say clearly that the cable does not transfer data. Back to the drawing board on that.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Pimoroni makes a wonderful little package called the Keybow which comes in 3 key and 12 key options. It uses a Raspberry Pi Zero on top of which sit some LED keys (there are both clicky or quiet). You can then program the whole thing to allow you to use keyboard shortcuts to do various [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":9618,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"cybocfi_hide_featured_image":"","footnotes":""},"categories":[9],"tags":[1040,921,1041],"class_list":["post-9612","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-technology","tag-keyboard","tag-raspberry-pi","tag-zoom"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.adambowie.com\/blog\/wp-json\/wp\/v2\/posts\/9612","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.adambowie.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.adambowie.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.adambowie.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.adambowie.com\/blog\/wp-json\/wp\/v2\/comments?post=9612"}],"version-history":[{"count":4,"href":"https:\/\/www.adambowie.com\/blog\/wp-json\/wp\/v2\/posts\/9612\/revisions"}],"predecessor-version":[{"id":9623,"href":"https:\/\/www.adambowie.com\/blog\/wp-json\/wp\/v2\/posts\/9612\/revisions\/9623"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.adambowie.com\/blog\/wp-json\/wp\/v2\/media\/9618"}],"wp:attachment":[{"href":"https:\/\/www.adambowie.com\/blog\/wp-json\/wp\/v2\/media?parent=9612"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.adambowie.com\/blog\/wp-json\/wp\/v2\/categories?post=9612"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.adambowie.com\/blog\/wp-json\/wp\/v2\/tags?post=9612"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}