Cameron Coward
Published © CC BY-NC-SA

Bear Claw: a Davinci Resolve Macro Pad

This is a device to speed up the editing process in Davinci Resolve. Kind of like a macro pad, but better!

BeginnerShowcase (no instructions)2 hours81
Bear Claw: a Davinci Resolve Macro Pad

Things used in this project

Hardware components

Adafruit KB2040
×1
Adafruit ANO
×1
Adafruit ANO Stemma QT Adapter
×1
Adafruit Metal Ball Tactile Buttons
×1
3-Way Toggle Switch
×1

Story

Read more

Custom parts and enclosures

Bear Claw Top

I recommend printing this in resin for the best quality, but you can do it with an FDM printer, too.

Sketchfab still processing.

Bear Claw Base

This has to be printed on an FDM printer, because you need to stick heat-set inserts in it. You should use transparent/translucent filament so the LED status light can shine through.

Sketchfab still processing.

Schematics

PCB Files

This is the complete package of PCBs, which you should be able to upload directly to a PCB manufacturer, such as PCBWay.

Code

code.py

Python
This is the main Circuit Python code for programming the KB2040 board. Make sure you have the Adafruit libraries installed!
import time
import board
import neopixel
import usb_hid
from adafruit_seesaw import seesaw, rotaryio, digitalio
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
from adafruit_hid.keycode import Keycode
from digitalio import DigitalInOut, Direction, Pull

pixel_pin = board.A1
num_pixels = 4
pixel_brightness = 0.1
brightness_adjustment = 0.01
pixels = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=pixel_brightness, auto_write=False)
RED = (255, 20, 20)
GREEN = (0, 255, 30)
BLUE = (0, 40, 255)

# The pins connected to each switch/button
buttonpins = [board.D4, board.D5, board.D6]

toggle_one = DigitalInOut(board.D2)
toggle_one.direction = Direction.INPUT
toggle_one.pull = Pull.UP

toggle_two = DigitalInOut(board.D3)
toggle_two.direction = Direction.INPUT
toggle_two.pull = Pull.UP

last_toggle = 0

if toggle_one.value is False:
    last_toggle = 1
    pixels.fill(GREEN)
elif toggle_two.value is False:
    last_toggle = 2
    pixels.fill(RED)
else:
    last_toggle = 0
    pixels.fill(BLUE)
pixels.show()

# our array of buttons
buttons = []

# The keycode sent for each switch/button
# Order should be: Center, Up, Left, Down, Right, Index, Middle, Ring
buttonkeys_first = [Keycode.SPACE, Keycode.CONTROL, Keycode.CONTROL, Keycode.N, Keycode.ALT, Keycode.BACKSPACE, Keycode.SHIFT, Keycode.CONTROL]
buttonkeys_second = [0, Keycode.SHIFT, Keycode.ALT, 0, Keycode.Y, 0, Keycode.BACKSPACE, Keycode.Z]
buttonkeys_third = [0, Keycode.L, Keycode.Y, 0, 0, 0, 0, 0]
buttonspressed = [False, False, False, False, False, False, False, False]
buttonspressedlast = [False, False, False, False, False, False, False, False] # Don't forget to update these! Should be same number as buttons

i2c = board.STEMMA_I2C()  # For using the built-in STEMMA QT connector on a microcontroller
seesaw = seesaw.Seesaw(i2c, addr=0x49)

seesaw.pin_mode(1, seesaw.INPUT_PULLUP)
seesaw.pin_mode(2, seesaw.INPUT_PULLUP)
seesaw.pin_mode(3, seesaw.INPUT_PULLUP)
seesaw.pin_mode(4, seesaw.INPUT_PULLUP)
seesaw.pin_mode(5, seesaw.INPUT_PULLUP)

buttons.append(digitalio.DigitalIO(seesaw, 1)) # select
buttons.append(digitalio.DigitalIO(seesaw, 2)) # up
buttons.append(digitalio.DigitalIO(seesaw, 3)) # left
buttons.append(digitalio.DigitalIO(seesaw, 4)) # down
buttons.append(digitalio.DigitalIO(seesaw, 5)) # right

encoder = rotaryio.IncrementalEncoder(seesaw)
last_position = 0

# the keyboard object!
kbd = Keyboard(usb_hid.devices)
# we're americans :)
layout = KeyboardLayoutUS(kbd)

# make all button pin objects, make them inputs w/pullups
for pin in buttonpins:
    button = DigitalInOut(pin)
    button.direction = Direction.INPUT
    button.pull = Pull.UP
    buttons.append(button)

def pressbutton(index):
    k1 = buttonkeys_first[index]  # get the corresp. keycode/str
    k2 = buttonkeys_second[index]
    k3 = buttonkeys_third[index]
    kbd.press(k1, k2, k3)  # send keycode


def releasebutton(index):
    k1 = buttonkeys_first[index]  # get the corresp. keycode/str
    k2 = buttonkeys_second[index]
    k3 = buttonkeys_third[index]
    kbd.release(k1, k2, k3)  # send keycode

while True:
    # check each button
    for button in buttons:
        i = buttons.index(button)
        if button.value is False:  # button is pressed?
            buttonspressed[i] = True  # save pressed button
            # was button not pressed last time?
            if buttonspressedlast[i] is False:
                pressbutton(i)
        else:
            buttonspressed[i] = False  # button was not pressed
            if buttonspressedlast[i] is True:  # was button pressed last time?
                releasebutton(i)
    # save pressed buttons as pressed last
    buttonspressedlast = list(buttonspressed)

    position = encoder.position
    if position != last_position:
        if position < last_position:
            kbd.press(Keycode.CONTROL, Keycode.MINUS)
            kbd.release(Keycode.CONTROL, Keycode.MINUS)
        elif position > last_position:
            kbd.press(Keycode.CONTROL, Keycode.EQUALS)
            kbd.release(Keycode.CONTROL, Keycode.EQUALS)
        last_position = position

    if toggle_one.value is False:
        if last_toggle != 1:
            kbd.press(Keycode.A)
            kbd.release(Keycode.A)
            last_toggle = 1
            pixels.fill(GREEN)
    elif toggle_two.value is False:
        if last_toggle != 2:
            kbd.press(Keycode.B)
            kbd.release(Keycode.B)
            last_toggle = 2
            pixels.fill(RED)
    else:
        if last_toggle != 0:
            kbd.press(Keycode.T)
            kbd.release(Keycode.T)
            last_toggle = 0
            pixels.fill(BLUE)

    if pixel_brightness < 0.1:
        brightness_adjustment = 0.005
    elif pixel_brightness > 0.2:
        brightness_adjustment = -0.01

    pixel_brightness = pixel_brightness + brightness_adjustment
    pixels.brightness = pixel_brightness
    pixels.show()

    time.sleep(0.01)
 # type: ignore

Credits

Cameron Coward

Cameron Coward

18 projects • 1401 followers
Writer for Hackster News. Proud husband and dog dad. Maker and serial hobbyist. Check out my YouTube channel: Serial Hobbyism

Comments