RGB_HUI
、RGB_HUD
、RGB_SAI
、RGB_SAD
、RGB_VAI
和 RGB_VAD
》允许我增加或减少 RGB 底光灯的色调、饱和度和值。但我希望能够按住一个键来连续更改颜色。所以我做了这些改变:
在
config.h
:
#ifdef RGBLIGHT_ENABLE
#define RGBLIGHT_HUE_STEP 1
#define RGBLIGHT_SAT_STEP 1
#define RGBLIGHT_VAL_STEP 1
#endif
然后在
keymap.c
我制作了自定义键码:
enum custom_keycodes {
KC_HUI = SAFE_RANGE,
KC_HUD,
KC_SAI,
KC_SAD,
KC_VAI,
KC_VAD
};
并定义了一些变量:
// 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;
然后我使用键码来设置标志和计时器:
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;
}
然后我使用矩阵扫描来使用这些标志和计时器来更改颜色:
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_HUI
和 KC_HUD
的预期完全一样:如果我按住按键足够长的时间,它会绕过弯曲,并且色调会继续循环。KC_SAI
、KC_VAI
和KC_VAD
至少可以正常工作。我可以将饱和度或值增加到最大值,它就会停在那里,同样,如果我减少值,它就会停在零。KC_SAD
就是问题所在。当我按住它足够长的时间(刚刚过去白色)时,键盘就会爆炸。它变成了奇怪的橙色,没有任何作用。作为参考,这里是 GitHub 提交,我在其中进行了所有更改,当然还有我的其余代码。
KC_SAD
会爆炸而不是停下来或绕过去吗?我对此进行了更多实验,并提出了一种不同的实现,该实现在添加到固件大小的代码行和字节方面更加有效。请注意,它不是定义新的自定义键码,而是劫持现有的 RGB_... 来实现新的和改进的目的:
#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;
}
这是一个非常好的功能!
"bomb out"
上看到的 KC_SAD
行为。rgblight_increase_sat_noeeprom()
来调整饱和度(及其对应的色调/饱和度和减少)。然后当您松开按键时,才可以将当前的 HSV 设置写入 eeprom(使用 rgblight_sethsv()
将最终值设置到 eeprom 中。