macropad heatmap

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
dearmash
 
Posts: 66
Joined: Mon Nov 28, 2011 4:20 pm

macropad heatmap

Post by dearmash »

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

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)

User avatar
dearmash
 
Posts: 66
Joined: Mon Nov 28, 2011 4:20 pm

Re: macropad heatmap

Post by dearmash »

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

Code: Select all

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)

User avatar
johnpark
 
Posts: 985
Joined: Wed Mar 25, 2009 2:15 pm

Re: macropad heatmap

Post by johnpark »

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

Locked
Please be positive and constructive with your questions and comments.

Return to “AdaBox! Show us what you made!”