~ruther/qmk_firmware

3da8d46a07167fc862e90b6bb232812d5cb64651 — Takeshi ISHII 6 years ago 4db31fb
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.
M docs/feature_rgblight.md => docs/feature_rgblight.md +1 -1
@@ 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_ALTERNATING`       |*Not defined*|If defined, enable alternating animation mode.                                       |
|`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_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                            |

M quantum/rgblight.c => quantum/rgblight.c +12 -0
@@ 879,6 879,14 @@ void rgblight_task(void) {

// Effects
#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))
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;

  // 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));
#endif
  rgblight_sethsv_noeeprom_old(rgblight_config.hue, rgblight_config.sat, val);
  anim->pos = (anim->pos + 1);
}

M quantum/rgblight.h => quantum/rgblight.h +1 -3
@@ 80,9 80,7 @@ enum RGBLIGHT_EFFECT_MODE {

#define RGBLIGHT_MODES (RGBLIGHT_MODE_last-1)

#ifndef RGBLIGHT_EFFECT_BREATHE_CENTER
#define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85  // 1-2.7
#endif
// sample: #define RGBLIGHT_EFFECT_BREATHE_CENTER   1.85

#ifndef RGBLIGHT_EFFECT_BREATHE_MAX
#define RGBLIGHT_EFFECT_BREATHE_MAX 255   // 0-255

A quantum/rgblight_breathe_table.h => quantum/rgblight_breathe_table.h +116 -0
@@ 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 */

M quantum/template/avr/config.h => quantum/template/avr/config.h +6 -0
@@ 77,6 77,12 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
//   #define RGBLIGHT_EFFECT_STATIC_GRADIENT
//   #define RGBLIGHT_EFFECT_RGB_TEST
//   #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

/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */

A util/rgblight_breathing_table_calc.c => util/rgblight_breathing_table_calc.c +49 -0
@@ 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;
}