zmkfirmware / zmk

ZMK Firmware Repository
https://zmk.dev/
MIT License
2.69k stars 2.76k forks source link

Feature: Encoder layers #333

Open benjizhai opened 3 years ago

benjizhai commented 3 years ago

Problem

The encoder (AB and pushbutton) functions are defined per layer. Adding multiple functions to encoders are cumbersome and would involve many duplications of each layer.

Proposal

Example

An example keymap with 2 normal keys and 2 encoders.

/ {
    keymap {
        compatible = "zmk,keymap";

        default_layer {
            bindings = < &tog 1    &kp Z    &kp M    &kp K>;   //normal keys + pushbutton override
            sensor-bindings = <&inc_dec_cp C_VOLUME_UP C_VOLUME_DOWN   &inc_dec_cp C_BRI_INC C_BRI_DEC  >;   // encoder override
                };

        lower_layer {
            bindings = < &tog 1    &einc    &trans    &trans>;   //normal keys + pushbutton override
            sensor-bindings = <&trans &trans &trans &trans>;   // encoder override
                };
    };

    encodermap {
        compatible = "zmk,encodermap";

        default_layer {
            bindings = <&C_MUTE    &C_BKLT_TOG>;   // pushbuttons
            sensor-bindings = <&inc_dec_cp C_VOLUME_UP C_VOLUME_DOWN   &inc_dec_cp C_BRI_INC C_BRI_DEC  >;   // encoders
                };

        lower_layer {
            bindings = < &kp M    &kp C>;   // pushbuttons
            sensor-bindings = <&kp LC(U) &kp LC(D) &kp N &kp LS(N)>;   // encoders
                };
    };

};

And define which keys in the key matrix correspond to encoder pushbuttons in .dtsi file

left_encoder0: encoder_0 {
        compatible = "alps,ec11";
        label = "ENCODER_0";
        a-gpios = <&pro_micro_a 3 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>;
        b-gpios = <&pro_micro_a 2 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>;
        resolution = <4>;
        btn-row = <0>;
        btn-col = <2>;
    };
left_encoder1: encoder_1 {
        compatible = "alps,ec11";
        label = "ENCODER_1";
        a-gpios = <&pro_micro_a 4 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>;
        b-gpios = <&pro_micro_a 5 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>;
        resolution = <4>;
        btn-row = <0>;
        btn-col = <3>;
    };
joelspadin commented 3 years ago

Keep in mind that encoders are currently the only type of sensor, but other types of sensors will likely be added in the future (sliders, trackballs, accelerometers?, etc.). Should these special layers only apply to encoders or to all sensors at the same time?

innovaker commented 3 years ago

Thanks @benjizhai!

@joelspadin, I can envisage use cases for them, but they'd need to be optional. I believe @petejohanson's also keeping multiple types of sensors in mind as he revisits inter-node communications.

Also, let's keep in mind that we're currently fitting our square pegs into DT's round holes, so there might be come a point where it's wiser just to start working on the successor (built for purpose) rather than burning time trying to it with the current system.

innovaker commented 3 years ago

Generally speaking I'd like us to avoid the route of duplicating behaviors. This has been discussed at length in #213, so I think we should think outside the box a bit before going down this path.