Keyboard Shortcut, Qwiic Keypad

Pages
Contributors: santaimpersonator
Favorited Favorite 2

CircuitPython Example

In an effort to utilize the CircuitPython capability of the RedBoard Turbo, I also have included CircuitPython example code. When you plug the RedBoard Turbo into the computer, it should show up as an USB drive. If not, check out the Troubleshooting section below on how to re-install CircuitPython. To upload your code to your board, you must save the python file on the drive that appears when the board is plugged in.

Note: This tutorial assumes you are familiar with Arduino products and CircuitPython. If you need help, please consult the CircuitPython documentation.

Import CircuitPython Libraries

Installing the Libraries

There may be better instructions than these, but this is what I did to get the CircuitPython libraries onto the RedBoard Turbo. You can also download the library directly using the button below.

  1. Go to the Releases tab for the GitHub Repository.
  2. Download the .zip file containing "bundule-3.x-mpy" in the name or click the button below.
  3. Unzip the file.
  4. Copy the lib folder from file onto the board.

Note: The instructions for importing the CircuitPython libraries were confusing for me; I originally ended up downloading the master .zip file, instead of the release .zip file.

Utilizing the Libraries

To utilize the libraries in your code, you need to import them. Below, are the lines used for importing the libraries in the example python code.

language:python
import time
import board
import busio

from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
from adafruit_hid.keycode import Keycode
from adafruit_hid.consumer_control import ConsumerControl
from adafruit_hid.consumer_control_code import ConsumerControlCode

Implementing CircuitPython

Querying the Keypad

Using the description of the FIFO operation from the Qwiic Keypad hookup guide, the Qwiic Keypad utilizes two registers for querying button presses. The first is register 0x03, that is read for the oldest entry in the FIFO (first-in, first-out) stack. The second is the FIFO increment command register, 0x06, used to update register 0x03 with the next button value.

Setup for I2C

To setup your I2C connection, you need to import the following libraries. You also need to define the pins used for the I2C bus, which was built into the board library for the SAMD21 used on the Turbo. Finally, the I2C address for the Qwiic Keypad was store as a variable.

language:python
import time
import board
import busio

i2c = busio.I2C(board.SCL, board.SDA)
i2caddress = 75 #equals 0x4B in HEX
Read Register

The following code is used to read the value of the oldest button press out of the FIFO stack from register 0x03.

language:python
i2c.writeto(i2caddress, bytes([0x03]), start=0, end=8, stop=True)
time.sleep(.2)
i2c.readfrom_into(i2caddress, result2, start=0, end=1)
Write/Set Register

The following code is used to write 0x01 to register 0x06 to increment the FIFO stack, updating the value stores in register 0x03.

language:python
i2c.writeto(i2caddress, bytes([0x06,0x01]), start=0, end=16, stop=True)

Creating Shortcuts

Utilizing HID Library

The CircuitPython HID library works similarly to the Arduino library used in the previous section. To reference keycodes and naming conventions I used a combination of the following documentation:

Button Combinations

To create shortcut using button combinations, find out the button combination for your shortcut. These should be listed in the user manual for your program or operating system; otherwise, the internet is a great resource. Make sure to test that the shortcut works before programming it.

To code your shortcut in CircuitPython, use the kbd.press(Define_Key) function, designating the individual key. To press multiple keys together, call this function again while designating each of the individual keys. Then use kbd.release_all() to release all the keys pressed at once. Please refer to the documentation listed above for the naming convention (or keycode) of each keyboard key.

Example: Ctrl + Alt + F1

Code:

language:python
kbd.press(Keycode.CONTROL)
kbd.press(Keycode.ALT)
kbd.press(Keycode.INSERT)
kbd.release_all()

Functional Buttons

To create a functional shortcut in CircuitPython, use the cc.send(Define_Key) function, designating the functional key to implement. Please refer to the documentation listed above for the naming convention (or keycode) of the available keys.

Example:

Code:

language:python
cc.send(ConsumerControlCode.VOLUME_DECREMENT)

Text String

To type out a string of text in CircuitPython, use the layout.write('Text') function.

Example Text:
<table>
    <tr>
        <td></td>
        <td></td>
        <td></td>
    </tr>
    <tr>
        <td></td>
        <td></td>
        <td></td>
    </tr>
    <tr>
        <td></td>
        <td></td>
        <td></td>
    </tr>
</table>
Code:
layout.write('<table border="1">\n')
layout.write('    <tr style="padding:10px">\n')
layout.write('        <td style="padding:10px" valign="center"></td>\n')
layout.write('        <td style="padding:10px" valign="center"></td>\n')
layout.write('        <td style="padding:10px" valign="center"></td>\n')
layout.write('    </tr>\n')
layout.write('    <tr style="padding:10px">\n')
layout.write('        <td style="padding:10px" valign="top"></td>\n')
layout.write('        <td style="padding:10px"></td>\n')
layout.write('        <td style="padding:10px"></td>\n')
layout.write('    </tr>\n')
layout.write('    <tr style="padding:10px">\n')
layout.write('        <td></td>\n')
layout.write('        <td></td>\n')
layout.write('        <td></td>\n')
layout.write('    </tr>\n')
layout.write('</table>\n')

Example Code

In the example code below I have implemented specific keyboard shortcuts for my personal needs. You will also notice, that in certain instances, I have combined a series of different shortcuts for greater functionality.

Note: Your code must be saved in a file named code.py on the drive that appears when the RedBoard Turbo is plugged into your computer.
language:python
"""   Hot-Shortcut KeyPad
By: Wes Furuya
SparkFun Electronics
Date: March 27th, 2019
License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license).

Feel like supporting our work? Buy a board from SparkFun!
https://www.sparkfun.com/products/14641
https://www.sparkfun.com/products/14812

This sketch allows the RedBoard Turbo to emulate a HID keyboard. The buttons on the Qwiic Keypad are set for specific keyboard entries. For more details, please refer to the project guide:
https://learn.sparkfun.com/tutorials/keyboard-shortcut-qwiic-keypad """

import time

import board
import busio

# https:#github.com/adafruit/Adafruit_CircuitPython_Bundle/releases/tag/20190326
# 1. Download "bundule-3.x":
#    https:#github.com/adafruit/Adafruit_CircuitPython_Bundle/releases/download/20190326/adafruit-circuitpython-bundle-3.x-mpy-20190326.zip
# 2. Unzip
# 3. Copy lib folder on to board

from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
from adafruit_hid.keycode import Keycode
from adafruit_hid.consumer_control import ConsumerControl
from adafruit_hid.consumer_control_code import ConsumerControlCode

cc = ConsumerControl()
kbd = Keyboard()
layout = KeyboardLayoutUS(kbd)

i2c = busio.I2C(board.SCL, board.SDA)
i2caddress = 75 #equals 0x4B in HEX
CALCULATOR = 402 #equals 0x192 in HEX

while not i2c.try_lock():
    pass

while True:
    result2 = bytearray(1)
    i2c.writeto(i2caddress, bytes([0x03]), start=0, end=8, stop=True)
    i2c.readfrom_into(i2caddress, result2, start=0, end=1)

    if result2 != bytes([0x00]):
        if result2 == b'1':
            cc.send(ConsumerControlCode.MUTE)
            print(result2)

        elif result2 == b'2':
            cc.send(ConsumerControlCode.VOLUME_DECREMENT)
            print(result2)

        elif result2 == b'3':
            cc.send(ConsumerControlCode.VOLUME_INCREMENT)
            print(result2)

        elif result2 == b'4':
            cc.send(CALCULATOR) #cc.send(402)
            print(result2)

        elif result2 == b'5':
            kbd.press(Keycode.CONTROL)
            kbd.press(Keycode.ALT)
            kbd.press(Keycode.INSERT)
            kbd.release_all()
            print(result2)

        elif result2 == b'6':
            kbd.send(227) #Windows Button
            time.sleep(.05)
            layout.write('ter')
            time.sleep(.1)
            kbd.send(Keycode.ENTER)
            print(result2)

        elif result2 == b'7':
            # Cuts selected entry
            kbd.press(Keycode.CONTROL)
            kbd.press(Keycode.X)
            kbd.release_all()
            time.sleep(.05)

            layout.write('<!-- product_big(')
            time.sleep(.05)

            #Pastes entry
            kbd.press(Keycode.CONTROL)
            kbd.press(Keycode.V)
            kbd.release_all()
            time.sleep(.05)

            #Types text
            layout.write(') -->\n')
            layout.write('<!-- products_by_id(')
            time.sleep(.05)

            #Pastes entry
            kbd.press(Keycode.CONTROL)
            kbd.press(Keycode.V)
            kbd.release_all()
            time.sleep(.05)

            #Types text
            layout.write('ID1, ID2) -->\n')
            layout.write('<div class="clearfix"></div>')

        elif result2 == b'8':
            #Types text
            layout.write('<table border="1">\n')
            layout.write('    <tr style="padding:10px">\n')
            layout.write('        <td style="padding:10px" valign="center"></td>\n')
            layout.write('        <td style="padding:10px" valign="center"></td>\n')
            layout.write('        <td style="padding:10px" valign="center"></td>\n')
            layout.write('    </tr>\n')
            layout.write('    <tr style="padding:10px">\n')
            layout.write('        <td style="padding:10px" valign="top"></td>\n')
            layout.write('        <td style="padding:10px"></td>\n')
            layout.write('        <td style="padding:10px"></td>\n')
            layout.write('    </tr>\n')
            layout.write('    <tr style="padding:10px">\n')
            layout.write('        <td></td>\n')
            layout.write('        <td></td>\n')
            layout.write('        <td></td>\n')
            layout.write('    </tr>\n')
            layout.write('</table>\n')

        elif result2 == b'9':
            #Cuts selected entry
            kbd.press(Keycode.CONTROL)
            kbd.press(Keycode.X)
            kbd.release_all()
            time.sleep(.05)

            #Types text
            layout.write('<div class="alert alert-info"><b>Note:</b>')
            time.sleep(.05)

            #Pastes entry
            kbd.press(Keycode.CONTROL)
            kbd.press(Keycode.V)
            kbd.release_all()
            time.sleep(.05)

            #Types text
            layout.write('</div>')

        elif result2 == b'*':
            #Cuts selected entry
            kbd.press(Keycode.CONTROL)
            kbd.press(Keycode.X)
            kbd.release_all()
            time.sleep(.05)

            #Types text
            layout.write('-> [![alt text](')
            time.sleep(.05)

            #Pastes entry
            kbd.press(Keycode.CONTROL)
            kbd.press(Keycode.V)
            kbd.release_all()
            time.sleep(.05)

            #Types text
            layout.write(')](')
            time.sleep(.05)

            #Pastes entry
            kbd.press(Keycode.CONTROL)
            kbd.press(Keycode.V)
            kbd.release_all()
            time.sleep(.05)

            #Types text
            layout.write(') <-')
            layout.write('<div class="center-block text-center"> *Caption* </div>')

        elif result2 == b'0':
            #Cuts selected entry
            kbd.press(Keycode.CONTROL)
            kbd.press(Keycode.X)
            kbd.release_all()
            time.sleep(.05)

            #Types text
            layout.write('<center><a href="')
            time.sleep(.05)

            #Pastes entry
            kbd.press(Keycode.CONTROL)
            kbd.press(Keycode.V)
            kbd.release_all()
            time.sleep(.05)

            #Types text
            layout.write('"><img src="')
            time.sleep(.05)

            #Pastes entry
            kbd.press(Keycode.CONTROL)
            kbd.press(Keycode.V)
            kbd.release_all()
            time.sleep(.05)

            #Types text
            layout.write('" alt=""></a></center>')
            layout.write('<center><i>Caption</i></center>')

        elif result2 == b'#':
            #Cuts selected entry
            kbd.press(Keycode.CONTROL)
            kbd.press(Keycode.X)
            kbd.release_all()
            time.sleep(.05)

            #Types text
            layout.write('<kbd>')
            time.sleep(.05)

            #Pastes entry
            kbd.press(Keycode.CONTROL)
            kbd.press(Keycode.V)
            kbd.release_all()
            time.sleep(.05)

            #Types text
            layout.write('</kbd>')

        else:
            print(result2)

    time.sleep(.05)
    i2c.writeto(i2caddress, bytes([0x06,0x01]), start=0, end=16, stop=True)