首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QMK RGB饱和度触底

QMK RGB饱和度触底
EN

Stack Overflow用户
提问于 2021-01-04 00:20:46
回答 2查看 285关注 0票数 0

RGB密钥码 RGB_HUIRGB_HUDRGB_SAIRGB_SADRGB_VAIRGB_VAD允许我增加或减少我的RGB欠辉灯的色调、饱和度和值。但我希望能够按住键,不断地改变颜色。所以我做了这些改变:

config.h

代码语言:javascript
复制
#ifdef RGBLIGHT_ENABLE
  #define RGBLIGHT_HUE_STEP 1
  #define RGBLIGHT_SAT_STEP 1
  #define RGBLIGHT_VAL_STEP 1
#endif

然后在keymap.c中,我制作了自定义密钥:

代码语言:javascript
复制
enum custom_keycodes {
    KC_HUI = SAFE_RANGE,
    KC_HUD,
    KC_SAI,
    KC_SAD,
    KC_VAI,
    KC_VAD
};

并定义了一些变量:

代码语言:javascript
复制
// flags. 0 = no change, 1 = increment, -1 = decrement.
int8_t change_hue = 0;
int8_t change_saturation = 0;
int8_t change_value = 0;

// timers to control color change speed
uint16_t hue_timer = 0;
uint16_t saturation_timer = 0;
uint16_t value_timer = 0;

// seconds it takes to cycle through 0-255 or back
// technically 1 = 1.024 seconds, yielding even multiples of 4ms per tick (1024 / 256).
const int8_t hue_seconds = 5;
const int8_t saturation_seconds = 5;
const int8_t value_seconds = 5;

然后我使用键码来设置标志和计时器:

代码语言:javascript
复制
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
    switch (keycode) {
        case KC_HUI:
            if (record->event.pressed) {
                hue_timer = timer_read();
                change_hue = 1;
            } else {
                change_hue = 0;
            }
            break;
        case KC_HUD:
            if (record->event.pressed) {
                hue_timer = timer_read();
                change_hue = -1;
            } else {
                change_hue = 0;
            }
            break;
        case KC_SAI:
            if (record->event.pressed) {
                saturation_timer = timer_read();
                change_saturation = 1;
            } else {
                change_saturation = 0;
            }
            break;
        case KC_SAD:
            if (record->event.pressed) {
                saturation_timer = timer_read();
                change_saturation = -1;
            } else {
                change_saturation = 0;
            }
            break;
        case KC_VAI:
            if (record->event.pressed) {
                value_timer = timer_read();
                change_value = 1;
            } else {
                change_value = 0;
            }
            break;
        case KC_VAD:
            if (record->event.pressed) {
                value_timer = timer_read();
                change_value = -1;
            } else {
                change_value = 0;
            }
            break;
    }
    return true;
}

然后,我使用矩阵扫描来更改颜色,使用这些标志和定时器:

代码语言:javascript
复制
void matrix_scan_user(void) {
    switch (change_hue) {
        case 0:
            break;
        case 1:
            if (timer_elapsed(hue_timer) > (hue_seconds * 4)) {
                hue_timer = timer_read();
                rgblight_increase_hue();
            }
            break;
        case -1:
            if (timer_elapsed(hue_timer) > (hue_seconds * 4)) {
                hue_timer = timer_read();
                rgblight_decrease_hue();
            }
            break;
    }
    switch (change_saturation) {
        case 0:
            break;
        case 1:
            if (timer_elapsed(saturation_timer) > (saturation_seconds * 4)) {
                saturation_timer = timer_read();
                rgblight_increase_sat();
            }
            break;
        case -1:
            if (timer_elapsed(saturation_timer) > (saturation_seconds * 4)) {
                saturation_timer = timer_read();
                rgblight_decrease_sat();
            }
            break;
    }
    switch (change_value) {
        case 0:
            break;
        case 1:
            if (timer_elapsed(value_timer) > (value_seconds * 4)) {
                value_timer = timer_read();
                rgblight_increase_val();
            }
            break;
        case -1:
            if (timer_elapsed(value_timer) > (value_seconds * 4)) {
                value_timer = timer_read();
                rgblight_decrease_val();
            }
            break;
    }
}

根据医生们的说法,每种颜色都应该分别以最大/分色调/饱和度/值来环绕。

  • 这似乎与KC_HUIKC_HUD的预期完全一样:如果我按住键足够长的时间,它就会绕过弯道,然后继续循环。
  • KC_SAIKC_VAIKC_VAD至少正常工作.我可以将饱和值或值增加到最大值,然后它就会停止,同样地,如果我将值降到零,它就会停止。
  • KC_SAD是问题所在。当我按住它足够长的时间(刚过了白色),键盘就会弹出来。它变成了奇怪的橙色,什么也不管用。

作为参考,这里是我所做的所有更改的GitHub提交,当然还有我的其余代码。

  1. 你知道为什么KC_SAD会爆炸,而不是停下来或绕来绕去?
  2. 你知道为什么饱和和价值都停止了吗,而不是像我所期望的那样,根据我对文档的阅读结果。
  3. 我能不能用另一种方式(向更有经验的用户提问)来尝试整个过程呢?
EN

回答 2

Stack Overflow用户

发布于 2021-01-04 03:53:06

我尝试了更多,并提出了一个不同的实现,在代码行和字节添加到固件大小方面效率要高得多。注意,它没有定义新的自定义密钥,而是劫持了现有的RGB_.为这一新的和改进的目的:

代码语言:javascript
复制
#include <lib/lib8tion/lib8tion.h>

// flags. 0 = no change, 1 = increment, -1 = decrement.
int8_t change_hue = 0;
int8_t change_sat = 0;
int8_t change_val = 0;

// timer to control color change speed
uint16_t change_timer = 0;
const uint16_t change_tick  = 15;

void matrix_scan_user(void) {
    if (change_hue != 0 || change_val != 0 || change_sat != 0) {
        if (timer_elapsed(change_timer) > change_tick) {
            HSV hsv = rgblight_get_hsv();
            hsv.h += change_hue;
            hsv.s = change_sat > 0 ? qadd8(hsv.s, (uint8_t) change_sat) : qsub8(hsv.s, (uint8_t) -change_sat);
            hsv.v = change_val > 0 ? qadd8(hsv.v, (uint8_t) change_val) : qsub8(hsv.v, (uint8_t) -change_val);
            rgblight_sethsv_noeeprom(hsv.h, hsv.s, hsv.v);
            change_timer = timer_read();
        }
    }
}

bool process_record_user(uint16_t keycode, keyrecord_t *record) {
    if (record->event.pressed) {
        switch (keycode) {

                // clang-format off
            case RGB_HUI: change_timer = timer_read(); change_hue =  1; return false;
            case RGB_HUD: change_timer = timer_read(); change_hue = -1; return false;
            case RGB_SAI: change_timer = timer_read(); change_sat =  1; return false;
            case RGB_SAD: change_timer = timer_read(); change_sat = -1; return false;
            case RGB_VAI: change_timer = timer_read(); change_val =  1; return false;
            case RGB_VAD: change_timer = timer_read(); change_val = -1; return false;
                // clang-format on
        }
    } else {
        bool rgb_done = false;
        switch (keycode) {
            case RGB_HUI:
            case RGB_HUD:
                change_hue = 0;
                rgb_done   = true;
                break;
            case RGB_SAI:
            case RGB_SAD:
                change_sat = 0;
                rgb_done   = true;
                break;
            case RGB_VAI:
            case RGB_VAD:
                change_val = 0;
                rgb_done   = true;
                break;
        }

        if (rgb_done) {
            HSV final = rgblight_get_hsv();
            rgblight_sethsv(final.h, final.s, final.v);
        }
    }

    return true;
}
票数 1
EN

Stack Overflow用户

发布于 2021-01-04 02:17:43

这是一个非常好的功能!

  1. 我将您的代码复制到我的键盘中,我无法复制您在"bomb out"上看到的KC_SAD行为。
  2. 文件不正确。饱和和值的增加/减少函数不会被包围,据我所知,它们不是打算包装的。他们的最大值在255,底部限制在0。我会申请公关来修正文件。
  3. 我在您的实现中看到的唯一重要问题是,它会导致大量写入eeprom,这是不健康的(随着时间的推移,它们会逐渐耗尽)。例如,您应该使用rgblight_increase_sat_noeeprom()来调整饱和度(以及对应的色调/饱和度和减少)。然后,当您释放键时,才应该将当前的HSV设置写入eeprom (使用rgblight_sethsv()将最终值设置为eeprom )。
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65556317

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档