diff options
| author | Selene ToyKeeper | 2019-05-13 02:27:55 -0600 |
|---|---|---|
| committer | Selene ToyKeeper | 2019-05-13 02:27:55 -0600 |
| commit | 17472974892e4ff224fc84c73cefb2af6cfd4954 (patch) | |
| tree | 49d39a93dda664829aca996328aaa3e76c84d3c8 | |
| parent | completely recalibrated FF E01 to match production sample (diff) | |
| parent | Increased default candle magnitude to better fit recent changes (diff) | |
| download | anduril-17472974892e4ff224fc84c73cefb2af6cfd4954.tar.gz anduril-17472974892e4ff224fc84c73cefb2af6cfd4954.tar.bz2 anduril-17472974892e4ff224fc84c73cefb2af6cfd4954.zip | |
merged from lantern branch, to get candle mode updates
| -rw-r--r-- | spaghetti-monster/anduril/anduril.c | 86 | ||||
| -rw-r--r-- | spaghetti-monster/anduril/cfg-blf-lantern.h | 76 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-ramping.c | 18 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-ramping.h | 4 |
4 files changed, 171 insertions, 13 deletions
diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c index 88aafbb..e3ff0cb 100644 --- a/spaghetti-monster/anduril/anduril.c +++ b/spaghetti-monster/anduril/anduril.c @@ -145,6 +145,9 @@ typedef enum { ramp_discrete_ceil_e, ramp_discrete_steps_e, #endif + #ifdef USE_TINT_RAMPING + tint_e, + #endif #ifdef USE_STROBE_STATE strobe_type_e, #endif @@ -198,6 +201,10 @@ uint8_t steady_state(Event event, uint16_t arg); #ifdef USE_RAMP_CONFIG uint8_t ramp_config_state(Event event, uint16_t arg); #endif +#ifdef USE_TINT_RAMPING +// not actually a mode, more of a fallback under other modes +uint8_t tint_ramping_state(Event event, uint16_t arg); +#endif // party and tactical strobes #ifdef USE_STROBE_STATE uint8_t strobe_state(Event event, uint16_t arg); @@ -376,6 +383,9 @@ volatile uint8_t bike_flasher_brightness = MAX_1x7135; #ifdef USE_CANDLE_MODE uint8_t candle_mode_state(Event event, uint16_t arg); uint8_t triangle_wave(uint8_t phase); +#ifndef CANDLE_AMPLITUDE +#define CANDLE_AMPLITUDE 25 +#endif #endif #ifdef USE_BEACON_MODE @@ -860,6 +870,39 @@ uint8_t steady_state(Event event, uint16_t arg) { } +#ifdef USE_TINT_RAMPING +uint8_t tint_ramping_state(Event event, uint16_t arg) { + static int8_t tint_ramp_direction = 1; + + // click, click, hold: change the tint + if (event == EV_click3_hold) { + //if ((arg & 1) == 0) { // ramp slower + if ((tint_ramp_direction > 0) && (tint < 255)) { + tint += 1; + } + else if ((tint_ramp_direction < 0) && (tint > 0)) { + tint -= 1; + } + set_level(actual_level); + //} + return EVENT_HANDLED; + } + + // click, click, hold, release: reverse direction for next ramp + else if (event == EV_click3_hold_release) { + tint_ramp_direction = -tint_ramp_direction; + if (tint == 0) tint_ramp_direction = 1; + else if (tint == 255) tint_ramp_direction = -1; + // remember tint after battery change + save_config(); + return EVENT_HANDLED; + } + + return EVENT_NOT_HANDLED; +} +#endif // ifdef USE_TINT_RAMPING + + #ifdef USE_STROBE_STATE uint8_t strobe_state(Event event, uint16_t arg) { // 'st' reduces ROM size by avoiding access to a volatile var @@ -1060,17 +1103,18 @@ inline void bike_flasher_iter() { #ifdef USE_CANDLE_MODE uint8_t candle_mode_state(Event event, uint16_t arg) { - // FIXME: make candle variance magnitude a compile-time option, - // since 20 is sometimes too much or too little, - // depending on the driver type and ramp shape - //#define MAX_CANDLE_LEVEL (RAMP_SIZE-8-6-4) - #define MAX_CANDLE_LEVEL (RAMP_SIZE/2) + #define MAX_CANDLE_LEVEL (RAMP_LENGTH-CANDLE_AMPLITUDE-15) static uint8_t candle_wave1 = 0; static uint8_t candle_wave2 = 0; static uint8_t candle_wave3 = 0; static uint8_t candle_wave2_speed = 0; - static uint8_t candle_wave2_depth = 7; - static uint8_t candle_wave3_depth = 4; + // these should add up to 100 + #define CANDLE_WAVE1_MAXDEPTH 30 + #define CANDLE_WAVE2_MAXDEPTH 45 + #define CANDLE_WAVE3_MAXDEPTH 25 + static const uint8_t candle_wave1_depth = CANDLE_WAVE1_MAXDEPTH * CANDLE_AMPLITUDE / 100; + static uint8_t candle_wave2_depth = CANDLE_WAVE2_MAXDEPTH * CANDLE_AMPLITUDE / 100; + static uint8_t candle_wave3_depth = CANDLE_WAVE3_MAXDEPTH * CANDLE_AMPLITUDE / 100; static uint8_t candle_mode_brightness = 24; static uint8_t candle_mode_timer = 0; #define TICKS_PER_CANDLE_MINUTE 4096 // about 65 seconds @@ -1115,7 +1159,7 @@ uint8_t candle_mode_state(Event event, uint16_t arg) { // self-timer dims the light during the final minute uint8_t subtract = 0; if (candle_mode_timer == 1) { - subtract = ((candle_mode_brightness+20) + subtract = ((candle_mode_brightness+CANDLE_AMPLITUDE) * ((arg & (TICKS_PER_CANDLE_MINUTE-1)) >> 4)) >> 8; } @@ -1132,7 +1176,7 @@ uint8_t candle_mode_state(Event event, uint16_t arg) { } // 3-oscillator synth for a relatively organic pattern uint8_t add; - add = ((triangle_wave(candle_wave1) * 8) >> 8) + add = ((triangle_wave(candle_wave1) * candle_wave1_depth) >> 8) + ((triangle_wave(candle_wave2) * candle_wave2_depth) >> 8) + ((triangle_wave(candle_wave3) * candle_wave3_depth) >> 8); int8_t brightness = candle_mode_brightness + add - subtract; @@ -1140,6 +1184,7 @@ uint8_t candle_mode_state(Event event, uint16_t arg) { set_level(brightness); // wave1: slow random LFO + // TODO: make wave slower and more erratic? if ((arg & 1) == 0) candle_wave1 += pseudo_rand() & 1; // wave2: medium-speed erratic LFO candle_wave2 += candle_wave2_speed; @@ -1152,8 +1197,10 @@ uint8_t candle_mode_state(Event event, uint16_t arg) { if ((candle_wave2_depth > 0) && ((pseudo_rand() & 0b00111111) == 0)) candle_wave2_depth --; // random sawtooth retrigger - if ((pseudo_rand()) == 0) { - candle_wave2_depth = 7; + if (pseudo_rand() == 0) { + // random amplitude + //candle_wave2_depth = 2 + (pseudo_rand() % ((CANDLE_WAVE2_MAXDEPTH * CANDLE_AMPLITUDE / 100) - 2)); + candle_wave2_depth = pseudo_rand() % (CANDLE_WAVE2_MAXDEPTH * CANDLE_AMPLITUDE / 100); //candle_wave3_depth = 5; candle_wave2 = 0; } @@ -1161,7 +1208,9 @@ uint8_t candle_mode_state(Event event, uint16_t arg) { if ((candle_wave3_depth > 2) && ((pseudo_rand() & 0b00011111) == 0)) candle_wave3_depth --; if ((pseudo_rand() & 0b01111111) == 0) - candle_wave3_depth = 5; + // random amplitude + //candle_wave3_depth = 2 + (pseudo_rand() % ((CANDLE_WAVE3_MAXDEPTH * CANDLE_AMPLITUDE / 100) - 2)); + candle_wave3_depth = pseudo_rand() % (CANDLE_WAVE3_MAXDEPTH * CANDLE_AMPLITUDE / 100); return MISCHIEF_MANAGED; } return EVENT_NOT_HANDLED; @@ -1936,6 +1985,9 @@ void load_config() { ramp_discrete_ceil = eeprom[ramp_discrete_ceil_e]; ramp_discrete_steps = eeprom[ramp_discrete_steps_e]; #endif + #ifdef USE_TINT_RAMPING + tint = eeprom[tint_e]; + #endif #if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE) strobe_type = eeprom[strobe_type_e]; // TODO: move this to eeprom_wl? strobe_delays[0] = eeprom[strobe_delays_0_e]; @@ -1974,6 +2026,9 @@ void save_config() { eeprom[ramp_discrete_ceil_e] = ramp_discrete_ceil; eeprom[ramp_discrete_steps_e] = ramp_discrete_steps; #endif + #ifdef USE_TINT_RAMPING + eeprom[tint_e] = tint; + #endif #if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE) eeprom[strobe_type_e] = strobe_type; // TODO: move this to eeprom_wl? eeprom[strobe_delays_0_e] = strobe_delays[0]; @@ -2073,14 +2128,19 @@ void setup() { load_config(); + #ifdef USE_TINT_RAMPING + // add tint ramping underneath every other state + push_state(tint_ramping_state, 0); + #endif // ifdef USE_TINT_RAMPING + #ifdef USE_MUGGLE_MODE if (muggle_mode_active) push_state(muggle_state, (MUGGLE_FLOOR+MUGGLE_CEILING)/2); else #endif push_state(off_state, 0); - #endif + #endif // ifdef START_AT_MEMORIZED_LEVEL } diff --git a/spaghetti-monster/anduril/cfg-blf-lantern.h b/spaghetti-monster/anduril/cfg-blf-lantern.h new file mode 100644 index 0000000..3d4c762 --- /dev/null +++ b/spaghetti-monster/anduril/cfg-blf-lantern.h @@ -0,0 +1,76 @@ +// BLF Lantern config options for Anduril +/* BLF Lantern pinout + * ---- + * Reset -|1 8|- VCC + * eswitch -|2 7|- powerbank enable? + * aux LED -|3 6|- PWM (5000K) + * GND -|4 5|- PWM (3000K) + * ---- + */ + +// basically the same as a Q8... sort of +#include "hwdef-BLF_Q8.h" + +// the button lights up +#define USE_INDICATOR_LED +// the button is visible while main LEDs are on +#define USE_INDICATOR_LED_WHILE_RAMPING +// enable blinking indicator LED while off +#define TICK_DURING_STANDBY +#define STANDBY_TICK_SPEED 3 // every 0.128 s +#define USE_FANCIER_BLINKING_INDICATOR +// off mode: high (2) +// lockout: blinking (3) +#define INDICATOR_LED_DEFAULT_MODE ((3<<2) + 2) + +// the lantern has two PWM channels, but they drive different sets of emitters +// (one channel for warm emitters, one channel for cold) +// so enable a special ramping mode which changes tint instead of brightness +#define USE_TINT_RAMPING + +#ifdef RAMP_LENGTH +#undef RAMP_LENGTH +#endif + +// level_calc.py 1 150 7135 1 30 800 +#define RAMP_LENGTH 150 +#define PWM1_LEVELS 1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,11,11,12,13,13,14,15,15,16,17,18,18,19,20,21,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,43,44,45,46,48,49,50,51,53,54,56,57,58,60,61,63,64,66,67,69,70,72,74,75,77,79,80,82,84,85,87,89,91,93,95,97,98,100,102,104,106,108,111,113,115,117,119,121,124,126,128,130,133,135,137,140,142,145,147,150,152,155,157,160,163,165,168,171,173,176,179,182,185,188,190,193,196,199,202,205,209,212,215,218,221,224,228,231,234,238,241,245,248,251,255 +#define MAX_1x7135 65 +#define HALFSPEED_LEVEL 14 +#define QUARTERSPEED_LEVEL 5 + +// the default of 26 looks a bit flat, so increase it +#define CANDLE_AMPLITUDE 40 + +// set floor and ceiling as far apart as possible +// because this lantern isn't overpowered +#define RAMP_SMOOTH_FLOOR 1 +#define RAMP_SMOOTH_CEIL 150 +#define RAMP_DISCRETE_FLOOR 20 +#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL +#define RAMP_DISCRETE_STEPS 5 + +// the sensor (attiny85) is nowhere near the emitters +// so thermal regulation can't work +#ifdef USE_THERMAL_REGULATION +#undef USE_THERMAL_REGULATION +#endif + +// also, the set_level_gradually() thing isn't compatible with tint ramping +// (but unsetting it here doesn't actually do anything, because the thermal +// regulation define enables it later... so this is mostly just a note to +// make this compatibility issue explicit) +#ifdef USE_SET_LEVEL_GRADUALLY +#undef USE_SET_LEVEL_GRADUALLY +#endif + +// don't blink while ramping +#ifdef BLINK_AT_RAMP_MIDDLE +#undef BLINK_AT_RAMP_MIDDLE +#endif +#ifdef BLINK_AT_RAMP_CEILING +#undef BLINK_AT_RAMP_CEILING +#endif +#ifdef BLINK_AT_RAMP_FLOOR +#undef BLINK_AT_RAMP_FLOOR +#endif diff --git a/spaghetti-monster/fsm-ramping.c b/spaghetti-monster/fsm-ramping.c index 6cdf5e6..ee816dd 100644 --- a/spaghetti-monster/fsm-ramping.c +++ b/spaghetti-monster/fsm-ramping.c @@ -25,9 +25,11 @@ void set_level(uint8_t level) { actual_level = level; + #ifdef USE_SET_LEVEL_GRADUALLY gradual_target = level; #endif + #ifdef USE_INDICATOR_LED #ifdef USE_INDICATOR_LED_WHILE_RAMPING if (! go_to_standby) @@ -40,6 +42,7 @@ void set_level(uint8_t level) { indicator_led(0); #endif #endif + //TCCR0A = PHASE; if (level == 0) { #if PWM_CHANNELS >= 1 @@ -56,6 +59,19 @@ void set_level(uint8_t level) { #endif } else { level --; + + #ifdef USE_TINT_RAMPING + // calculate actual PWM levels based on a single-channel ramp + // and a global tint value + uint8_t brightness = pgm_read_byte(pwm1_levels + level); + uint8_t warm_PWM, cool_PWM; + cool_PWM = (((uint16_t)tint * (uint16_t)brightness) + 127) / 255; + warm_PWM = brightness - cool_PWM; + + PWM1_LVL = warm_PWM; + PWM2_LVL = cool_PWM; + #else + #if PWM_CHANNELS >= 1 PWM1_LVL = pgm_read_byte(pwm1_levels + level); #endif @@ -68,6 +84,8 @@ void set_level(uint8_t level) { #if PWM_CHANNELS >= 4 PWM4_LVL = pgm_read_byte(pwm4_levels + level); #endif + + #endif // ifdef USE_TINT_RAMPING } #ifdef USE_DYNAMIC_UNDERCLOCKING auto_clock_speed(); diff --git a/spaghetti-monster/fsm-ramping.h b/spaghetti-monster/fsm-ramping.h index 14c8dae..4ce8015 100644 --- a/spaghetti-monster/fsm-ramping.h +++ b/spaghetti-monster/fsm-ramping.h @@ -26,6 +26,10 @@ // actual_level: last ramp level set by set_level() volatile uint8_t actual_level = 0; +#ifdef USE_TINT_RAMPING +uint8_t tint = 128; +#endif + #ifdef USE_SET_LEVEL_GRADUALLY // adjust brightness very smoothly volatile uint8_t gradual_target; |
