pimoroni / keybow-firmware

Keybow Firmware for the Raspberry Pi Zero

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Adaptive layouts

hardillb opened this issue · comments

I've been trying to use the serial support added at v0.0.4 to change the key mapping with something like the following:

require "keybow"

-- Keybow MINI volume/zoom controls --

function setup()
    keybow.use_mini()
    keybow.auto_lights(false)
    keybow.clear_lights()
    keybow.set_pixel(0, 0, 255, 255)
    keybow.set_pixel(1, 255, 0, 255)
    keybow.set_pixel(2, 0, 255, 255)
end

-- Key mappings --

state = 'zoom'

function handle_minikey_02(pressed)
    if state == 'zoom' then
	if pressed then
            keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_DOWN)
            keybow.tap_key("v")
            keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_UP)
        end
    elseif state == 'media' then
        keybow.set_media_key(keybow.MEDIA_VOL_UP, pressed)
    end
end

function handle_minikey_01(pressed)
    if state == 'zoom' then
	if pressed then
            keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_DOWN)
            keybow.tap_key("a")
            keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_UP)
        end
    elseif state == 'media' then
        keybow.set_media_key(keybow.MEDIA_MUTE, pressed)
    end
end

function handle_minikey_00(pressed)
    if state == 'zoom' then
	if pressed then
             keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_DOWN)
             keybow.tap_key("n")
             keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_UP)
        end
    elseif state == 'media' then
        keybow.set_media_key(keybow.MEDIA_VOL_DOWN, pressed)
    end
end

local function isempty(s)
  return s == nil or s == ''
end

function tick()
    local line
    line = keybow_serial_read()
    if not isempty(line) then 
        -- keybow_serial_write( line .. "\n" )
        if line == 'zoom' then
            keybow.clear_lights()
            keybow.set_pixel(0, 0, 255, 255)
            keybow.set_pixel(1, 255, 0, 255)
            keybow.set_pixel(2, 0, 255, 255)
            state = 'zoom'
        elseif line == 'media' then
            keybow.clear_lights()
            keybow.set_pixel(0, 255, 0, 255)
            keybow.set_pixel(1, 0, 255, 255)
            keybow.set_pixel(2, 255, 0, 255)
            state = 'media'
        end
    end

end

It's really laggy which I think is down to:

termios.c_cc[VTIME] = 10;

Which sets a 1 second read timeout on the serial connection.

I tried reducing that to 1 decasecond but when I built the keybow binary (on a different pi zero) from the head of the repo it doesn't look to setup the USB gadget properly (at least it never shows up on the host machine).

Any suggestions?

Or suggestions on how to debug, I attached a screen, but it just drops me at a login prompt and there is no way to add a keyboard as the USB port is in device mode to talk to the host. (When Pi Zero W's become available again I will try and grab one so I can ssh in and have a look).

P.s. I understand the world has probably mainly moved on to the 2040 based kit, but this is still useful and being able to switch profiles would be huge upgrade.

OK, the rebuilt keybow with the VTIME set to 1 does work (it was a dodgy USB-C hub that needed resetting). There was still a 10th of a second latency which is not great but just about workable.

I tried it with the VTIME set to 0 and it's lighting fast, I'm shift between layouts with echo zoom > /dev/ttyACM0 and echo media > /dev/ttyACM0 It doesn't appear to work with picocom, but that's fine. I should be able to script this with xprop or xdotool.

If there is ever a new release, making the serial_read act more like a callback than an explicit read (or at least having it configurable) would be great and mean the lua would only see the input when there had been a new line char.

I guess this might need a background thread to handle the serial read.

@hardillb agreed- it would be nice to have it structured as a callback, and that's relatively straight-forward to do. A non-blocking, buffer-filling, short read on the main loop that triggers the callback on \n or something might work well.

@hardillb while you're here, and since you can build/run keybow from source... would you mind trying out the refactored code here?: #79

This is what any changes to the serial handling would be based upon, so getting it merged would be a great start.

Cheers!

Might have to wait for the weekend, but will do.

Thanks- it's been sitting in PR purgatory for months, so there's no hurry.