0

macropad heatmap
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

macropad heatmap

by dearmash on Tue Jul 27, 2021 3:29 am

I'm a huge fan of the QMK keyboard heatmap animation, so here is my take on the same effect for the macropad.

On each keypress, the pressed key will light up the brightest, the orthogonally adjacent keys (up down left right) will light up less so, and the diagonally adjacent keys will light up a even less. This makes use of the fancy led palettes to light up from "cool" to "warm" as more presses are registered for that key. Over time, the keys "cool down" and eventually turn back off again. The OLED display updates with the value of each key less frequently than the neopixels simply for performance reasons.

Haven't decided what to do with the encoder for this just yet, maybe wipe the whole board up or down, not sure.

By far one of my top boxes, thank you!

Code: Select all | TOGGLE FULL SIZE
import displayio
import terminalio
import time
from adafruit_display_shapes.rect import Rect
from adafruit_display_text import label
from adafruit_macropad import MacroPad
import adafruit_fancyled.adafruit_fancyled as fancy

MACROPAD = MacroPad()
MACROPAD.display.auto_refresh = False
MACROPAD.pixels.auto_write = False

# Set up displayio group with all the labels
GROUP = displayio.Group(max_size=14) # 12 keys + rect + app name
for KEY_INDEX in range(12):
    x = KEY_INDEX % 3
    y = KEY_INDEX // 3
    GROUP.append(label.Label(terminalio.FONT, text='', color=0xFFFFFF,
                             anchored_position=((MACROPAD.display.width - 1) * x / 2,
                                                MACROPAD.display.height - 1 -
                                                (3 - y) * 12),
                             anchor_point=(x / 2, 1.0)))
GROUP.append(Rect(0, 0, MACROPAD.display.width, 12, fill=0xFFFFFF))
GROUP.append(label.Label(terminalio.FONT, text='', color=0x000000,
                         anchored_position=(MACROPAD.display.width//2, -2),
                         anchor_point=(0.5, 0.0)))
MACROPAD.display.show(GROUP)

GROUP[13].text = "Heatmap"

COUNTS = [0]*12

last_display = 0
last_cooldown = 0

CENTER_BUMP = 20
ORTHO_BUMP = 14
DIAG_BUMP = 7

GRAD = [(0.0, 0x000000),
        (0.1, 0x000066),
        (0.2, 0x009900),
        (0.3, 0xAAAA00),
        (0.5, 0xFF9900),
        (1.0, 0xFF0000)]
PALETTE = fancy.expand_gradient(GRAD, 50)

while True:
    if time.monotonic() - last_cooldown > 0.01:
        last_cooldown = time.monotonic()
        for i in range(12):
            COUNTS[i] = max(COUNTS[i] - 1, 0)
            color = fancy.palette_lookup(PALETTE, COUNTS[i]/256.0)
            MACROPAD.pixels[i] = color.pack()
        MACROPAD.pixels.show()

    if time.monotonic() - last_display > 1:
        last_display = time.monotonic()
        for i in range(12):
            GROUP[i].text = str(COUNTS[i])
        MACROPAD.display.refresh()

    EVENT = MACROPAD.keys.events.get()
    if not EVENT:
        continue
   
    if EVENT.pressed:
        COUNTS[EVENT.key_number] = min(COUNTS[EVENT.key_number] + CENTER_BUMP, 255)
        if EVENT.key_number%3:
            if EVENT.key_number>=3:
                COUNTS[EVENT.key_number-4] = min(COUNTS[EVENT.key_number-4] + DIAG_BUMP, 255)
            if EVENT.key_number<9:
                COUNTS[EVENT.key_number+2] = min(COUNTS[EVENT.key_number+2] + DIAG_BUMP, 255)
            COUNTS[EVENT.key_number-1] = min(COUNTS[EVENT.key_number-1] + ORTHO_BUMP, 255)
        if (EVENT.key_number+1)%3:
            if EVENT.key_number>=3:
                COUNTS[EVENT.key_number-2] = min(COUNTS[EVENT.key_number-2] + DIAG_BUMP, 255)
            if EVENT.key_number<9:
                COUNTS[EVENT.key_number+4] = min(COUNTS[EVENT.key_number+4] + DIAG_BUMP, 255)
            COUNTS[EVENT.key_number+1] = min(COUNTS[EVENT.key_number+1] + ORTHO_BUMP, 255)
        if EVENT.key_number>=3:
            COUNTS[EVENT.key_number-3] = min(COUNTS[EVENT.key_number-3] + ORTHO_BUMP, 255)
        if EVENT.key_number<9:
            COUNTS[EVENT.key_number+3] = min(COUNTS[EVENT.key_number+3] + ORTHO_BUMP, 255)

dearmash
 
Posts: 48
Joined: Mon Nov 28, 2011 4:20 pm

Re: macropad heatmap

by dearmash on Tue Jul 27, 2021 3:50 am

Encoder now increases / decreases all the keys, and on press zeros them out.

Code: Select all | TOGGLE FULL SIZE
import displayio
import terminalio
import time
from adafruit_display_shapes.rect import Rect
from adafruit_display_text import label
from adafruit_macropad import MacroPad
import adafruit_fancyled.adafruit_fancyled as fancy

MACROPAD = MacroPad()
MACROPAD.display.auto_refresh = False
MACROPAD.pixels.auto_write = False

# Set up displayio group with all the labels
GROUP = displayio.Group(max_size=14) # 12 keys + rect + app name
for KEY_INDEX in range(12):
    x = KEY_INDEX % 3
    y = KEY_INDEX // 3
    GROUP.append(label.Label(terminalio.FONT, text='', color=0xFFFFFF,
                             anchored_position=((MACROPAD.display.width - 1) * x / 2,
                                                MACROPAD.display.height - 1 -
                                                (3 - y) * 12),
                             anchor_point=(x / 2, 1.0)))
GROUP.append(Rect(0, 0, MACROPAD.display.width, 12, fill=0xFFFFFF))
GROUP.append(label.Label(terminalio.FONT, text='', color=0x000000,
                         anchored_position=(MACROPAD.display.width//2, -2),
                         anchor_point=(0.5, 0.0)))
MACROPAD.display.show(GROUP)

GROUP[13].text = "Heatmap"

COUNTS = [0]*12

last_display = 0
last_cooldown = 0
last_position = MACROPAD.encoder

CENTER_BUMP = 20
ORTHO_BUMP = 14
DIAG_BUMP = 7

GRAD = [(0.0, 0x000000),
        (0.1, 0x000066),
        (0.2, 0x009900),
        (0.3, 0xAAAA00),
        (0.5, 0xFF9900),
        (1.0, 0xFF0000)]
PALETTE = fancy.expand_gradient(GRAD, 50)

while True:
    if time.monotonic() - last_cooldown > 0.01:
        last_cooldown = time.monotonic()
        for i in range(12):
            COUNTS[i] = max(COUNTS[i] - 1, 0)
            color = fancy.palette_lookup(PALETTE, COUNTS[i]/256.0)
            MACROPAD.pixels[i] = color.pack()
        MACROPAD.pixels.show()

    if time.monotonic() - last_display > 0.5:
        last_display = time.monotonic()
        for i in range(12):
            GROUP[i].text = str(COUNTS[i])
        MACROPAD.display.refresh()

    position = MACROPAD.encoder
    if last_position != position:
        delta = 10
        if position < last_position:
            delta = -10
        for i in range(12):
            COUNTS[i] = min(max(COUNTS[i] + delta, 0), 255)
        last_position = position
   
    MACROPAD.encoder_switch_debounced.update()
    if MACROPAD.encoder_switch_debounced.pressed:
        for i in range(12):
            COUNTS[i] = 0
   
    EVENT = MACROPAD.keys.events.get()
   
    if EVENT and EVENT.pressed:
        COUNTS[EVENT.key_number] = min(COUNTS[EVENT.key_number] + CENTER_BUMP, 255)
        if EVENT.key_number%3:
            if EVENT.key_number>=3:
                COUNTS[EVENT.key_number-4] = min(COUNTS[EVENT.key_number-4] + DIAG_BUMP, 255)
            if EVENT.key_number<9:
                COUNTS[EVENT.key_number+2] = min(COUNTS[EVENT.key_number+2] + DIAG_BUMP, 255)
            COUNTS[EVENT.key_number-1] = min(COUNTS[EVENT.key_number-1] + ORTHO_BUMP, 255)
        if (EVENT.key_number+1)%3:
            if EVENT.key_number>=3:
                COUNTS[EVENT.key_number-2] = min(COUNTS[EVENT.key_number-2] + DIAG_BUMP, 255)
            if EVENT.key_number<9:
                COUNTS[EVENT.key_number+4] = min(COUNTS[EVENT.key_number+4] + DIAG_BUMP, 255)
            COUNTS[EVENT.key_number+1] = min(COUNTS[EVENT.key_number+1] + ORTHO_BUMP, 255)
        if EVENT.key_number>=3:
            COUNTS[EVENT.key_number-3] = min(COUNTS[EVENT.key_number-3] + ORTHO_BUMP, 255)
        if EVENT.key_number<9:
            COUNTS[EVENT.key_number+3] = min(COUNTS[EVENT.key_number+3] + ORTHO_BUMP, 255)

dearmash
 
Posts: 48
Joined: Mon Nov 28, 2011 4:20 pm

Re: macropad heatmap

by johnpark on Wed Aug 04, 2021 11:55 am

Very cool! Can't wait to try this out, I love that effect.

johnpark
 
Posts: 888
Joined: Wed Mar 25, 2009 2:15 pm

Please be positive and constructive with your questions and comments.