If RGBLIGHT_EFFECT_BREATHE_CENTER is undefined, use fixed breathe table instead of exp() and sin() (#5484)

* If RGBLIGHT_EFFECT_BREATHE_CENTER is undefined, use fixed breathe table instead of exp() and sin()

* Change rgblight breathing table size to be easily selectable.

add RGBLIGHT_BREATHE_TABLE_SIZE macro for customize breathing effect.
This commit is contained in:
Takeshi ISHII 2019-05-02 23:59:29 +09:00 committed by MechMerlin
parent 4db31fb374
commit 3da8d46a07
6 changed files with 185 additions and 4 deletions

View File

@ -114,7 +114,7 @@ The following options can be used to tweak the various animations:
|`RGBLIGHT_EFFECT_RGB_TEST` |*Not defined*|If defined, enable RGB test animation mode. | |`RGBLIGHT_EFFECT_RGB_TEST` |*Not defined*|If defined, enable RGB test animation mode. |
|`RGBLIGHT_EFFECT_ALTERNATING` |*Not defined*|If defined, enable alternating animation mode. | |`RGBLIGHT_EFFECT_ALTERNATING` |*Not defined*|If defined, enable alternating animation mode. |
|`RGBLIGHT_ANIMATIONS` |*Not defined*|If defined, enables all additional animation modes | |`RGBLIGHT_ANIMATIONS` |*Not defined*|If defined, enables all additional animation modes |
|`RGBLIGHT_EFFECT_BREATHE_CENTER` |`1.85` |Used to calculate the curve for the breathing animation. Valid values are 1.0 to 2.7 | |`RGBLIGHT_EFFECT_BREATHE_CENTER` |*Not defined*|If defined, used to calculate the curve for the breathing animation. Valid values are 1.0 to 2.7 |
|`RGBLIGHT_EFFECT_BREATHE_MAX` |`255` |The maximum brightness for the breathing mode. Valid values are 1 to 255 | |`RGBLIGHT_EFFECT_BREATHE_MAX` |`255` |The maximum brightness for the breathing mode. Valid values are 1 to 255 |
|`RGBLIGHT_EFFECT_SNAKE_LENGTH` |`4` |The number of LEDs to light up for the "Snake" animation | |`RGBLIGHT_EFFECT_SNAKE_LENGTH` |`4` |The number of LEDs to light up for the "Snake" animation |
|`RGBLIGHT_EFFECT_KNIGHT_LENGTH` |`3` |The number of LEDs to light up for the "Knight" animation | |`RGBLIGHT_EFFECT_KNIGHT_LENGTH` |`3` |The number of LEDs to light up for the "Knight" animation |

View File

@ -879,6 +879,14 @@ void rgblight_task(void) {
// Effects // Effects
#ifdef RGBLIGHT_EFFECT_BREATHING #ifdef RGBLIGHT_EFFECT_BREATHING
#ifndef RGBLIGHT_EFFECT_BREATHE_CENTER
#ifndef RGBLIGHT_BREATHE_TABLE_SIZE
#define RGBLIGHT_BREATHE_TABLE_SIZE 256 // 256 or 128 or 64
#endif
#include <rgblight_breathe_table.h>
#endif
__attribute__ ((weak)) __attribute__ ((weak))
const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5}; const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5};
@ -886,7 +894,11 @@ void rgblight_effect_breathing(animation_status_t *anim) {
float val; float val;
// http://sean.voisen.org/blog/2011/10/breathing-led-with-arduino/ // http://sean.voisen.org/blog/2011/10/breathing-led-with-arduino/
#ifdef RGBLIGHT_EFFECT_BREATHE_TABLE
val = pgm_read_byte(&rgblight_effect_breathe_table[anim->pos / table_scale]);
#else
val = (exp(sin((anim->pos/255.0)*M_PI)) - RGBLIGHT_EFFECT_BREATHE_CENTER/M_E)*(RGBLIGHT_EFFECT_BREATHE_MAX/(M_E-1/M_E)); val = (exp(sin((anim->pos/255.0)*M_PI)) - RGBLIGHT_EFFECT_BREATHE_CENTER/M_E)*(RGBLIGHT_EFFECT_BREATHE_MAX/(M_E-1/M_E));
#endif
rgblight_sethsv_noeeprom_old(rgblight_config.hue, rgblight_config.sat, val); rgblight_sethsv_noeeprom_old(rgblight_config.hue, rgblight_config.sat, val);
anim->pos = (anim->pos + 1); anim->pos = (anim->pos + 1);
} }

View File

@ -80,9 +80,7 @@ enum RGBLIGHT_EFFECT_MODE {
#define RGBLIGHT_MODES (RGBLIGHT_MODE_last-1) #define RGBLIGHT_MODES (RGBLIGHT_MODE_last-1)
#ifndef RGBLIGHT_EFFECT_BREATHE_CENTER // sample: #define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85
#define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85 // 1-2.7
#endif
#ifndef RGBLIGHT_EFFECT_BREATHE_MAX #ifndef RGBLIGHT_EFFECT_BREATHE_MAX
#define RGBLIGHT_EFFECT_BREATHE_MAX 255 // 0-255 #define RGBLIGHT_EFFECT_BREATHE_MAX 255 // 0-255

View File

@ -0,0 +1,116 @@
#ifndef RGBLIGHT_EFFECT_BREATHE_TABLE
#define RGBLIGHT_EFFECT_BREATHE_TABLE
const uint8_t rgblight_effect_breathe_table[] PROGMEM = {
/* #define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85 */
/* #define RGBLIGHT_EFFECT_BREATHE_MAX 255 */
#if RGBLIGHT_BREATHE_TABLE_SIZE == 256
0x22, 0x23, 0x25, 0x26, 0x28, 0x29, 0x2a, 0x2c,
0x2d, 0x2f, 0x30, 0x32, 0x33, 0x35, 0x36, 0x38,
0x3a, 0x3b, 0x3d, 0x3e, 0x40, 0x42, 0x43, 0x45,
0x47, 0x49, 0x4a, 0x4c, 0x4e, 0x50, 0x51, 0x53,
0x55, 0x57, 0x59, 0x5a, 0x5c, 0x5e, 0x60, 0x62,
0x64, 0x66, 0x68, 0x69, 0x6b, 0x6d, 0x6f, 0x71,
0x73, 0x75, 0x77, 0x79, 0x7b, 0x7d, 0x7f, 0x81,
0x83, 0x85, 0x87, 0x89, 0x8a, 0x8c, 0x8e, 0x90,
0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, 0x9f,
0xa1, 0xa3, 0xa5, 0xa7, 0xa8, 0xaa, 0xac, 0xae,
0xaf, 0xb1, 0xb3, 0xb4, 0xb6, 0xb8, 0xb9, 0xbb,
0xbc, 0xbe, 0xbf, 0xc1, 0xc2, 0xc3, 0xc5, 0xc6,
0xc7, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xd0,
0xd1, 0xd2, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0xd7, 0xd8, 0xd9, 0xd9, 0xda, 0xda, 0xdb, 0xdb,
0xdb, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdd, 0xdd,
0xdd, 0xdd, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdb,
0xdb, 0xdb, 0xda, 0xda, 0xd9, 0xd9, 0xd8, 0xd7,
0xd7, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd2, 0xd1,
0xd0, 0xce, 0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc7,
0xc6, 0xc5, 0xc3, 0xc2, 0xc1, 0xbf, 0xbe, 0xbc,
0xbb, 0xb9, 0xb8, 0xb6, 0xb4, 0xb3, 0xb1, 0xaf,
0xae, 0xac, 0xaa, 0xa8, 0xa7, 0xa5, 0xa3, 0xa1,
0x9f, 0x9e, 0x9c, 0x9a, 0x98, 0x96, 0x94, 0x92,
0x90, 0x8e, 0x8c, 0x8a, 0x89, 0x87, 0x85, 0x83,
0x81, 0x7f, 0x7d, 0x7b, 0x79, 0x77, 0x75, 0x73,
0x71, 0x6f, 0x6d, 0x6b, 0x69, 0x68, 0x66, 0x64,
0x62, 0x60, 0x5e, 0x5c, 0x5a, 0x59, 0x57, 0x55,
0x53, 0x51, 0x50, 0x4e, 0x4c, 0x4a, 0x49, 0x47,
0x45, 0x43, 0x42, 0x40, 0x3e, 0x3d, 0x3b, 0x3a,
0x38, 0x36, 0x35, 0x33, 0x32, 0x30, 0x2f, 0x2d,
0x2c, 0x2a, 0x29, 0x28, 0x26, 0x25, 0x23, 0x22
#endif /* 256 bytes table */
#if RGBLIGHT_BREATHE_TABLE_SIZE == 128
0x22, 0x25, 0x28, 0x2a,
0x2d, 0x30, 0x33, 0x36,
0x3a, 0x3d, 0x40, 0x43,
0x47, 0x4a, 0x4e, 0x51,
0x55, 0x59, 0x5c, 0x60,
0x64, 0x68, 0x6b, 0x6f,
0x73, 0x77, 0x7b, 0x7f,
0x83, 0x87, 0x8a, 0x8e,
0x92, 0x96, 0x9a, 0x9e,
0xa1, 0xa5, 0xa8, 0xac,
0xaf, 0xb3, 0xb6, 0xb9,
0xbc, 0xbf, 0xc2, 0xc5,
0xc7, 0xca, 0xcc, 0xce,
0xd1, 0xd2, 0xd4, 0xd6,
0xd7, 0xd9, 0xda, 0xdb,
0xdb, 0xdc, 0xdc, 0xdd,
0xdd, 0xdc, 0xdc, 0xdc,
0xdb, 0xda, 0xd9, 0xd8,
0xd7, 0xd5, 0xd3, 0xd2,
0xd0, 0xcd, 0xcb, 0xc9,
0xc6, 0xc3, 0xc1, 0xbe,
0xbb, 0xb8, 0xb4, 0xb1,
0xae, 0xaa, 0xa7, 0xa3,
0x9f, 0x9c, 0x98, 0x94,
0x90, 0x8c, 0x89, 0x85,
0x81, 0x7d, 0x79, 0x75,
0x71, 0x6d, 0x69, 0x66,
0x62, 0x5e, 0x5a, 0x57,
0x53, 0x50, 0x4c, 0x49,
0x45, 0x42, 0x3e, 0x3b,
0x38, 0x35, 0x32, 0x2f,
0x2c, 0x29, 0x26, 0x23
#endif /* 128 bytes table */
#if RGBLIGHT_BREATHE_TABLE_SIZE == 64
0x22, 0x28,
0x2d, 0x33,
0x3a, 0x40,
0x47, 0x4e,
0x55, 0x5c,
0x64, 0x6b,
0x73, 0x7b,
0x83, 0x8a,
0x92, 0x9a,
0xa1, 0xa8,
0xaf, 0xb6,
0xbc, 0xc2,
0xc7, 0xcc,
0xd1, 0xd4,
0xd7, 0xda,
0xdb, 0xdc,
0xdd, 0xdc,
0xdb, 0xd9,
0xd7, 0xd3,
0xd0, 0xcb,
0xc6, 0xc1,
0xbb, 0xb4,
0xae, 0xa7,
0x9f, 0x98,
0x90, 0x89,
0x81, 0x79,
0x71, 0x69,
0x62, 0x5a,
0x53, 0x4c,
0x45, 0x3e,
0x38, 0x32,
0x2c, 0x26
#endif /* 64 bytes table */
};
static const int table_scale = 256/sizeof(rgblight_effect_breathe_table);
#endif /* RGBLIGHT_EFFECT_BREATHE_TABLE */

View File

@ -77,6 +77,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// #define RGBLIGHT_EFFECT_STATIC_GRADIENT // #define RGBLIGHT_EFFECT_STATIC_GRADIENT
// #define RGBLIGHT_EFFECT_RGB_TEST // #define RGBLIGHT_EFFECT_RGB_TEST
// #define RGBLIGHT_EFFECT_ALTERNATING // #define RGBLIGHT_EFFECT_ALTERNATING
// /*== customize breathing effect ==*/
// /*==== (DEFAULT) use fixed table instead of exp() and sin() ====*/
// #define RGBLIGHT_BREATHE_TABLE_SIZE 256 // 256(default) or 128 or 64
// /*==== use exp() and sin() ====*/
// #define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85 // 1 to 2.7
// #define RGBLIGHT_EFFECT_BREATHE_MAX 255 // 0 to 255
// #endif // #endif
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ /* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */

View File

@ -0,0 +1,49 @@
//
// calculate rgblight_effect_breathe_table[] values
//
// this is host program for quantum/rgblight.c:void rgblight_effect_breathing();
//
// example:
// $ edit util/rgblight_breathing_table_calc.c
// $ cc -o util/rgblight_breathing_table_calc util/rgblight_breathing_table_calc.c
// $ ./util/rgblight_breathing_table_calc > keyboards/KEYBOARD_NAME/keymaps/KEYMAP_NAME/rgblight_breathe_table.h
//
#include <stdio.h>
#include <math.h>
#include <stdint.h>
/// customize breeathing effect part ///////////////////////////
#define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85 // 1 to 2.7
#define RGBLIGHT_EFFECT_BREATHE_MAX 255 // 0 to 255
////////////////////////////////////////////////////////////////
int main(void) {
int pos, step;
int table[256];
for (pos = 0; pos < 256; pos ++ ) {
table[pos] = (uint8_t)(
(exp(sin((pos/255.0)*M_PI))- RGBLIGHT_EFFECT_BREATHE_CENTER/M_E)
* (RGBLIGHT_EFFECT_BREATHE_MAX/(M_E-1/M_E))
);
}
printf("#ifndef RGBLIGHT_EFFECT_BREATHE_TABLE\n");
printf("#define RGBLIGHT_EFFECT_BREATHE_TABLE\n\n");
printf("const uint8_t rgblight_effect_breathe_table[] PROGMEM = {\n");
printf(" /* #define RGBLIGHT_EFFECT_BREATHE_CENTER %.2f */\n", RGBLIGHT_EFFECT_BREATHE_CENTER);
printf(" /* #define RGBLIGHT_EFFECT_BREATHE_MAX %d */\n", RGBLIGHT_EFFECT_BREATHE_MAX);
for (int s = 0, step = (1<<s); s < 3 ; s += 1, step = (1<<s) ) {
printf("\n #if RGBLIGHT_BREATHE_TABLE_SIZE == %d\n",
s == 0 ? 256:(s== 1 ? 128: 64));
for (pos = 0; pos < 256; pos += step ) {
printf(" 0x%x%s", table[pos], (pos+step)>=256?"":"," );
if ((pos+step) % 8 == 0)
printf("\n");
}
printf(" #endif /* %d bytes table */\n", s == 0 ? 256:(s== 1 ? 128: 64));
}
printf("};\n");
printf("\nstatic const int table_scale = 256/sizeof(rgblight_effect_breathe_table);\n");
printf("\n#endif /* RGBLIGHT_EFFECT_BREATHE_TABLE */\n");
return 0;
}