aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSelene ToyKeeper2019-08-11 15:16:23 -0600
committerSelene ToyKeeper2019-08-11 15:16:23 -0600
commit89a86871aa6330218043586f0347c0c1e7c79dab (patch)
treee3a4cc2a4517e5563e91cdaaf86718170d4f0a37
parentAdded setup info for Fedora. (diff)
parentadded scripts to flash attiny1634, which were missing before (diff)
downloadanduril-89a86871aa6330218043586f0347c0c1e7c79dab.tar.gz
anduril-89a86871aa6330218043586f0347c0c1e7c79dab.tar.bz2
anduril-89a86871aa6330218043586f0347c0c1e7c79dab.zip
merged fsm to trunk... lots of updates:
+ attiny1634 support + Emisar D4v2 support + Mateminco MF01S / MT18 support + Fireflies E01 and E07v2 support + RGB aux LED support + added factory reset function + added manual / automatic memory toggle + added 2-level brightness during lockout + added Fireflies UI + made momentary mode also support strobe-group modes * thermal regulation rewritten, behaves mostly better now * strobe modes auto-reverse their ramp now * muggle mode fixes * UI diagram and manual updated * button timing adjusted, and compile-time options added for it * general refactoring
-rwxr-xr-xbin/build.sh4
-rwxr-xr-xbin/flash-tiny1634-fuses.sh9
-rwxr-xr-xbin/flash-tiny1634.sh3
-rw-r--r--hwdef-Emisar_D4v2.h100
-rw-r--r--hwdef-Mateminco_MF01S.h60
-rw-r--r--spaghetti-monster/anduril/anduril-manual.txt39
-rw-r--r--spaghetti-monster/anduril/anduril-ui.pngbin244079 -> 286759 bytes
-rw-r--r--spaghetti-monster/anduril/anduril.c647
-rw-r--r--spaghetti-monster/anduril/anduril.svg982
-rw-r--r--spaghetti-monster/anduril/anduril.txt18
-rwxr-xr-xspaghetti-monster/anduril/build-all.sh6
-rw-r--r--spaghetti-monster/anduril/cfg-emisar-d18.h2
-rw-r--r--spaghetti-monster/anduril/cfg-emisar-d4.h16
-rw-r--r--spaghetti-monster/anduril/cfg-emisar-d4s.h6
-rw-r--r--spaghetti-monster/anduril/cfg-emisar-d4v2-219.h8
-rw-r--r--spaghetti-monster/anduril/cfg-emisar-d4v2.h51
-rw-r--r--spaghetti-monster/anduril/cfg-ff-e01.h15
-rw-r--r--spaghetti-monster/anduril/cfg-ff-pl47-219.h2
-rw-r--r--spaghetti-monster/anduril/cfg-ff-pl47.h6
-rw-r--r--spaghetti-monster/anduril/cfg-ff-rot66.h2
-rw-r--r--spaghetti-monster/anduril/cfg-fw3a.h7
-rw-r--r--spaghetti-monster/anduril/cfg-mateminco-mf01s.h45
-rw-r--r--spaghetti-monster/fireflies-ui/Makefile2
-rwxr-xr-xspaghetti-monster/fireflies-ui/build-all.sh2
-rw-r--r--spaghetti-monster/fireflies-ui/cfg-ff-e01.h44
-rw-r--r--spaghetti-monster/fireflies-ui/cfg-ff-e07-2.h (renamed from spaghetti-monster/fireflies-ui/cfg-ff-edc-thrower.h)16
-rw-r--r--spaghetti-monster/fireflies-ui/fireflies-ui.c370
-rw-r--r--spaghetti-monster/fsm-adc.c244
-rw-r--r--spaghetti-monster/fsm-adc.h3
-rw-r--r--spaghetti-monster/fsm-events.c24
-rw-r--r--spaghetti-monster/fsm-events.h2
-rw-r--r--spaghetti-monster/fsm-main.c51
-rw-r--r--spaghetti-monster/fsm-misc.c52
-rw-r--r--spaghetti-monster/fsm-misc.h11
-rw-r--r--spaghetti-monster/fsm-pcint.c42
-rw-r--r--spaghetti-monster/fsm-ramping.c26
-rw-r--r--spaghetti-monster/fsm-standby.c2
-rw-r--r--spaghetti-monster/fsm-wdt.c82
-rw-r--r--spaghetti-monster/fsm-wdt.h5
-rw-r--r--spaghetti-monster/rampingios/rampingiosv3.c43
-rw-r--r--spaghetti-monster/spaghetti-monster.h1
-rw-r--r--tk-attiny.h55
42 files changed, 2366 insertions, 739 deletions
diff --git a/bin/build.sh b/bin/build.sh
index ddd2a72..192fa30 100755
--- a/bin/build.sh
+++ b/bin/build.sh
@@ -33,4 +33,6 @@ function run () {
run $CC $OTHERFLAGS $CFLAGS -o $PROGRAM.o -c $PROGRAM.c
run $CC $OFLAGS $LDFLAGS -o $PROGRAM.elf $PROGRAM.o
run $OBJCOPY $OBJCOPYFLAGS $PROGRAM.elf $PROGRAM.hex
-run avr-size -C --mcu=$MCU $PROGRAM.elf | grep Full
+# deprecated
+#run avr-size -C --mcu=$MCU $PROGRAM.elf | grep Full
+run avr-objdump -Pmem-usage $PROGRAM.elf | grep Full
diff --git a/bin/flash-tiny1634-fuses.sh b/bin/flash-tiny1634-fuses.sh
new file mode 100755
index 0000000..1bc73e1
--- /dev/null
+++ b/bin/flash-tiny1634-fuses.sh
@@ -0,0 +1,9 @@
+#/bin/sh
+# 8 MHz, 64ms boot delay, enable flashing
+# (everything else disabled)
+# Use low fuse 0xD2 for 4ms startup delay,
+# or 0xE2 for 64ms (useful on a twisty light)
+# Use high fuse 0xDE for BOD 1.8V,
+# or 0xDF for no BOD
+avrdude -c usbasp -p t1634 -u -U lfuse:w:0xe2:m -U hfuse:w:0xde:m -U efuse:w:0xff:m
+
diff --git a/bin/flash-tiny1634.sh b/bin/flash-tiny1634.sh
new file mode 100755
index 0000000..2eb9b77
--- /dev/null
+++ b/bin/flash-tiny1634.sh
@@ -0,0 +1,3 @@
+#/bin/sh
+FIRMWARE=$1
+avrdude -c usbasp -p t1634 -u -Uflash:w:$FIRMWARE
diff --git a/hwdef-Emisar_D4v2.h b/hwdef-Emisar_D4v2.h
new file mode 100644
index 0000000..0460fad
--- /dev/null
+++ b/hwdef-Emisar_D4v2.h
@@ -0,0 +1,100 @@
+#ifndef HWDEF_EMISAR_D4V2_H
+#define HWDEF_EMISAR_D4V2_H
+
+/* Emisar D4v2 driver layout (attiny1634)
+ *
+ * Pin / Name / Function
+ * 1 PA6 FET PWM (PWM1B)
+ * 2 PA5 red aux LED (PWM0B)
+ * 3 PA4 green aux LED
+ * 4 PA3 blue aux LED
+ * 5 PA2 e-switch
+ * 6 PA1 (none)
+ * 7 PA0 (none)
+ * 8 GND GND
+ * 9 VCC VCC
+ * 10 PC5 (none)
+ * 11 PC4 (none)
+ * 12 PC3 RESET
+ * 13 PC2 (none)
+ * 14 PC1 SCK
+ * 15 PC0 (none) PWM0A
+ * 16 PB3 7135 PWM (PWM1A)
+ * 17 PB2 MISO
+ * 18 PB1 MOSI
+ * 19 PB0 (none)
+ * 20 PA7 (none)
+ * ADC12 thermal sensor
+ */
+
+#ifdef ATTINY
+#undef ATTINY
+#endif
+#define ATTINY 1634
+#include <avr/io.h>
+
+#define PWM_CHANNELS 2
+
+#define SWITCH_PIN PA2 // pin 5
+#define SWITCH_PCINT PCINT2 // pin 5 pin change interrupt
+#define SWITCH_PCIE PCIE0 // PCIE0 is for PCINT[7:0]
+#define SWITCH_PCMSK PCMSK0 // PCMSK0 is for PCINT[7:0]
+#define SWITCH_PORT PINA // PINA or PINB or PINC
+
+#define PWM1_PIN PB3 // pin 16, 1x7135 PWM
+#define PWM1_LVL OCR1A // OCR1A is the output compare register for PB3
+
+#define PWM2_PIN PA6 // pin 1, FET PWM
+#define PWM2_LVL OCR1B // OCR1B is the output compare register for PB1
+
+
+#define ADC_PRSCL 0x06 // clk/64
+
+// average drop across diode on this hardware
+#ifndef VOLTAGE_FUDGE_FACTOR
+#define VOLTAGE_FUDGE_FACTOR 4 // add 0.20V (measured 0.22V)
+#endif
+
+#define TEMP_CHANNEL 0b00001111
+
+// this light has aux LEDs under the optic
+#define AUXLED_R_PIN PA5 // pin 2
+#define AUXLED_G_PIN PA4 // pin 3
+#define AUXLED_B_PIN PA3 // pin 4
+#define AUXLED_RGB_PORT PORTA // PORTA or PORTB or PORTC
+#define AUXLED_RGB_DDR DDRA // DDRA or DDRB or DDRC
+#define AUXLED_RGB_PUE PUEA // PUEA or PUEB or PUEC
+
+// with so many pins, doing this all with #ifdefs gets awkward...
+// ... so just hardcode it in each hwdef file instead
+inline void hwdef_setup() {
+ // enable output ports
+ // 7135
+ DDRB = (1 << PWM1_PIN);
+ // FET, aux R/G/B
+ DDRA = (1 << PWM2_PIN)
+ | (1 << AUXLED_R_PIN)
+ | (1 << AUXLED_G_PIN)
+ | (1 << AUXLED_B_PIN)
+ ;
+
+ // configure PWM
+ // Setup PWM. F_pwm = F_clkio / 2 / N / TOP, where N = prescale factor, TOP = top of counter
+ // pre-scale for timer: N = 1
+ TCCR1A = (0<<WGM11) | (1<<WGM10) // 8-bit (TOP=0xFF) (DS table 12-5)
+ | (1<<COM1A1) | (0<<COM1A0) // PWM 1A in normal direction (DS table 12-4)
+ | (1<<COM1B1) | (0<<COM1B0) // PWM 1B in normal direction (DS table 12-4)
+ ;
+ TCCR1B = (0<<CS12) | (0<<CS11) | (1<<CS10) // clk/1 (no prescaling) (DS table 12-6)
+ | (0<<WGM13) | (0<<WGM12) // phase-correct PWM (DS table 12-5)
+ ;
+
+ // set up e-switch
+ //PORTA = (1 << SWITCH_PIN); // TODO: configure PORTA / PORTB / PORTC?
+ PUEA = (1 << SWITCH_PIN); // pull-up for e-switch
+ SWITCH_PCMSK = (1 << SWITCH_PCINT); // enable pin change interrupt
+}
+
+#define LAYOUT_DEFINED
+
+#endif
diff --git a/hwdef-Mateminco_MF01S.h b/hwdef-Mateminco_MF01S.h
new file mode 100644
index 0000000..ab1c5bf
--- /dev/null
+++ b/hwdef-Mateminco_MF01S.h
@@ -0,0 +1,60 @@
+#ifndef HWDEF_MF01S_H
+#define HWDEF_MF01S_H
+
+/* MF01S driver layout
+ * ----
+ * Reset -|1 8|- VCC (unused)
+ * eswitch -|2 7|- Voltage divider (2S)
+ * AUX LED -|3 6|- PWM (FET)
+ * GND -|4 5|- PWM (smaller FET)
+ * ----
+ */
+
+#define PWM_CHANNELS 2
+
+#ifndef AUXLED_PIN
+#define AUXLED_PIN PB4 // pin 3
+#endif
+
+#ifndef SWITCH_PIN
+#define SWITCH_PIN PB3 // pin 2
+#define SWITCH_PCINT PCINT3 // pin 2 pin change interrupt
+#endif
+
+#ifndef PWM1_PIN
+#define PWM1_PIN PB0 // pin 5, 1x7135 PWM
+#define PWM1_LVL OCR0A // OCR0A is the output compare register for PB0
+#endif
+#ifndef PWM2_PIN
+#define PWM2_PIN PB1 // pin 6, FET PWM
+#define PWM2_LVL OCR0B // OCR0B is the output compare register for PB1
+#endif
+
+#define USE_VOLTAGE_DIVIDER // use a voltage divider on pin 7, not VCC
+#ifndef VOLTAGE_PIN
+#define VOLTAGE_PIN PB2 // pin 7, voltage ADC
+#define VOLTAGE_CHANNEL 0x01 // MUX 01 corresponds with PB2
+#define VOLTAGE_ADC_DIDR ADC1D // Digital input disable bit corresponding with PB2
+// 1.1V reference, left-adjust, ADC1/PB2
+//#define ADMUX_VOLTAGE_DIVIDER ((1 << V_REF) | (1 << ADLAR) | VOLTAGE_CHANNEL)
+// 1.1V reference, no left-adjust, ADC1/PB2
+#define ADMUX_VOLTAGE_DIVIDER ((1 << V_REF) | VOLTAGE_CHANNEL)
+#endif
+#define ADC_PRSCL 0x06 // clk/64
+
+// Raw ADC readings at 4.4V and 2.2V (in-between, we assume values form a straight line)
+#ifndef ADC_44
+#define ADC_44 234
+#endif
+#ifndef ADC_22
+#define ADC_22 117
+#endif
+
+#define TEMP_CHANNEL 0b00001111
+
+#define FAST 0xA3 // fast PWM both channels
+#define PHASE 0xA1 // phase-correct PWM both channels
+
+#define LAYOUT_DEFINED
+
+#endif
diff --git a/spaghetti-monster/anduril/anduril-manual.txt b/spaghetti-monster/anduril/anduril-manual.txt
index 96640f6..3f17f41 100644
--- a/spaghetti-monster/anduril/anduril-manual.txt
+++ b/spaghetti-monster/anduril/anduril-manual.txt
@@ -56,6 +56,13 @@ While the light is on, a few basic actions are available:
- Click, hold: Change brightness (down).
- 3 clicks: Switch to the other ramp.
- 4 clicks: Go to ramp config mode.
+ - 5 clicks: Activate manual memory and save the current brightness.
+ - 5 clicks, but hold the last click: Go back to automatic memory.
+
+The "automatic" vs "manual" memory modes change the level the light goes
+to with 1 click from off. In automatic mode, it uses the last
+brightness the user ramped to. In manual mode, it uses the brightness
+the user explicitly saved with 5 clicks.
Other Modes
@@ -215,7 +222,10 @@ then return to the regular "off" mode.
Lockout mode also doubles as a momentary moon mode, so the user can do
quick tasks without having to unlock the light. The brightness in
-lockout mode is determined by the floor setting of the current ramp.
+lockout mode has two levels:
+
+ - Hold: light up at the floor level of the current ramp.
+ - Click, Hold: light up at the floor level of the other ramp.
Momentary Mode
@@ -223,11 +233,23 @@ Momentary Mode
Click 5 times from Off to enter Momentary mode. This locks the
flashlight into a single-mode interface where the LEDs are only on when
-the button is held down. It is intended for Morse code and other
-signalling tasks.
+the button is held down. It is intended for Morse code, light painting,
+and other tasks where the light should be on only for a short time and
+probably in a pattern.
+
+Momentary mode does either a steady brightness level or a strobe. To
+select which one, go to the mode you want to use, adjust the brightness
+and speed and other settings, then turn the light off. Then click 5
+times to enter momentary mode.
+
+Supported momentary modes are steady (normal ramping mode) and strobes
+(everything in the "strobe" mode group).
-Brightness is the last-ramped level, so adjust that before entering
-momentary mode.
+In steady mode, brightness is the last-ramped level, so adjust that
+before entering momentary mode.
+
+In momentary strobe mode, the settings are copied from the last-used
+strobe mode, such as party strobe, tactical strobe, or lightning.
To exit this mode, physically disconnect power by unscrewing the tailcap
or battery tube.
@@ -352,6 +374,13 @@ click the button a few times:
This should change the aux LEDs to the next mode supported on this
light.
+If the aux LEDs can change color, there are additional actions to change
+the color. It is the same as above, but hold the button on the last
+click and then let go when the desired color is reached.
+
+ - Off mode: 7 clicks, but hold the last click.
+ - Lockout mode: 3 clicks, but hold the last click.
+
For lights with a button LED, the button LED typically stays on while
the main emitters are on. Its brightness level is set in a way which
mirrors the main LED -- off, low, or high.
diff --git a/spaghetti-monster/anduril/anduril-ui.png b/spaghetti-monster/anduril/anduril-ui.png
index b778a30..3c032bc 100644
--- a/spaghetti-monster/anduril/anduril-ui.png
+++ b/spaghetti-monster/anduril/anduril-ui.png
Binary files differ
diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c
index 5878d47..8ab66f5 100644
--- a/spaghetti-monster/anduril/anduril.c
+++ b/spaghetti-monster/anduril/anduril.c
@@ -28,10 +28,18 @@
#define USE_THERMAL_REGULATION
#define DEFAULT_THERM_CEIL 45 // try not to get hotter than this
+#define USE_FACTORY_RESET
+//#define USE_SOFT_FACTORY_RESET // only needed on models which can't use hold-button-at-boot
+
+// dual-switch support (second switch is a tail clicky)
+// (currently incompatible with factory reset)
+//#define START_AT_MEMORIZED_LEVEL
+
+
// short blip when crossing from "click" to "hold" from off
// (helps the user hit moon mode exactly, instead of holding too long
// or too short)
-#define MOON_TIMING_HINT
+#define MOON_TIMING_HINT // only applies if B_TIMING_ON == B_PRESS_T
// short blips while ramping
#define BLINK_AT_RAMP_MIDDLE
//#define BLINK_AT_RAMP_FLOOR
@@ -42,6 +50,13 @@
// ("hold, release, hold" ramps down instead of up)
#define USE_REVERSING
+// add a runtime option to switch between automatic memory (default)
+// and manual memory (only available if compiled in)
+// (manual memory makes 1-click-from-off start at the same level each time)
+// (the level can be set explicitly with 5 clicks from on,
+// or the user can go back to automatic with click-click-click-click-hold)
+#define USE_MANUAL_MEMORY
+
// battery readout style (pick one)
#define BATTCHECK_VpT
//#define BATTCHECK_8bars // FIXME: breaks build
@@ -74,9 +89,6 @@
//#define USE_POLICE_STROBE_MODE
//#define USE_SOS_MODE
-// dual-switch support (second switch is a tail clicky)
-//#define START_AT_MEMORIZED_LEVEL
-
/***** specific settings for known driver types *****/
#include "tk.h"
#include incfile(CONFIGFILE)
@@ -120,11 +132,13 @@
// full FET strobe can be a bit much... use max regulated level instead,
// if there's a bright enough regulated level
+#ifndef STROBE_BRIGHTNESS
#ifdef MAX_Nx7135
#define STROBE_BRIGHTNESS MAX_Nx7135
#else
#define STROBE_BRIGHTNESS MAX_LEVEL
#endif
+#endif
#if defined(USE_CANDLE_MODE) || defined(USE_BIKE_FLASHER_MODE) || defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE) || defined(USE_LIGHTNING_MODE)
#define USE_STROBE_STATE
@@ -145,6 +159,9 @@ typedef enum {
ramp_discrete_ceil_e,
ramp_discrete_steps_e,
#endif
+ #ifdef USE_MANUAL_MEMORY
+ manual_memory_e,
+ #endif
#ifdef USE_TINT_RAMPING
tint_e,
#endif
@@ -171,6 +188,10 @@ typedef enum {
#ifdef USE_INDICATOR_LED
indicator_led_mode_e,
#endif
+ #ifdef USE_AUX_RGB_LEDS
+ rgb_led_off_mode_e,
+ rgb_led_lockout_mode_e,
+ #endif
eeprom_indexes_e_END
} eeprom_indexes_e;
#define EEPROM_BYTES eeprom_indexes_e_END
@@ -191,9 +212,31 @@ typedef enum {
#endif
#endif
+#ifdef USE_SOFT_FACTORY_RESET
+#define USE_REBOOT
+#endif
+
#include "spaghetti-monster.h"
+// configure the timing of turning on/off in regular ramp mode
+// press: react as soon as the button is pressed
+#define B_PRESS_T 0
+// release: react as soon as the button is released
+#define B_RELEASE_T 1
+// timeout: react as soon as we're sure the user isn't doing a double-click
+#define B_TIMEOUT_T 2
+// defaults are release on, timeout off
+#ifndef B_TIMING_ON
+//#define B_TIMING_ON B_PRESS_T
+#define B_TIMING_ON B_RELEASE_T
+#endif
+#ifndef B_TIMING_OFF
+//#define B_TIMING_OFF B_RELEASE_T
+#define B_TIMING_OFF B_TIMEOUT_T
+#endif
+
+
// FSM states
uint8_t off_state(Event event, uint16_t arg);
// simple numeric entry config menu
@@ -240,10 +283,12 @@ uint8_t beacon_config_state(Event event, uint16_t arg);
// soft lockout
#define MOON_DURING_LOCKOUT_MODE
// if enabled, 2nd lockout click goes to the other ramp's floor level
-//#define LOCKOUT_MOON_FANCY
+#define LOCKOUT_MOON_FANCY
uint8_t lockout_state(Event event, uint16_t arg);
// momentary / signalling mode
uint8_t momentary_state(Event event, uint16_t arg);
+uint8_t momentary_mode = 0; // 0 = ramping, 1 = strobe
+uint8_t momentary_active = 0; // boolean, true if active *right now*
#ifdef USE_MUGGLE_MODE
// muggle mode, super-simple, hard to exit
uint8_t muggle_state(Event event, uint16_t arg);
@@ -260,6 +305,35 @@ void blip();
#if defined(USE_INDICATOR_LED) && defined(TICK_DURING_STANDBY)
void indicator_blink(uint8_t arg);
#endif
+#if defined(USE_AUX_RGB_LEDS) && defined(TICK_DURING_STANDBY)
+void rgb_led_update(uint8_t mode, uint8_t arg);
+/*
+ * 0: R
+ * 1: RG
+ * 2: G
+ * 3: GB
+ * 4: B
+ * 5: R B
+ * 6: RGB
+ * 7: rainbow
+ * 8: voltage
+ */
+#define RGB_LED_NUM_COLORS 10
+#define RGB_LED_NUM_PATTERNS 4
+#ifndef RGB_LED_OFF_DEFAULT
+//#define RGB_LED_OFF_DEFAULT 0x18 // low, voltage
+#define RGB_LED_OFF_DEFAULT 0x17 // low, rainbow
+#endif
+#ifndef RGB_LED_LOCKOUT_DEFAULT
+#define RGB_LED_LOCKOUT_DEFAULT 0x37 // blinking, rainbow
+#endif
+uint8_t rgb_led_off_mode = RGB_LED_OFF_DEFAULT;
+uint8_t rgb_led_lockout_mode = RGB_LED_LOCKOUT_DEFAULT;
+#endif
+
+#ifdef USE_FACTORY_RESET
+void factory_reset();
+#endif
// remember stuff even after battery was changed
void load_config();
@@ -314,6 +388,9 @@ void save_config_wl();
#define DEFAULT_LEVEL MAX_1x7135
#endif
uint8_t memorized_level = DEFAULT_LEVEL;
+#ifdef USE_MANUAL_MEMORY
+uint8_t manual_memory = 0;
+#endif
// smooth vs discrete ramping
volatile uint8_t ramp_style = RAMP_STYLE; // 0 = smooth, 1 = discrete
volatile uint8_t ramp_smooth_floor = RAMP_SMOOTH_FLOOR;
@@ -347,6 +424,9 @@ uint8_t nearest_level(int16_t target);
#ifdef USE_THERMAL_REGULATION
// brightness before thermal step-down
uint8_t target_level = 0;
+void set_level_and_therm_target(uint8_t level);
+#else
+#define set_level_and_therm_target(level) set_level(level)
#endif
// internal numbering for strobe modes
@@ -410,43 +490,58 @@ uint8_t off_state(Event event, uint16_t arg) {
set_level(0);
#ifdef USE_INDICATOR_LED
indicator_led(indicator_led_mode & 0x03);
+ #elif defined(USE_AUX_RGB_LEDS)
+ rgb_led_update(rgb_led_off_mode, 0);
#endif
// sleep while off (lower power use)
- go_to_standby = 1;
+ // (unless delay requested; give the ADC some time to catch up)
+ if (! arg) { go_to_standby = 1; }
return MISCHIEF_MANAGED;
}
// go back to sleep eventually if we got bumped but didn't leave "off" state
else if (event == EV_tick) {
- if (arg > TICKS_PER_SECOND*2) {
+ if (arg > HOLD_TIMEOUT) {
go_to_standby = 1;
#ifdef USE_INDICATOR_LED
indicator_led(indicator_led_mode & 0x03);
+ #elif defined(USE_AUX_RGB_LEDS)
+ rgb_led_update(rgb_led_off_mode, arg);
#endif
}
return MISCHIEF_MANAGED;
}
- #if defined(TICK_DURING_STANDBY) && defined(USE_INDICATOR_LED)
+ #if defined(TICK_DURING_STANDBY) && (defined(USE_INDICATOR_LED) || defined(USE_AUX_RGB_LEDS))
// blink the indicator LED, maybe
else if (event == EV_sleep_tick) {
+ #ifdef USE_INDICATOR_LED
if ((indicator_led_mode & 0b00000011) == 0b00000011) {
indicator_blink(arg);
}
+ #elif defined(USE_AUX_RGB_LEDS)
+ rgb_led_update(rgb_led_off_mode, arg);
+ #endif
return MISCHIEF_MANAGED;
}
#endif
+ #if (B_TIMING_ON == B_PRESS_T)
// hold (initially): go to lowest level (floor), but allow abort for regular click
else if (event == EV_click1_press) {
set_level(nearest_level(1));
return MISCHIEF_MANAGED;
}
+ #endif // B_TIMING_ON == B_PRESS_T
// hold: go to lowest level
else if (event == EV_click1_hold) {
+ #if (B_TIMING_ON == B_PRESS_T)
#ifdef MOON_TIMING_HINT
if (arg == 0) {
// let the user know they can let go now to stay at moon
blip();
} else
#endif
+ #else // B_RELEASE_T or B_TIMEOUT_T
+ set_level(nearest_level(1));
+ #endif
// don't start ramping immediately;
// give the user time to release at moon level
//if (arg >= HOLD_TIMEOUT) { // smaller
@@ -460,13 +555,25 @@ uint8_t off_state(Event event, uint16_t arg) {
set_state(steady_state, 1);
return MISCHIEF_MANAGED;
}
+ #if (B_TIMING_ON != B_TIMEOUT_T)
// 1 click (before timeout): go to memorized level, but allow abort for double click
else if (event == EV_click1_release) {
+ #ifdef USE_MANUAL_MEMORY
+ if (manual_memory)
+ set_level(nearest_level(manual_memory));
+ else
+ #endif
set_level(nearest_level(memorized_level));
return MISCHIEF_MANAGED;
}
+ #endif // if (B_TIMING_ON != B_TIMEOUT_T)
// 1 click: regular mode
else if (event == EV_1click) {
+ #ifdef USE_MANUAL_MEMORY
+ if (manual_memory)
+ set_state(steady_state, manual_memory);
+ else
+ #endif
set_state(steady_state, memorized_level);
return MISCHIEF_MANAGED;
}
@@ -541,7 +648,33 @@ uint8_t off_state(Event event, uint16_t arg) {
save_config();
return MISCHIEF_MANAGED;
}
- #endif
+ #elif defined(USE_AUX_RGB_LEDS)
+ // 7 clicks: change RGB aux LED pattern
+ else if (event == EV_7clicks) {
+ uint8_t mode = (rgb_led_off_mode >> 4) + 1;
+ mode = mode % RGB_LED_NUM_PATTERNS;
+ rgb_led_off_mode = (mode << 4) | (rgb_led_off_mode & 0x0f);
+ rgb_led_update(rgb_led_off_mode, 0);
+ save_config();
+ blink_confirm(1);
+ return MISCHIEF_MANAGED;
+ }
+ // 7 clicks (hold last): change RGB aux LED color
+ else if (event == EV_click7_hold) {
+ if (0 == (arg & 0x3f)) {
+ uint8_t mode = (rgb_led_off_mode & 0x0f) + 1;
+ mode = mode % RGB_LED_NUM_COLORS;
+ rgb_led_off_mode = mode | (rgb_led_off_mode & 0xf0);
+ //save_config();
+ }
+ rgb_led_update(rgb_led_off_mode, arg);
+ return MISCHIEF_MANAGED;
+ }
+ else if (event == EV_click7_hold_release) {
+ save_config();
+ return MISCHIEF_MANAGED;
+ }
+ #endif // end 7 clicks
#ifdef USE_TENCLICK_THERMAL_CONFIG
// 10 clicks: thermal config mode
else if (event == EV_10clicks) {
@@ -549,6 +682,13 @@ uint8_t off_state(Event event, uint16_t arg) {
return MISCHIEF_MANAGED;
}
#endif
+ #if defined(USE_FACTORY_RESET) && defined(USE_SOFT_FACTORY_RESET)
+ // 13 clicks and hold the last click: invoke factory reset (reboot)
+ else if (event == EV_click13_hold) {
+ reboot();
+ return MISCHIEF_MANAGED;
+ }
+ #endif
return EVENT_NOT_HANDLED;
}
@@ -560,6 +700,11 @@ uint8_t steady_state(Event event, uint16_t arg) {
#ifdef USE_REVERSING
static int8_t ramp_direction = 1;
#endif
+ #if (B_TIMING_OFF == B_RELEASE_T)
+ // if the user double clicks, we need to abort turning off,
+ // and this stores the level to return to
+ static uint8_t level_before_off = 0;
+ #endif
if (ramp_style) {
mode_min = ramp_discrete_floor;
mode_max = ramp_discrete_ceil;
@@ -568,6 +713,7 @@ uint8_t steady_state(Event event, uint16_t arg) {
// turn LED on when we first enter the mode
if ((event == EV_enter_state) || (event == EV_reenter_state)) {
+ momentary_mode = 0; // 0 = ramping, 1 = strobes
// if we just got back from config mode, go back to memorized level
if (event == EV_reenter_state) {
arg = memorized_level;
@@ -577,15 +723,25 @@ uint8_t steady_state(Event event, uint16_t arg) {
memorized_level = arg;
// use the requested level even if not memorized
arg = nearest_level(arg);
- #ifdef USE_THERMAL_REGULATION
- target_level = arg;
- #endif
- set_level(arg);
+ set_level_and_therm_target(arg);
#ifdef USE_REVERSING
ramp_direction = 1;
#endif
return MISCHIEF_MANAGED;
}
+ #if (B_TIMING_OFF == B_RELEASE_T)
+ // 1 click (early): off, if configured for early response
+ else if (event == EV_click1_release) {
+ level_before_off = actual_level;
+ set_level_and_therm_target(0);
+ return MISCHIEF_MANAGED;
+ }
+ // 2 clicks (early): abort turning off, if configured for early response
+ else if (event == EV_click2_press) {
+ set_level_and_therm_target(level_before_off);
+ return MISCHIEF_MANAGED;
+ }
+ #endif // if (B_TIMING_OFF == B_RELEASE_T)
// 1 click: off
else if (event == EV_1click) {
set_state(off_state, 0);
@@ -594,36 +750,24 @@ uint8_t steady_state(Event event, uint16_t arg) {
// 2 clicks: go to/from highest level
else if (event == EV_2clicks) {
if (actual_level < MAX_LEVEL) {
- #ifdef USE_THERMAL_REGULATION
- target_level = MAX_LEVEL;
- #endif
// true turbo, not the mode-specific ceiling
- set_level(MAX_LEVEL);
+ set_level_and_therm_target(MAX_LEVEL);
}
else {
- #ifdef USE_THERMAL_REGULATION
- target_level = memorized_level;
- #endif
- set_level(memorized_level);
+ set_level_and_therm_target(memorized_level);
}
return MISCHIEF_MANAGED;
}
// 3 clicks: toggle smooth vs discrete ramping
else if (event == EV_3clicks) {
ramp_style = !ramp_style;
- memorized_level = nearest_level(actual_level);
- #ifdef USE_THERMAL_REGULATION
- target_level = memorized_level;
- #ifdef USE_SET_LEVEL_GRADUALLY
- //set_level_gradually(lvl);
- #endif
- #endif
save_config();
#ifdef START_AT_MEMORIZED_LEVEL
save_config_wl();
#endif
blip();
- set_level(memorized_level);
+ memorized_level = nearest_level(actual_level);
+ set_level_and_therm_target(memorized_level);
return MISCHIEF_MANAGED;
}
#ifdef USE_RAMP_CONFIG
@@ -653,9 +797,6 @@ uint8_t steady_state(Event event, uint16_t arg) {
#else
memorized_level = nearest_level((int16_t)actual_level + ramp_step_size);
#endif
- #ifdef USE_THERMAL_REGULATION
- target_level = memorized_level;
- #endif
#if defined(BLINK_AT_RAMP_CEILING) || defined(BLINK_AT_RAMP_MIDDLE)
// only blink once for each threshold
if ((memorized_level != actual_level) && (
@@ -690,7 +831,7 @@ uint8_t steady_state(Event event, uint16_t arg) {
blip();
}
#endif
- set_level(memorized_level);
+ set_level_and_therm_target(memorized_level);
return MISCHIEF_MANAGED;
}
#if defined(USE_REVERSING) || defined(START_AT_MEMORIZED_LEVEL)
@@ -716,9 +857,6 @@ uint8_t steady_state(Event event, uint16_t arg) {
}
// TODO? make it ramp up instead, if already at min?
memorized_level = nearest_level((int16_t)actual_level - ramp_step_size);
- #ifdef USE_THERMAL_REGULATION
- target_level = memorized_level;
- #endif
#if defined(BLINK_AT_RAMP_FLOOR) || defined(BLINK_AT_RAMP_MIDDLE)
// only blink once for each threshold
if ((memorized_level != actual_level) && (
@@ -750,7 +888,7 @@ uint8_t steady_state(Event event, uint16_t arg) {
blip();
}
#endif
- set_level(memorized_level);
+ set_level_and_therm_target(memorized_level);
return MISCHIEF_MANAGED;
}
#ifdef START_AT_MEMORIZED_LEVEL
@@ -760,6 +898,20 @@ uint8_t steady_state(Event event, uint16_t arg) {
return MISCHIEF_MANAGED;
}
#endif
+ #ifdef USE_MANUAL_MEMORY
+ else if (event == EV_5clicks) {
+ manual_memory = actual_level;
+ save_config();
+ blip();
+ }
+ else if (event == EV_click5_hold) {
+ if (0 == arg) {
+ manual_memory = 0;
+ save_config();
+ blip();
+ }
+ }
+ #endif
#if defined(USE_SET_LEVEL_GRADUALLY) || defined(USE_REVERSING)
else if (event == EV_tick) {
#ifdef USE_REVERSING
@@ -768,7 +920,10 @@ uint8_t steady_state(Event event, uint16_t arg) {
#endif
#ifdef USE_SET_LEVEL_GRADUALLY
// make thermal adjustment speed scale with magnitude
- if ((arg & 1) && (actual_level < THERM_FASTER_LEVEL)) {
+ // also, adjust slower when going up
+ if ((arg & 1) &&
+ ((actual_level < THERM_FASTER_LEVEL) ||
+ (actual_level < gradual_target))) {
return MISCHIEF_MANAGED; // adjust slower when not a high mode
}
#ifdef THERM_HARD_TURBO_DROP
@@ -786,31 +941,38 @@ uint8_t steady_state(Event event, uint16_t arg) {
uint8_t intervals[] = {248, 128, 66, 34, 17, 9, 4, 2};
uint8_t diff;
static uint8_t ticks_since_adjust = 0;
- ticks_since_adjust ++;
- if (gradual_target > actual_level) diff = gradual_target - actual_level;
- else {
+ if (gradual_target > actual_level) {
+ // rise at half speed (skip half the frames)
+ if (arg & 2) return MISCHIEF_MANAGED;
+ diff = gradual_target - actual_level;
+ } else {
diff = actual_level - gradual_target;
}
- uint8_t magnitude = 0;
- #ifndef THERM_HARD_TURBO_DROP
- // if we're on a really high mode, drop faster
- if (actual_level >= THERM_FASTER_LEVEL) { magnitude ++; }
- #endif
- while (diff) {
- magnitude ++;
- diff >>= 1;
- }
- uint8_t ticks_per_adjust = intervals[magnitude];
- if (ticks_since_adjust > ticks_per_adjust)
- {
- gradual_tick();
- ticks_since_adjust = 0;
+ ticks_since_adjust ++;
+ // if there's any adjustment to be made, make it
+ if (diff) {
+ uint8_t magnitude = 0;
+ #ifndef THERM_HARD_TURBO_DROP
+ // if we're on a really high mode, drop faster
+ if ((actual_level >= THERM_FASTER_LEVEL)
+ && (actual_level > gradual_target)) { magnitude ++; }
+ #endif
+ while (diff) {
+ magnitude ++;
+ diff >>= 1;
+ }
+ uint8_t ticks_per_adjust = intervals[magnitude];
+ if (ticks_since_adjust > ticks_per_adjust)
+ {
+ gradual_tick();
+ ticks_since_adjust = 0;
+ }
+ //if (!(arg % ticks_per_adjust)) gradual_tick();
}
- //if (!(arg % ticks_per_adjust)) gradual_tick();
#ifdef THERM_HARD_TURBO_DROP
}
#endif
- #endif
+ #endif // ifdef USE_SET_LEVEL_GRADUALLY
return MISCHIEF_MANAGED;
}
#endif
@@ -821,13 +983,14 @@ uint8_t steady_state(Event event, uint16_t arg) {
blip();
#endif
#ifdef THERM_HARD_TURBO_DROP
- if (actual_level > THERM_FASTER_LEVEL) {
+ //if (actual_level > THERM_FASTER_LEVEL) {
+ if (actual_level == MAX_LEVEL) {
#ifdef USE_SET_LEVEL_GRADUALLY
set_level_gradually(THERM_FASTER_LEVEL);
+ target_level = THERM_FASTER_LEVEL;
#else
- set_level(THERM_FASTER_LEVEL);
+ set_level_and_therm_target(THERM_FASTER_LEVEL);
#endif
- target_level = THERM_FASTER_LEVEL;
} else
#endif
if (actual_level > MIN_THERM_STEPDOWN) {
@@ -861,7 +1024,7 @@ uint8_t steady_state(Event event, uint16_t arg) {
}
return MISCHIEF_MANAGED;
}
- #endif
+ #endif // ifdef USE_THERMAL_REGULATION
return EVENT_NOT_HANDLED;
}
@@ -931,10 +1094,14 @@ uint8_t tint_ramping_state(Event event, uint16_t arg) {
#ifdef USE_STROBE_STATE
uint8_t strobe_state(Event event, uint16_t arg) {
+ static int8_t ramp_direction = 1;
+
// 'st' reduces ROM size by avoiding access to a volatile var
// (maybe I should just make it nonvolatile?)
strobe_mode_te st = strobe_type;
+ momentary_mode = 1; // 0 = ramping, 1 = strobes
+
#ifdef USE_CANDLE_MODE
// pass all events to candle mode, when it's active
// (the code is in its own pseudo-state to keep things cleaner)
@@ -944,11 +1111,11 @@ uint8_t strobe_state(Event event, uint16_t arg) {
#endif
if (0) {} // placeholder
- /* not used any more
+ // init anything which needs to be initialized
else if (event == EV_enter_state) {
+ ramp_direction = 1;
return MISCHIEF_MANAGED;
}
- */
// 1 click: off
else if (event == EV_1click) {
set_state(off_state, 0);
@@ -973,7 +1140,11 @@ uint8_t strobe_state(Event event, uint16_t arg) {
else if (st == party_strobe_e) {
#endif
if ((arg & 1) == 0) {
- if (strobe_delays[st] > 8) strobe_delays[st] --;
+ uint8_t d = strobe_delays[st];
+ d -= ramp_direction;
+ if (d < 8) d = 8;
+ else if (d > 254) d = 254;
+ strobe_delays[st] = d;
}
}
#endif
@@ -984,17 +1155,27 @@ uint8_t strobe_state(Event event, uint16_t arg) {
// biking mode brighter
#ifdef USE_BIKE_FLASHER_MODE
else if (st == bike_flasher_e) {
- if (bike_flasher_brightness < MAX_BIKING_LEVEL)
- bike_flasher_brightness ++;
+ bike_flasher_brightness += ramp_direction;
+ if (bike_flasher_brightness < 2) bike_flasher_brightness = 2;
+ else if (bike_flasher_brightness > MAX_BIKING_LEVEL) bike_flasher_brightness = MAX_BIKING_LEVEL;
set_level(bike_flasher_brightness);
}
#endif
return MISCHIEF_MANAGED;
}
+ // reverse ramp direction on hold release
+ // ... and save new strobe settings
+ else if (event == EV_click1_hold_release) {
+ ramp_direction = -ramp_direction;
+ save_config();
+ return MISCHIEF_MANAGED;
+ }
// click, hold: change speed (go slower)
// or change brightness (dimmer)
else if (event == EV_click2_hold) {
+ ramp_direction = 1;
+
if (0) {} // placeholder
// party / tactical strobe slower
@@ -1025,14 +1206,16 @@ uint8_t strobe_state(Event event, uint16_t arg) {
return MISCHIEF_MANAGED;
}
// release hold: save new strobe settings
- else if ((event == EV_click1_hold_release)
- || (event == EV_click2_hold_release)) {
+ else if (event == EV_click2_hold_release) {
save_config();
return MISCHIEF_MANAGED;
}
#if defined(USE_LIGHTNING_MODE) || defined(USE_CANDLE_MODE)
// clock tick: bump the random seed
else if (event == EV_tick) {
+ // un-reverse after 1 second
+ if (arg == TICKS_PER_SECOND) ramp_direction = 1;
+
pseudo_rand_seed += arg;
return MISCHIEF_MANAGED;
}
@@ -1129,6 +1312,7 @@ inline void bike_flasher_iter() {
#ifdef USE_CANDLE_MODE
uint8_t candle_mode_state(Event event, uint16_t arg) {
+ static int8_t ramp_direction = 1;
#define MAX_CANDLE_LEVEL (RAMP_LENGTH-CANDLE_AMPLITUDE-15)
static uint8_t candle_wave1 = 0;
static uint8_t candle_wave2 = 0;
@@ -1148,6 +1332,7 @@ uint8_t candle_mode_state(Event event, uint16_t arg) {
if (event == EV_enter_state) {
candle_mode_timer = 0; // in case any time was left over from earlier
+ ramp_direction = 1;
return MISCHIEF_MANAGED;
}
// 2 clicks: cancel timer
@@ -1159,12 +1344,25 @@ uint8_t candle_mode_state(Event event, uint16_t arg) {
}
// hold: change brightness (brighter)
else if (event == EV_click1_hold) {
- if (candle_mode_brightness < MAX_CANDLE_LEVEL)
- candle_mode_brightness ++;
+ // ramp away from extremes
+ if (! arg) {
+ if (candle_mode_brightness >= MAX_CANDLE_LEVEL) { ramp_direction = -1; }
+ else if (candle_mode_brightness <= 1) { ramp_direction = 1; }
+ }
+ // change brightness, but not too far
+ candle_mode_brightness += ramp_direction;
+ if (candle_mode_brightness < 1) candle_mode_brightness = 1;
+ else if (candle_mode_brightness > MAX_CANDLE_LEVEL) candle_mode_brightness = MAX_CANDLE_LEVEL;
+ return MISCHIEF_MANAGED;
+ }
+ // reverse ramp direction on hold release
+ else if (event == EV_click1_hold_release) {
+ ramp_direction = -ramp_direction;
return MISCHIEF_MANAGED;
}
// click, hold: change brightness (dimmer)
else if (event == EV_click2_hold) {
+ ramp_direction = 1;
if (candle_mode_brightness > 1)
candle_mode_brightness --;
return MISCHIEF_MANAGED;
@@ -1182,6 +1380,9 @@ uint8_t candle_mode_state(Event event, uint16_t arg) {
}
// clock tick: animate candle brightness
else if (event == EV_tick) {
+ // un-reverse after 1 second
+ if (arg == TICKS_PER_SECOND) ramp_direction = 1;
+
// self-timer dims the light during the final minute
uint8_t subtract = 0;
if (candle_mode_timer == 1) {
@@ -1426,6 +1627,10 @@ uint8_t lockout_state(Event event, uint16_t arg) {
#ifdef MOON_DURING_LOCKOUT_MODE
// momentary(ish) moon mode during lockout
// button is being held
+ #ifdef USE_AUX_RGB_LEDS
+ // don't turn on during RGB aux LED configuration
+ if (event == EV_click3_hold) { set_level(0); } else
+ #endif
if ((event & (B_CLICK | B_PRESS)) == (B_CLICK | B_PRESS)) {
#ifdef LOCKOUT_MOON_LOWEST
// Use lowest moon configured
@@ -1459,75 +1664,82 @@ uint8_t lockout_state(Event event, uint16_t arg) {
if (event == EV_enter_state) {
indicator_led(indicator_led_mode >> 2);
} else
+ #elif defined(USE_AUX_RGB_LEDS)
+ if (event == EV_enter_state) {
+ rgb_led_update(rgb_led_lockout_mode, 0);
+ } else
#endif
if (event == EV_tick) {
- if (arg > TICKS_PER_SECOND*2) {
+ if (arg > HOLD_TIMEOUT) {
go_to_standby = 1;
#ifdef USE_INDICATOR_LED
indicator_led(indicator_led_mode >> 2);
+ #elif defined(USE_AUX_RGB_LEDS)
+ rgb_led_update(rgb_led_lockout_mode, arg);
#endif
}
return MISCHIEF_MANAGED;
}
- #if defined(TICK_DURING_STANDBY) && defined(USE_INDICATOR_LED)
+ #if defined(TICK_DURING_STANDBY) && (defined(USE_INDICATOR_LED) || defined(USE_AUX_RGB_LEDS))
else if (event == EV_sleep_tick) {
+ #if defined(USE_INDICATOR_LED)
if ((indicator_led_mode & 0b00001100) == 0b00001100) {
indicator_blink(arg);
}
+ #elif defined(USE_AUX_RGB_LEDS)
+ rgb_led_update(rgb_led_lockout_mode, arg);
+ #endif
return MISCHIEF_MANAGED;
}
#endif
- #ifdef USE_INDICATOR_LED
+ #if defined(USE_INDICATOR_LED)
// 3 clicks: rotate through indicator LED modes (lockout mode)
else if (event == EV_3clicks) {
- uint8_t mode = indicator_led_mode >> 2;
- #ifdef TICK_DURING_STANDBY
- mode = (mode + 1) & 3;
- #else
- mode = (mode + 1) % 3;
- #endif
- #ifdef INDICATOR_LED_SKIP_LOW
- if (mode == 1) { mode ++; }
+ #if defined(USE_INDICATOR_LED)
+ uint8_t mode = indicator_led_mode >> 2;
+ #ifdef TICK_DURING_STANDBY
+ mode = (mode + 1) & 3;
+ #else
+ mode = (mode + 1) % 3;
+ #endif
+ #ifdef INDICATOR_LED_SKIP_LOW
+ if (mode == 1) { mode ++; }
+ #endif
+ indicator_led_mode = (mode << 2) + (indicator_led_mode & 0x03);
+ indicator_led(mode);
+ #elif defined(USE_AUX_RGB_LEDS)
#endif
- indicator_led_mode = (mode << 2) + (indicator_led_mode & 0x03);
- indicator_led(mode);
save_config();
return MISCHIEF_MANAGED;
}
- #if 0 // old method, deprecated in favor of "7 clicks from off"
- // click, click, hold: rotate through indicator LED modes (off mode)
+ #elif defined(USE_AUX_RGB_LEDS)
+ // 3 clicks: change RGB aux LED pattern
+ else if (event == EV_3clicks) {
+ uint8_t mode = (rgb_led_lockout_mode >> 4) + 1;
+ mode = mode % RGB_LED_NUM_PATTERNS;
+ rgb_led_lockout_mode = (mode << 4) | (rgb_led_lockout_mode & 0x0f);
+ rgb_led_update(rgb_led_lockout_mode, 0);
+ save_config();
+ blink_confirm(1);
+ return MISCHIEF_MANAGED;
+ }
+ // click, click, hold: change RGB aux LED color
else if (event == EV_click3_hold) {
- #ifndef USE_INDICATOR_LED_WHILE_RAMPING
- // if main LED obscures aux LEDs, turn it off
- set_level(0);
- #endif
- #ifdef TICK_DURING_STANDBY
- uint8_t mode = (arg >> 5) & 3;
- #else
- uint8_t mode = (arg >> 5) % 3;
- #endif
- #ifdef INDICATOR_LED_SKIP_LOW
- if (mode == 1) { mode ++; }
- #endif
- indicator_led_mode = (indicator_led_mode & 0b11111100) | mode;
- #ifdef TICK_DURING_STANDBY
- if (mode == 3)
- indicator_led(mode & (arg&3));
- else
- indicator_led(mode);
- #else
- indicator_led(mode);
- #endif
- //save_config();
+ if (0 == (arg & 0x3f)) {
+ uint8_t mode = (rgb_led_lockout_mode & 0x0f) + 1;
+ mode = mode % RGB_LED_NUM_COLORS;
+ rgb_led_lockout_mode = mode | (rgb_led_lockout_mode & 0xf0);
+ //save_config();
+ }
+ rgb_led_update(rgb_led_lockout_mode, arg);
return MISCHIEF_MANAGED;
}
- // click, click, hold, release: save indicator LED mode (off mode)
+ // click, click, hold, release: save new color
else if (event == EV_click3_hold_release) {
save_config();
return MISCHIEF_MANAGED;
}
#endif
- #endif
// 4 clicks: exit
else if (event == EV_4clicks) {
blink_confirm(1);
@@ -1542,14 +1754,24 @@ uint8_t lockout_state(Event event, uint16_t arg) {
uint8_t momentary_state(Event event, uint16_t arg) {
// TODO: momentary strobe here? (for light painting)
+ // init strobe mode, if relevant
+ if ((event == EV_enter_state) && (momentary_mode == 1)) {
+ strobe_state(event, arg);
+ }
+
// light up when the button is pressed; go dark otherwise
// button is being held
if ((event & (B_CLICK | B_PRESS)) == (B_CLICK | B_PRESS)) {
- set_level(memorized_level);
+ momentary_active = 1;
+ // 0 = ramping, 1 = strobes
+ if (momentary_mode == 0) {
+ set_level(memorized_level);
+ }
return MISCHIEF_MANAGED;
}
// button was released
else if ((event & (B_CLICK | B_PRESS)) == (B_CLICK)) {
+ momentary_active = 0;
set_level(0);
//go_to_standby = 1; // sleep while light is off
return MISCHIEF_MANAGED;
@@ -1560,10 +1782,18 @@ uint8_t momentary_state(Event event, uint16_t arg) {
// with exiting via tailcap loosen+tighten unless you leave power
// disconnected for several seconds, so we want to be awake when that
// happens to speed up the process)
- else if ((event == EV_tick) && (actual_level == 0)) {
- if (arg > TICKS_PER_SECOND*15) { // sleep after 15 seconds
- go_to_standby = 1; // sleep while light is off
- // TODO: lighted button should use lockout config?
+ else if (event == EV_tick) {
+ if (momentary_active) {
+ // 0 = ramping, 1 = strobes
+ if (momentary_mode == 1) {
+ return strobe_state(event, arg);
+ }
+ }
+ else {
+ if (arg > TICKS_PER_SECOND*15) { // sleep after 15 seconds
+ go_to_standby = 1; // sleep while light is off
+ // TODO: lighted button should use lockout config?
+ }
}
return MISCHIEF_MANAGED;
}
@@ -1697,12 +1927,16 @@ uint8_t muggle_state(Event event, uint16_t arg) {
#ifdef USE_THERMAL_REGULATION
// overheating is handled specially in muggle mode
else if(event == EV_temperature_high) {
- // don't even try...
- // go immediately to the bottom, in case someone put the light on
- // maximum while wrapped in dark-colored flammable insulation
- // or something, because muggles are cool like that
- // memorized_level = MUGGLE_FLOOR; // override memory? maybe not
- set_level(MUGGLE_FLOOR);
+ #if 0
+ blip();
+ #endif
+ // ignore warnings while off
+ if (! muggle_off_mode) {
+ // step down proportional to the amount of overheating
+ int16_t new = actual_level - arg;
+ if (new < MUGGLE_FLOOR) { new = MUGGLE_FLOOR; }
+ set_level(new);
+ }
return MISCHIEF_MANAGED;
}
#endif
@@ -1800,14 +2034,15 @@ void thermal_config_save() {
// calibrate room temperature
val = config_state_values[0];
if (val) {
- int8_t rawtemp = (temperature >> 1) - therm_cal_offset;
+ int8_t rawtemp = temperature - therm_cal_offset;
therm_cal_offset = val - rawtemp;
+ reset_thermal_history = 1; // invalidate all recent temperature data
}
val = config_state_values[1];
if (val) {
// set maximum heat limit
- therm_ceil = 30 + val;
+ therm_ceil = 30 + val - 1;
}
if (therm_ceil > MAX_THERM_CEIL) therm_ceil = MAX_THERM_CEIL;
}
@@ -1960,6 +2195,12 @@ uint8_t nearest_level(int16_t target) {
return this_level;
}
+#ifdef USE_THERMAL_REGULATION
+void set_level_and_therm_target(uint8_t level) {
+ target_level = level;
+ set_level(level);
+}
+#endif
void blink_confirm(uint8_t num) {
for (; num>0; num--) {
@@ -1982,6 +2223,9 @@ void blip() {
#if defined(USE_INDICATOR_LED) && defined(TICK_DURING_STANDBY)
// beacon-like mode for the indicator LED
void indicator_blink(uint8_t arg) {
+ // turn off aux LEDs when battery is empty
+ if (voltage < VOLTAGE_LOW) { indicator_led(0); return; }
+
#ifdef USE_FANCIER_BLINKING_INDICATOR
// fancy blink, set off/low/high levels here:
@@ -2002,6 +2246,130 @@ void indicator_blink(uint8_t arg) {
}
#endif
+#if defined(USE_AUX_RGB_LEDS) && defined(TICK_DURING_STANDBY)
+// do fancy stuff with the RGB aux LEDs
+// mode: 0bPPPPCCCC where PPPP is the pattern and CCCC is the color
+// arg: time slice number
+void rgb_led_update(uint8_t mode, uint8_t arg) {
+ static uint8_t rainbow = 0; // track state of rainbow mode
+ static uint8_t frame = 0; // track state of animation mode
+
+ // turn off aux LEDs when battery is empty
+ // (but if voltage==0, that means we just booted and don't know yet)
+ uint8_t volts = voltage; // save a few bytes by caching volatile value
+ if ((volts) && (volts < VOLTAGE_LOW)) { rgb_led_set(0); return; }
+
+ uint8_t pattern = (mode>>4); // off, low, high, blinking, ... more?
+ uint8_t color = mode & 0x0f;
+
+ // preview in blinking mode is awkward... use high instead
+ if ((! go_to_standby) && (pattern > 2)) { pattern = 2; }
+
+
+ uint8_t colors[] = {
+ 0b00000001, // 0: red
+ 0b00000101, // 1: yellow
+ 0b00000100, // 2: green
+ 0b00010100, // 3: cyan
+ 0b00010000, // 4: blue
+ 0b00010001, // 5: purple
+ 0b00010101, // 6: white
+ };
+ uint8_t actual_color = 0;
+ if (color < 7) { // normal color
+ actual_color = colors[color];
+ }
+ else if (color == 7) { // rainbow
+ if (0 == (arg & 0x03)) {
+ rainbow = (rainbow + 1) % 6;
+ }
+ actual_color = colors[rainbow];
+ }
+ else { // voltage
+ // show actual voltage while asleep...
+ if (go_to_standby) {
+ // choose a color based on battery voltage
+ if (volts >= 38) actual_color = colors[4];
+ else if (volts >= 33) actual_color = colors[2];
+ else actual_color = colors[0];
+ }
+ // ... but during preview, cycle colors quickly
+ else {
+ actual_color = colors[((arg>>1) % 3) << 1];
+ }
+ }
+
+ // pick a brightness from the animation sequence
+ if (pattern == 3) {
+ // uses an odd length to avoid lining up with rainbow loop
+ uint8_t animation[] = {2, 1, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1};
+ frame = (frame + 1) % sizeof(animation);
+ pattern = animation[frame];
+ }
+ switch (pattern) {
+ case 0: // off
+ rgb_led_set(0);
+ break;
+ case 1: // low
+ rgb_led_set(actual_color);
+ break;
+ case 2: // high
+ rgb_led_set(actual_color << 1);
+ break;
+ }
+}
+#endif
+
+
+#ifdef USE_FACTORY_RESET
+void factory_reset() {
+ // display a warning for a few seconds before doing the actual reset,
+ // so the user has time to abort if they want
+ #define SPLODEY_TIME 3000
+ #define SPLODEY_STEPS 64
+ #define SPLODEY_TIME_PER_STEP (SPLODEY_TIME/SPLODEY_STEPS)
+ uint8_t bright;
+ uint8_t reset = 1;
+ // wind up to an explosion
+ for (bright=0; bright<SPLODEY_STEPS; bright++) {
+ set_level(bright);
+ delay_4ms(SPLODEY_TIME_PER_STEP/2/4);
+ set_level(bright>>1);
+ delay_4ms(SPLODEY_TIME_PER_STEP/2/4);
+ if (! button_is_pressed()) {
+ reset = 0;
+ break;
+ }
+ }
+ // explode, if button pressed long enough
+ if (reset) {
+ #ifdef USE_THERMAL_REGULATION
+ // auto-calibrate temperature... assume current temperature is 21 C
+ config_state_values[0] = 21;
+ config_state_values[1] = 0;
+ thermal_config_save();
+ #endif
+ // save all settings to eeprom
+ // (assuming they're all at default because we haven't loaded them yet)
+ save_config();
+
+ bright = MAX_LEVEL;
+ for (; bright > 0; bright--) {
+ set_level(bright);
+ delay_4ms(SPLODEY_TIME_PER_STEP/6/4);
+ }
+ }
+ // explosion cancelled, fade away
+ else {
+ for (; bright > 0; bright--) {
+ set_level(bright);
+ delay_4ms(SPLODEY_TIME_PER_STEP/3/4);
+ }
+ }
+}
+#endif
+
void load_config() {
if (load_eeprom()) {
@@ -2013,6 +2381,9 @@ void load_config() {
ramp_discrete_ceil = eeprom[ramp_discrete_ceil_e];
ramp_discrete_steps = eeprom[ramp_discrete_steps_e];
#endif
+ #ifdef USE_MANUAL_MEMORY
+ manual_memory = eeprom[manual_memory_e];
+ #endif
#ifdef USE_TINT_RAMPING
tint = eeprom[tint_e];
#endif
@@ -2037,6 +2408,10 @@ void load_config() {
#ifdef USE_INDICATOR_LED
indicator_led_mode = eeprom[indicator_led_mode_e];
#endif
+ #ifdef USE_AUX_RGB_LEDS
+ rgb_led_off_mode = eeprom[rgb_led_off_mode_e];
+ rgb_led_lockout_mode = eeprom[rgb_led_lockout_mode_e];
+ #endif
}
#ifdef START_AT_MEMORIZED_LEVEL
if (load_eeprom_wl()) {
@@ -2054,6 +2429,9 @@ void save_config() {
eeprom[ramp_discrete_ceil_e] = ramp_discrete_ceil;
eeprom[ramp_discrete_steps_e] = ramp_discrete_steps;
#endif
+ #ifdef USE_MANUAL_MEMORY
+ eeprom[manual_memory_e] = manual_memory;
+ #endif
#ifdef USE_TINT_RAMPING
eeprom[tint_e] = tint;
#endif
@@ -2078,6 +2456,10 @@ void save_config() {
#ifdef USE_INDICATOR_LED
eeprom[indicator_led_mode_e] = indicator_led_mode;
#endif
+ #ifdef USE_AUX_RGB_LEDS
+ eeprom[rgb_led_off_mode_e] = rgb_led_off_mode;
+ eeprom[rgb_led_lockout_mode_e] = rgb_led_lockout_mode;
+ #endif
save_eeprom();
}
@@ -2109,14 +2491,7 @@ void low_voltage() {
else if (state == steady_state) {
if (actual_level > 1) {
uint8_t lvl = (actual_level >> 1) + (actual_level >> 2);
- set_level(lvl);
- #ifdef USE_THERMAL_REGULATION
- target_level = lvl;
- #ifdef USE_SET_LEVEL_GRADUALLY
- // not needed?
- //set_level_gradually(lvl);
- #endif
- #endif
+ set_level_and_therm_target(lvl);
}
else {
set_state(off_state, 0);
@@ -2154,6 +2529,11 @@ void setup() {
delay_4ms(3);
set_level(0);
+ #ifdef USE_FACTORY_RESET
+ if (button_is_pressed())
+ factory_reset();
+ #endif
+
load_config();
#ifdef USE_TINT_RAMPING
@@ -2166,7 +2546,7 @@ void setup() {
push_state(muggle_state, (MUGGLE_FLOOR+MUGGLE_CEILING)/2);
else
#endif
- push_state(off_state, 0);
+ push_state(off_state, 1);
#endif // ifdef START_AT_MEMORIZED_LEVEL
}
@@ -2179,7 +2559,8 @@ void loop() {
if (0) {}
#ifdef USE_STROBE_STATE
- else if (state == strobe_state) {
+ else if ((state == strobe_state)
+ || ((state == momentary_state) && (momentary_mode == 1) && (momentary_active)) ) { // also handle momentary strobes
uint8_t st = strobe_type;
switch(st) {
@@ -2243,7 +2624,7 @@ void loop() {
#ifdef USE_THERMAL_REGULATION
// TODO: blink out therm_ceil during thermal_config_state?
else if (state == tempcheck_state) {
- blink_num(temperature>>1);
+ blink_num(temperature);
nice_delay_ms(1000);
}
#endif
diff --git a/spaghetti-monster/anduril/anduril.svg b/spaghetti-monster/anduril/anduril.svg
index ab2926d..36840a4 100644
--- a/spaghetti-monster/anduril/anduril.svg
+++ b/spaghetti-monster/anduril/anduril.svg
@@ -12,14 +12,14 @@
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="18.056446cm"
- height="26.675991cm"
+ height="30.084438cm"
id="svg2"
version="1.1"
- inkscape:version="0.92.1 r15371"
+ inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
sodipodi:docname="anduril.svg"
inkscape:export-filename="/tmp/anduril-ui.png"
- inkscape:export-xdpi="342.78015"
- inkscape:export-ydpi="342.78015">
+ inkscape:export-xdpi="109.75774"
+ inkscape:export-ydpi="109.75774">
<defs
id="defs4">
<linearGradient
@@ -2049,17 +2049,6 @@
style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt"
inkscape:connector-curvature="0" />
</marker>
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4336"
- id="radialGradient5882-9"
- cx="-305.73798"
- cy="215.58585"
- fx="-305.73798"
- fy="215.58585"
- r="82.355362"
- gradientTransform="matrix(0.81547374,1.0752196e-8,0,0.75203116,-56.41674,53.458608)"
- gradientUnits="userSpaceOnUse" />
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
@@ -2651,6 +2640,139 @@
style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt"
inkscape:connector-curvature="0" />
</marker>
+ <marker
+ inkscape:stockid="Arrow1Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Mend-88-76"
+ style="overflow:visible">
+ <path
+ id="path3856-868-73"
+ d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath4663-1">
+ <path
+ inkscape:connector-curvature="0"
+ id="path4665-4"
+ d="m -271.05789,1210.0412 a 2.696785,2.696785 0 1 0 -4.67096,2.6968 c 5.0617,8.7665 3.23435,19.8443 -4.37646,26.5184 -7.61086,6.6741 -18.83242,7.0411 -26.8638,0.8787 -8.03135,-6.1624 -10.58122,-17.0975 -6.10408,-26.1761 4.08261,-8.2784 12.94463,-12.8563 21.88939,-11.6128 -0.88712,1.1542 -1.99278,2.1555 -3.29743,2.9254 l 20.14237,1.0263 -14.67953,-13.83 c 0.35969,1.6142 0.37477,3.2419 0.0897,4.7959 -11.69625,-2.3122 -23.64426,3.489 -28.98068,14.3099 -0.70001,1.4194 -1.26239,2.879 -1.69088,4.3574 -2.99958,10.3492 0.55726,21.7355 9.34721,28.4799 10.04564,7.7079 24.18077,7.2468 33.70064,-1.1014 9.51986,-8.3482 11.8258,-22.303 5.49454,-33.2684 z"
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7.18866682;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ </clipPath>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5876"
+ id="linearGradient26409"
+ x1="646.16797"
+ y1="875.3656"
+ x2="650.64648"
+ y2="804.4024"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.77810044,0,0,0.77810044,625.96494,284.11797)" />
+ <marker
+ inkscape:stockid="Arrow1Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Mend-88-76-8"
+ style="overflow:visible">
+ <path
+ id="path3856-868-73-5"
+ d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Mend-88-76-7"
+ style="overflow:visible">
+ <path
+ id="path3856-868-73-53"
+ d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Mend-88-76-83"
+ style="overflow:visible">
+ <path
+ id="path3856-868-73-1"
+ d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Mend-88-76-9"
+ style="overflow:visible">
+ <path
+ id="path3856-868-73-7"
+ d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Mend-88-76-9-6"
+ style="overflow:visible">
+ <path
+ id="path3856-868-73-7-4"
+ d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Mend-88-76-3"
+ style="overflow:visible">
+ <path
+ id="path3856-868-73-0"
+ d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4304"
+ id="linearGradient13243"
+ x1="1062.8518"
+ y1="400.22534"
+ x2="1257.9207"
+ y2="400.22534"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(4.1797945,-2.0898972)" />
+ <marker
+ inkscape:stockid="Arrow1Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Mend-367-6-0-0-2"
+ style="overflow:visible">
+ <path
+ id="path3856-53-1-2-2-2"
+ d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt"
+ inkscape:connector-curvature="0" />
+ </marker>
</defs>
<sodipodi:namedview
id="base"
@@ -2659,15 +2781,15 @@
borderopacity="1.0"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
- inkscape:zoom="1.2021109"
+ inkscape:zoom="1.0500861"
inkscape:cx="341.22418"
- inkscape:cy="504.11322"
+ inkscape:cy="568.52482"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
showguides="true"
gridtolerance="1"
- inkscape:window-width="2548"
+ inkscape:window-width="2389"
inkscape:window-height="1415"
inkscape:window-x="0"
inkscape:window-y="0"
@@ -2676,8 +2798,8 @@
fit-margin-left="0.5"
fit-margin-right="0.5"
fit-margin-bottom="0.5"
- units="cm"
- inkscape:snap-global="true"
+ units="px"
+ inkscape:snap-global="false"
inkscape:snap-bbox="true"
inkscape:bbox-paths="true"
inkscape:bbox-nodes="true"
@@ -2694,7 +2816,7 @@
spacingx="37.795276"
spacingy="37.795276"
originx="-1038.3034"
- originy="-33.268489" />
+ originy="95.554798" />
</sodipodi:namedview>
<metadata
id="metadata7">
@@ -2747,6 +2869,12 @@
x="-885.51392"
y="1093.7063"
style="font-size:29.33333397px;line-height:1.25;stroke-width:1.06666672">Strobes</tspan></text>
+ <path
+ style="opacity:1;fill:url(#linearGradient13243);fill-opacity:1;stroke:#060000;stroke-width:2.1329999;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:5.11920023;stroke-opacity:1;paint-order:markers fill stroke"
+ d="m 1068.0981,341.48719 118.2226,0 74.8741,113.29651 h -193.0967 z"
+ id="rect13226"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
<rect
style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect5159-4"
@@ -2775,13 +2903,12 @@
height="260.94336"
x="1301.3027"
y="480.43896" />
- <ellipse
- style="opacity:1;fill:none;fill-opacity:1;stroke:#9cb9e2;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- id="path13346"
- cx="1225.0675"
- cy="1364.3586"
- rx="153.35057"
- ry="94.775864" />
+ <path
+ style="fill:url(#linearGradient26409);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.55620086;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;opacity:0.316"
+ d="m 1132.6303,910.35848 h 17.5073 l -12.5835,21.63623 h 9.1098 l -18.3734,33.90788 5.8654,-23.97411 h -10.2792 z"
+ id="path26401"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccc" />
<rect
style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect5159-6"
@@ -2808,7 +2935,7 @@
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<rect
- style="opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.00000004;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect14693-4"
width="192.66586"
height="169.39575"
@@ -2878,7 +3005,7 @@
cy="604.77051"
cx="1593.5562"
id="path3639-4-4-9-1"
- style="fill:#ffffff;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;fill-opacity:1" />
+ style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<text
id="text3021-8-4-1-8-8-2-8"
y="612.58954"
@@ -2945,7 +3072,7 @@
style="fill:none;stroke:#ff0000;stroke-width:2.39758635;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
</g>
<path
- style="fill:none;stroke:#7777ff;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:2.13333344, 2.13333343999999991;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-09)"
+ style="fill:none;stroke:#7777ff;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:2.13333344, 2.13333344;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-09)"
d="m 1513.2522,717.92736 c 2.42,16.34201 29.9911,22.87705 72.4182,-3.30651"
id="path5213-6-8-4-9-9-8-4"
inkscape:connector-curvature="0"
@@ -2966,7 +3093,7 @@
id="tspan3023-4-0-1-9-63-8-83-9"
sodipodi:role="line">Beacon</tspan><tspan
style="font-size:18.66666603px;line-height:85.00000238%;text-align:center;text-anchor:middle;stroke-width:1.06666672"
- y="527.25836"
+ y="527.2583"
x="1639.1299"
sodipodi:role="line"
id="tspan14667">Cfg</tspan></text>
@@ -2981,113 +3108,11 @@
style="fill:none;stroke:#000000;stroke-width:2.39758635;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
</g>
<path
- style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999,2.1329999;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-09-2)"
+ style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-09-2)"
d="m 1655.5374,617.2342 c 16.7016,16.23216 46.3164,-11.31808 11.0065,-81.1781"
id="path5213-6-8-4-9-9-8-4-4"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
- <path
- style="fill:none;stroke:#009d00;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-3-7-0)"
- d="m 1491.9398,1267.3605 c -8.749,-5.9434 -13.9821,-11.313 -18.6473,-30.7381"
- id="path5213-6-8-4-9-9-56-6-6-1"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc" />
- <path
- style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:12.8, 2.13333333;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-31)"
- d="m 1749.3643,1233.7512 c -0.8442,-115.2108 143.7269,-36.5944 43.4448,7.9335"
- id="path5213-6-8-4-9-9-9-4"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc" />
- <text
- xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- x="1764.0304"
- y="1209.2281"
- id="text34914"><tspan
- sodipodi:role="line"
- id="tspan34912"
- x="1764.0304"
- y="1209.2281">Faster</tspan></text>
- <path
- style="fill:none;stroke:#009d00;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:12.8, 2.13333333;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-0)"
- d="m 1750.1766,1268.1926 c -1.1407,100.5282 126.1466,39.1705 50.9442,-11.7896"
- id="path5213-6-8-4-9-9-9-29-9"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc" />
- <text
- xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#009d00;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- x="1758.0332"
- y="1294.8982"
- id="text35803"><tspan
- sodipodi:role="line"
- id="tspan35801"
- x="1758.0332"
- y="1294.8982">Slower</tspan></text>
- <path
- style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:12.8, 2.13333333;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-31-1)"
- d="m 1598.9783,1248.5227 c 0.8442,115.2108 -143.7269,36.5944 -43.4448,-7.9335"
- id="path5213-6-8-4-9-9-9-4-6"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc" />
- <text
- xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- x="1534.7776"
- y="1275.1989"
- id="text34914-9"><tspan
- sodipodi:role="line"
- id="tspan34912-3"
- x="1534.7776"
- y="1275.1989">Faster</tspan></text>
- <path
- style="fill:none;stroke:#009d00;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:12.8, 2.13333333;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-0-3)"
- d="m 1628.5433,1249.2412 c -1.1407,100.5282 126.1466,39.1704 50.9442,-11.7896"
- id="path5213-6-8-4-9-9-9-29-9-0"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc" />
- <text
- xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#009d00;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- x="1636.3998"
- y="1275.9468"
- id="text35803-5"><tspan
- sodipodi:role="line"
- id="tspan35801-6"
- x="1636.3998"
- y="1275.9468">Slower</tspan></text>
- <path
- style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:12.8, 2.13333333;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-31-1-0)"
- d="m 1526.6479,1394.4202 c 0.8442,-115.2107 -143.7269,-36.5943 -43.4448,7.9335"
- id="path5213-6-8-4-9-9-9-4-6-4"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc" />
- <text
- xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- x="1452.4137"
- y="1372.4056"
- id="text34914-9-6"><tspan
- sodipodi:role="line"
- id="tspan34912-3-2"
- x="1452.4137"
- y="1372.4056">Brighter</tspan></text>
- <path
- style="fill:none;stroke:#009d00;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:12.8, 2.13333333;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-0-3-6)"
- d="m 1558.4705,1394.4542 c -1.1407,-100.5282 126.1467,-39.1704 50.9443,11.7896"
- id="path5213-6-8-4-9-9-9-29-9-0-6"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc" />
- <text
- xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#009d00;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- x="1564.822"
- y="1377.1671"
- id="text35803-5-7"><tspan
- sodipodi:role="line"
- id="tspan35801-6-5"
- x="1564.822"
- y="1377.1671">Dimmer</tspan></text>
<rect
style="opacity:1;fill:url(#linearGradient1364-8);fill-opacity:1;stroke:#000000;stroke-width:3.20000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect1356-0"
@@ -3162,12 +3187,6 @@
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
- style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:12.8, 2.13333333;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-37-9)"
- d="m 1161.2023,305.96846 c 19.9433,0.68416 37.9411,1.8706 43.0277,22.9023 23.0349,95.24415 139.8266,163.92069 134.3257,47.65282"
- id="path5213-6-8-4-9-9-9-2-5"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="csc" />
- <path
style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-start:url(#marker7637-9);marker-end:url(#Arrow1Mend-45-1)"
d="m 1314.3007,333.29999 c -90.8252,5.74785 -43.5378,-60.02663 -137.7344,-45.56247"
id="path5213-6-8-4-9-9-6-5"
@@ -3225,8 +3244,8 @@
style="opacity:1;fill:#c0c0c0;fill-opacity:1;stroke:#040000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
</g>
<path
- style="opacity:1;fill:#c0c0c0;fill-opacity:1;stroke:#040000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:4,4;stroke-dashoffset:6.1;stroke-opacity:1"
- d="m 1319.7047,180.764 69.7795,0"
+ style="opacity:1;fill:#c0c0c0;fill-opacity:1;stroke:#040000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:4, 4;stroke-dashoffset:7.30000019;stroke-opacity:1"
+ d="m 1319.7047,180.764 h 69.7795"
id="path15687-2-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
@@ -3237,8 +3256,8 @@
inkscape:connector-curvature="0"
sodipodi:nodetypes="csc" />
<path
- style="opacity:1;fill:#c0c0c0;fill-opacity:1;stroke:#040000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:4,4;stroke-dashoffset:3.5;stroke-opacity:1"
- d="m 1319.7047,381.98134 64.5803,0"
+ style="opacity:1;fill:#c0c0c0;fill-opacity:1;stroke:#040000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:4, 4;stroke-dashoffset:0;stroke-opacity:1"
+ d="m 1319.7047,381.98134 h 64.5803"
id="path15687-9-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
@@ -3347,7 +3366,7 @@
sodipodi:role="line"
x="1444.4535"
y="854.61517"
- id="tspan58146"> (click N times for 1+Turbo-N)</tspan><tspan
+ id="tspan58146"> (click N times for Nth highest)</tspan><tspan
sodipodi:role="line"
x="1444.4535"
y="870.74847"
@@ -3377,7 +3396,7 @@
sodipodi:role="line"
x="1444.4535"
y="977.63434"
- id="tspan39625"> (click N times for 30 C + N)</tspan></text>
+ id="tspan39625"> (click N times for N + 30 C)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
@@ -3398,13 +3417,13 @@
id="tspan43995"> for N seconds per flash)</tspan></text>
<path
style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-14)"
- d="m 1361.0391,358.39365 c 26.3813,0.76852 22.4829,57.6582 -8.9055,81.08668 -31.3884,23.42848 -96.7886,5.87049 -137.724,-26.36711"
+ d="m 1012.9365,299.28188 c 26.3813,0.76852 22.4829,57.6582 -8.9055,81.08668 -31.38843,23.42848 -96.78863,5.87049 -137.72403,-26.36711"
id="path5213-6-8-4-9-9-1-42"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csc" />
<g
id="g47455"
- transform="translate(-394.62442,281.246)">
+ transform="translate(-742.72705,222.13423)">
<text
inkscape:transform-center-y="10.020862"
inkscape:transform-center-x="-5.2422885"
@@ -3454,13 +3473,13 @@
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
- style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:4.26666689, 4.26666689;stroke-dashoffset:2.13333344;stroke-opacity:1;marker-end:url(#Arrow1Mend-88)"
+ style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:4.26666689, 4.26666689;stroke-dashoffset:0.21333334;stroke-opacity:1;marker-end:url(#Arrow1Mend-88)"
d="m 1499.0847,386.36671 c 49.5295,21.01119 54.6565,-32.82142 113.6548,0"
id="path5213-6-8-4-9-9-8-3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
- style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:5.11919975;stroke-opacity:1;marker-end:url(#Arrow1Mend-88)"
+ style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:2.55959988;stroke-opacity:1;marker-end:url(#Arrow1Mend-88)"
d="m 1499.0847,431.64591 c 49.5295,21.01119 54.6565,-32.82142 113.6548,0"
id="path5213-6-8-4-9-9-1-3"
inkscape:connector-curvature="0"
@@ -3469,58 +3488,58 @@
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672"
x="1508.8501"
- y="125.85442"
+ y="130.56808"
id="text3021-8-4-1-8-6-1-5-3"><tspan
sodipodi:role="line"
id="tspan3023-4-0-1-9-6-4-1-8"
x="1508.8501"
- y="125.85442"
+ y="130.56808"
style="font-size:25.60000038px;line-height:1.25;stroke-width:1.06666672">Actions</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672"
- x="1368.1968"
+ x="1387.957"
y="205.90257"
id="text3021-8-4-1-8-6-14-2-4-0"
transform="scale(1.0975814,0.91109416)"><tspan
sodipodi:role="line"
- x="1368.1968"
+ x="1387.957"
y="205.90257"
id="tspan3613-9-4"
- style="font-size:17.06666756px;line-height:1.25;stroke-width:1.06666672">1 Fast Click</tspan></text>
+ style="font-size:17.06666756px;line-height:1.25;stroke-width:1.06666672">1 Click</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672"
- x="1400.5447"
+ x="1397.882"
y="254.90924"
id="text3021-8-4-1-8-6-14-2-4-6-7"
transform="scale(1.0975814,0.91109416)"><tspan
sodipodi:role="line"
- x="1400.5447"
+ x="1397.882"
y="254.90924"
id="tspan3613-9-8-6"
style="font-size:17.06666756px;line-height:1.25;stroke-width:1.06666672">Hold</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672"
- x="1364.4215"
- y="446.51736"
+ x="1384.182"
+ y="447.44418"
id="text3021-8-4-1-8-6-14-2-4-7-8"
transform="scale(1.0975814,0.91109416)"><tspan
sodipodi:role="line"
- x="1364.4215"
- y="446.51736"
+ x="1384.182"
+ y="447.44418"
id="tspan3613-9-7-9"
- style="font-size:17.06666756px;line-height:1.25;stroke-width:1.06666672">3 Fast Clicks</tspan></text>
+ style="font-size:17.06666756px;line-height:1.25;stroke-width:1.06666672">3 Clicks</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#7777ff;fill-opacity:1;stroke:none;stroke-width:1.06666672"
- x="1363.7708"
+ x="1363.9153"
y="497.13034"
id="text3021-8-4-1-8-6-14-2-4-1-0"
transform="scale(1.0975814,0.91109416)"><tspan
sodipodi:role="line"
- x="1363.7708"
+ x="1363.9153"
y="497.13034"
id="tspan3613-9-1-6"
style="font-size:17.06666756px;line-height:1.25;fill:#7777ff;fill-opacity:1;stroke-width:1.06666672">Other Action</tspan></text>
@@ -3546,24 +3565,24 @@
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#009d00;fill-opacity:1;stroke:none;stroke-width:1.06666672"
- x="1365.7407"
+ x="1384.207"
y="328.28253"
id="text3021-8-4-1-8-6-14-2-4-12-3"
transform="scale(1.0975814,0.91109416)"><tspan
sodipodi:role="line"
- x="1365.7407"
+ x="1384.207"
y="328.28253"
id="tspan3613-9-70-3"
- style="font-size:17.06666756px;line-height:1.25;fill:#009d00;fill-opacity:1;stroke-width:1.06666672">2 Fast Clicks</tspan></text>
+ style="font-size:17.06666756px;line-height:1.25;fill:#009d00;fill-opacity:1;stroke-width:1.06666672">2 Clicks</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#009d00;fill-opacity:1;stroke:none;stroke-width:1.06666672"
- x="1373.6346"
+ x="1372.457"
y="377.28925"
id="text3021-8-4-1-8-6-14-2-4-6-9-3"
transform="scale(1.0975814,0.91109416)"><tspan
sodipodi:role="line"
- x="1373.6346"
+ x="1372.457"
y="377.28925"
id="tspan3613-9-8-3-7"
style="font-size:17.06666756px;line-height:1.25;fill:#009d00;fill-opacity:1;stroke-width:1.06666672">Click, Hold</tspan></text>
@@ -3579,7 +3598,7 @@
sodipodi:role="line"
id="tspan6532-6">Andúril‎ UI</tspan></text>
<path
- style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:4.26666667, 4.26666667;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-5)"
+ style="fill:none;stroke:#000000;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:4.26599979,4.26599979;stroke-dashoffset:5.11919975;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-5)"
d="m 1151.6852,495.69893 c 78.9733,-34.68373 144.1831,19.3203 183.6703,76.26436"
id="path5213-6-8-4-9-9-8-3-7"
inkscape:connector-curvature="0"
@@ -3651,74 +3670,6 @@
y="1000.3971"
style="font-size:24px;line-height:1.25;stroke-width:1.06666672"
id="tspan39590-4">Beacon Cfg</tspan></text>
- <g
- transform="translate(861.28782,-266.43715)"
- id="g58162-9">
- <ellipse
- ry="29.092394"
- rx="67.643234"
- cy="838.49103"
- cx="358.68741"
- id="path3639-4-4-0"
- style="fill:#505050;fill-opacity:1;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
- <text
- id="text3021-8-4-1-8-8-20"
- y="847.32025"
- x="310.00983"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#c0c0c0;fill-opacity:1;stroke:none;stroke-width:1.06666672"
- xml:space="preserve"><tspan
- style="font-size:25.60000038px;line-height:1.25;fill:#c0c0c0;fill-opacity:1;stroke-width:1.06666672"
- y="847.32025"
- x="310.00983"
- id="tspan3023-4-0-1-9-63-1"
- sodipodi:role="line">Lockout</tspan></text>
- </g>
- <g
- id="g66511"
- transform="translate(-260.15697,-113.49087)">
- <g
- id="g58191-2"
- transform="translate(811.71389,-56.245324)">
- <path
- sodipodi:type="star"
- style="fill:url(#radialGradient5882-9);fill-opacity:1;stroke:#000000;stroke-width:3.75277472;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- id="path4327-0"
- sodipodi:sides="7"
- sodipodi:cx="-309.93027"
- sodipodi:cy="215.58585"
- sodipodi:r1="69.471764"
- sodipodi:r2="50.343449"
- sodipodi:arg1="-0.13301265"
- sodipodi:arg2="0.55675103"
- inkscape:flatsided="false"
- inkscape:rounded="0.007"
- inkscape:randomized="0"
- d="m -241.07216,206.37245 c -0.0335,0.30848 -26.02137,35.52146 -26.11771,35.81642 -0.0494,0.15121 7.5296,21.40277 7.39526,21.48795 -0.26206,0.16616 -43.99586,1.80294 -44.28653,1.91153 -0.14902,0.0557 -12.03874,19.23129 -12.1891,19.17936 -0.2933,-0.10128 -28.84056,-33.27323 -29.10669,-33.43278 -0.13644,-0.0818 -22.54165,2.57825 -22.59481,2.42832 -0.10367,-0.29247 8.03227,-43.29399 7.99108,-43.60153 -0.0211,-0.15767 -16.07025,-16.01627 -15.98616,-16.1513 0.16401,-0.26341 38.85663,-20.71348 39.0714,-20.93744 0.1101,-0.11481 2.50238,-22.5502 2.66038,-22.56865 0.3082,-0.036 40.42117,17.4647 40.73017,17.49298 0.15841,0.0145 19.19067,-12.10338 19.30361,-11.99136 0.2203,0.21851 11.54773,42.4916 11.71828,42.75082 0.0874,0.13289 21.42799,7.45753 21.41082,7.61568 z"
- transform="matrix(0.92047755,0,0,0.7899176,640.59003,565.68064)"
- inkscape:transform-center-x="-3.8589074" />
- <text
- xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672"
- x="356.44214"
- y="746.58301"
- id="text3021-8-4-1-8-7"><tspan
- sodipodi:role="line"
- x="356.44214"
- y="746.58301"
- style="font-size:16px;line-height:1.25;text-align:center;text-anchor:middle;stroke-width:1.06666672"
- id="tspan4155-3">Momentary</tspan></text>
- </g>
- <text
- id="text58230"
- y="671.82159"
- x="1127.8752"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- xml:space="preserve"><tspan
- y="671.82159"
- x="1127.8752"
- id="tspan58228"
- sodipodi:role="line">Signalling</tspan></text>
- </g>
<path
style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.133, 2.133;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-9-4-0)"
d="m 1127.941,552.67567 c 8.2381,55.86142 12.4246,16.66987 28.876,-16.227 18.1418,-36.27675 65.1509,-72.19798 76.5732,0.99224"
@@ -3803,12 +3754,6 @@
x="1186.5371"
sodipodi:role="line">/ Faster</tspan></text>
</g>
- <path
- style="fill:none;stroke:#009d00;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:12.8, 2.13333333;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-0-3-6-6)"
- d="m 1672.0601,1378.93 c -1.1407,-100.5282 126.1467,-39.1704 50.9443,11.7896"
- id="path5213-6-8-4-9-9-9-29-9-0-6-9"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc" />
<g
id="g14623"
transform="translate(-13.294351,-29.307693)">
@@ -3846,15 +3791,6 @@
x="1172.5502"
y="720.89923"
style="font-size:25.60000038px;line-height:1.25;stroke-width:1.06666672">Muggle</tspan></text>
- <ellipse
- style="fill:none;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- id="path3639-4-4-9-1-4-2-6"
- cx="880.98413"
- cy="733.48511"
- rx="67.643234"
- ry="29.092394"
- inkscape:transform-center-x="-4.2569368"
- inkscape:transform-center-y="11.351831" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:21.33333397px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672"
@@ -3868,33 +3804,6 @@
x="1158.3502"
y="648.50262"
style="font-size:21.33333397px;line-height:1.25;stroke-width:1.06666672">Momentary</tspan></text>
- <ellipse
- style="fill:none;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- id="path3639-4-4-9-1-4-2-4"
- cx="875.37408"
- cy="658.87897"
- rx="67.643234"
- ry="29.092394"
- inkscape:transform-center-x="-4.2569368"
- inkscape:transform-center-y="11.351831" />
- <path
- sodipodi:type="star"
- style="fill:url(#radialGradient5882-9-2);fill-opacity:1;stroke:#000000;stroke-width:3.75277472;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- id="path4327-0-3"
- sodipodi:sides="9"
- sodipodi:cx="-309.93027"
- sodipodi:cy="215.58585"
- sodipodi:r1="81.329819"
- sodipodi:r2="68.11689"
- sodipodi:arg1="0.026660495"
- sodipodi:arg2="0.11055917"
- inkscape:flatsided="false"
- inkscape:rounded="0.037"
- inkscape:randomized="-6.9388939e-18"
- d="m -228.62935,217.75388 c 0.12785,0.52537 -13.40141,4.84463 -13.59991,5.34758 -0.63708,1.61421 -6.04498,44.84898 -6.81448,46.40442 -0.23976,0.48464 -13.38015,-4.90306 -13.85549,-4.64537 -1.52563,0.82704 -33.45909,30.47067 -35.04838,31.16758 -0.49518,0.21714 -7.09816,-12.35655 -7.62794,-12.4647 -1.70031,-0.34709 -45.21732,1.83481 -46.88275,1.3471 -0.51891,-0.15196 2.50513,-14.02828 2.16882,-14.45166 -1.07941,-1.35883 -35.81787,-27.65959 -36.78017,-29.10372 -0.29983,-0.44995 10.93625,-9.13602 10.95076,-9.67652 0.0466,-1.73476 -9.65884,-44.21176 -9.46774,-45.93658 0.0596,-0.53741 14.25017,0.0311 14.60872,-0.37364 1.15075,-1.29896 21.01967,-40.07675 22.27476,-41.2752 0.39105,-0.37341 10.89628,9.18365 11.43109,9.10408 1.71649,-0.25538 41.86284,-17.18939 43.59465,-17.3007 0.53958,-0.0347 2.4439,14.03907 2.90473,14.32189 1.47906,0.90771 43.11793,13.74108 44.51611,14.769 0.43564,0.32027 -7.152,12.32546 -6.98077,12.83833 0.54955,1.64606 24.19764,38.24195 24.60799,39.92811 z"
- transform="matrix(0.92707315,0,0,0.39837284,1506.7537,557.00764)"
- inkscape:transform-center-x="-3.8865684"
- inkscape:transform-center-y="3.5998252e-06" />
<path
sodipodi:type="star"
style="opacity:1;fill:none;fill-opacity:0.99504945;stroke:#000000;stroke-width:6.38363266;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
@@ -4031,7 +3940,7 @@
d="m 1094.1498,915.50098 c 17.8272,-22.80331 42.9724,-34.59893 64.3085,-42.39665"
style="fill:none;stroke:#009d00;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-3-5-0)" />
<path
- style="fill:none;stroke:#ffffff;stroke-width:1.00000004;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-3-5-0-0)"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-3-5-0-0)"
d="m 1094.1498,915.50098 c 17.8272,-22.80331 42.9724,-34.59893 64.3085,-42.39665"
id="path5213-6-8-4-9-9-56-6-28-2-8"
inkscape:connector-curvature="0"
@@ -4055,25 +3964,25 @@
d="m 1286.1122,1044.9041 c -32.6374,7.6868 -68.0318,7.3275 -98.7961,1.9808"
style="fill:none;stroke:#009d00;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-3-8-4)" />
<path
- style="fill:none;stroke:#ffffff;stroke-width:1.00000004;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-3-5-7-0)"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-3-5-7-0)"
d="m 1293.1165,869.27993 c 22.9934,5.0006 51.8174,18.31502 72.3787,39.21347"
id="path5213-6-8-4-9-9-56-6-28-20-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
- style="fill:none;stroke:#ffffff;stroke-width:1.00000004;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-3-5-6-0)"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-3-5-6-0)"
d="m 1386.1562,953.29137 c -0.01,16.47992 -3.5377,27.95532 -16.4966,45.71352"
id="path5213-6-8-4-9-9-56-6-28-8-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
- style="fill:none;stroke:#ffffff;stroke-width:1.00000004;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-3-8-4-9)"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-3-8-4-9)"
d="m 1286.1122,1044.9041 c -32.6374,7.6868 -68.0318,7.3275 -98.7961,1.9808"
id="path5213-6-8-4-9-9-56-6-9-6-1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
- style="fill:none;stroke:#f6fcf6;stroke-width:1.00000004;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-3-5-2-0)"
+ style="fill:none;stroke:#f6fcf6;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-3-5-2-0)"
d="m 1099.1838,1002.8716 c -10.8263,-13.3296 -17.2825,-22.994 -19.3174,-41.9076"
id="path5213-6-8-4-9-9-56-6-28-7-2"
inkscape:connector-curvature="0"
@@ -4255,7 +4164,7 @@
<g
id="g7705">
<circle
- style="opacity:1;fill:url(#linearGradient7569);fill-opacity:1;stroke:url(#linearGradient7692);stroke-width:1.715;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ style="opacity:1;fill:url(#linearGradient7569);fill-opacity:1;stroke:url(#linearGradient7692);stroke-width:1.71500003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="path7491"
cx="1375.8579"
cy="821.88452"
@@ -4327,25 +4236,25 @@
</g>
</g>
<path
- style="fill:none;stroke:#ffffff;stroke-width:1.00000004;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-9-6)"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-9-6)"
d="m 1499.2534,277.65781 c 49.5295,21.01119 54.6565,-32.82142 113.6548,0"
id="path5213-6-8-4-9-9-56-7-15"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
- style="fill:none;stroke:#fcfffc;stroke-width:1.00000004;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.9862002;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-9-2)"
+ style="fill:none;stroke:#fcfffc;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.98620009;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-9-2)"
d="m 1498.1078,321.38191 c 49.5295,21.0112 54.6565,-32.82141 113.6548,0"
id="path5213-6-8-4-9-9-9-29-90-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
- style="fill:none;stroke:#ffffff;stroke-width:1.00000004;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-6-0-0)"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-6-0-0)"
d="m 1131.0344,258.42719 c 48.1809,-3.99296 64.2076,-2.68523 79.9712,-42.47521 42.8072,-108.05255 133.489,-146.164071 131.2384,-34.5044"
id="path5213-6-8-4-9-9-9-29-5-2-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csc" />
<path
- style="fill:none;stroke:#ffffff;stroke-width:1.00000004;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-79-0-6)"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-79-0-6)"
d="m 1159.4045,270.23739 c 108.4581,4.22547 23.1574,-88.17063 154.3238,-89.5992"
id="path5213-6-8-4-9-9-8-2-0-3"
inkscape:connector-curvature="0"
@@ -4373,13 +4282,13 @@
style="font-size:25.60000038px;line-height:1.25;stroke-width:1.06666672">OFF</tspan></text>
</g>
<path
- style="fill:none;stroke:#ffffff;stroke-width:1.00000004;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-9-8-2)"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-9-8-2)"
d="m 1364.0175,147.54301 c 29.3791,49.77199 28.7391,140.19451 -0.7576,180.57634"
id="path5213-6-8-4-9-9-56-7-1-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
- style="fill:none;stroke:#ffffff;stroke-width:1.00000004;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-62-70-9)"
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-62-70-9)"
d="M 1419.75,188.60753 V 372.1669"
id="path5213-6-8-2-4-1"
inkscape:connector-curvature="0"
@@ -4391,7 +4300,7 @@
inkscape:connector-curvature="0"
id="path5213-6-8-4-9-9-9-4-6-4-2-3-7"
d="m 1284.876,826.56171 c 75.92,10.10449 72.6994,-54.50393 12.2633,-55.89492 -51.6628,-1.18906 -74.3675,75.06672 15.6104,66.18339"
- style="fill:none;stroke:#ffffff;stroke-width:1.00000004;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-31-1-0-9-9-9)" />
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-31-1-0-9-9-9)" />
</g>
<path
sodipodi:nodetypes="cc"
@@ -4405,5 +4314,490 @@
id="path5213-6-8-4-9-9-56-6-28-7-29"
d="M 23.378604,46.366264 C 12.552304,33.036664 6.0961038,23.372264 4.0612038,4.458664"
style="fill:none;stroke:#009d00;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-3-5-2-5)" />
+ <path
+ style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:5.11919975;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-76)"
+ d="m 1282.1305,1141.8934 c 50.2683,-0.2481 46.5806,-28.9567 108.0573,-27.528"
+ id="path5213-6-8-4-9-9-1-3-6"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:5.11919975;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-76-9)"
+ d="m 1282.1305,1141.8934 c 50.2683,0.2481 46.5806,27.9715 108.0573,26.5428"
+ id="path5213-6-8-4-9-9-1-3-6-7"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <g
+ transform="translate(1091.3148,706.581)"
+ id="g23629-5-4-1">
+ <ellipse
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:4.26666689;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path3639-2-0-8-5"
+ cx="140.59442"
+ cy="435.21741"
+ rx="48.48732"
+ ry="29.092394" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.06666672"
+ x="112.51038"
+ y="444.62402"
+ id="text3021-8-9-7-9"><tspan
+ sodipodi:role="line"
+ id="tspan3023-4-6-0-7"
+ x="112.51038"
+ y="444.62402"
+ style="font-size:25.60000038px;line-height:1.25;stroke-width:1.06666672">OFF</tspan></text>
+ </g>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:24px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672"
+ x="1072.3127"
+ y="366.15677"
+ id="text3021-8-4-1-8-8-2-3-0-39"><tspan
+ sodipodi:role="line"
+ id="tspan3023-4-0-1-9-63-8-8-2-0"
+ x="1072.3127"
+ y="366.15677"
+ style="font-size:24px;line-height:1.25;stroke-width:1.06666672">While On:</tspan><tspan
+ sodipodi:role="line"
+ x="1072.3127"
+ y="381.15677"
+ style="font-size:24px;line-height:1.25;stroke-width:1.06666672"
+ id="tspan39566-8" /><tspan
+ sodipodi:role="line"
+ x="1072.3127"
+ y="381.15677"
+ style="font-size:24px;line-height:1.25;stroke-width:1.06666672"
+ id="tspan39568-8" /><tspan
+ sodipodi:role="line"
+ x="1072.3127"
+ y="381.15677"
+ style="font-size:24px;line-height:1.25;stroke-width:1.06666672"
+ id="tspan39570-5" /><tspan
+ sodipodi:role="line"
+ x="1072.3127"
+ y="381.15677"
+ style="font-size:24px;line-height:1.25;stroke-width:1.06666672"
+ id="tspan39590-0" /></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="1510.0886"
+ y="165.4404"
+ id="text39623-4-9"><tspan
+ sodipodi:role="line"
+ x="1510.0886"
+ y="165.4404"
+ id="tspan39625-9-1">1C</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="1510.017"
+ y="209.22543"
+ id="text39623-4-9-1"><tspan
+ sodipodi:role="line"
+ x="1510.017"
+ y="209.22543"
+ id="tspan39625-9-1-5">1H</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="1510.3357"
+ y="386.13828"
+ id="text39623-4-9-0"><tspan
+ sodipodi:role="line"
+ x="1510.3357"
+ y="386.13828"
+ id="tspan39625-9-1-3">3C</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="1510.3572"
+ y="276.87189"
+ id="text39623-4-9-04"><tspan
+ sodipodi:role="line"
+ x="1510.3572"
+ y="276.87189"
+ id="tspan39625-9-1-4">2C</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="1510.2855"
+ y="320.65692"
+ id="text39623-4-9-1-4"><tspan
+ sodipodi:role="line"
+ x="1510.2855"
+ y="320.65692"
+ id="tspan39625-9-1-5-4">2H</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="1312.6547"
+ y="1103.8405"
+ id="text39623-7"><tspan
+ sodipodi:role="line"
+ x="1312.6547"
+ y="1103.8405"
+ id="tspan5550">Brightness: Off, Low, High, Blinking</tspan></text>
+ <g
+ id="g5486"
+ transform="translate(4.1797945,-2.0898972)">
+ <text
+ id="text39623-4"
+ y="384.38208"
+ x="1070.4884"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ y="384.38208"
+ x="1070.4884"
+ id="tspan39621-8"
+ sodipodi:role="line">3C. Smooth /</tspan><tspan
+ id="tspan5240"
+ y="400.51541"
+ x="1070.4884"
+ sodipodi:role="line" /><tspan
+ id="tspan5223"
+ y="416.64874"
+ x="1070.4884"
+ sodipodi:role="line">4C. Ramp Cfg</tspan><tspan
+ id="tspan5225"
+ y="432.78207"
+ x="1070.4884"
+ sodipodi:role="line">5C. Manual Memory</tspan><tspan
+ id="tspan5397"
+ y="448.91541"
+ x="1070.4884"
+ sodipodi:role="line">5H. Automatic Memory</tspan></text>
+ <text
+ id="text39623-4-5"
+ y="400.5062"
+ x="1099.3933"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ id="tspan5397-7"
+ y="400.5062"
+ x="1099.3933"
+ sodipodi:role="line">Stepped ramp</tspan></text>
+ </g>
+ <g
+ id="g10115"
+ transform="matrix(0.80339488,0,0,0.80339488,265.139,209.38804)">
+ <image
+ clip-path="url(#clipPath4663-1)"
+ transform="matrix(0.53333333,-0.92376043,0.92376043,0.53333333,462.65209,269.62078)"
+ width="62.81348"
+ height="62.813423"
+ preserveAspectRatio="none"
+ xlink:href="data:image/png;base64,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 "
+ id="image4618-1"
+ x="-325.4772"
+ y="1191.9255" />
+ <g
+ transform="matrix(0.26666665,0,0,0.26666665,1109.8963,1020.4347)"
+ id="g7109">
+ <path
+ style="fill:#000000;stroke-width:0.94693667"
+ d="m 1208.1597,502.25824 c -34.6326,-4.32593 -67.5133,-28.57627 -82.383,-60.75944 -12.8467,-27.80465 -12.8467,-61.60147 0,-89.40612 9.7942,-21.19809 29.0191,-40.74595 50.1059,-50.94757 35.3274,-17.09113 78.1788,-13.2618 109.0602,9.74593 53.9998,40.23171 58.8228,116.96375 10.2511,163.09238 -23.5191,22.33627 -54.3614,32.35596 -87.0342,28.27482 z m 24.1827,-6.50306 c 11.6943,-1.34018 21.6651,-4.13325 31.6647,-8.87003 12.0012,-5.68495 19.4819,-10.91833 28.505,-19.9414 39.0774,-39.0771 39.0935,-101.2754 0.036,-140.33228 -39.0376,-39.03726 -101.332,-39.03726 -140.3694,0 -39.0308,39.03052 -39.0308,101.48596 0,140.33228 9.0823,9.03938 16.5684,14.26979 28.5413,19.9414 16.6467,7.88554 34.0777,10.88063 51.6221,8.87003 z m -35.0726,-11.94697 c -9.3898,-2.7671 -19.4507,-7.43387 -25.7886,-11.96212 l -4.4827,-3.20262 3.6968,-3.60972 3.6968,-3.60972 2.8267,2.01277 c 5.0825,3.61909 18.4812,9.53498 25.7326,11.36174 l 7.1021,1.78909 0.2862,4.84668 c 0.2809,4.75606 0.2366,4.84572 -2.3673,4.79626 -1.4594,-0.0276 -6.2756,-1.11778 -10.7026,-2.42236 z m 37.1179,-2.3739 0.2863,-4.84668 7.1019,-1.78909 c 7.2608,-1.82911 20.6519,-7.74381 25.7486,-11.37297 l 2.8424,-2.02399 3.3864,3.38644 c 4.0359,4.03586 3.7514,4.63405 -4.6241,9.7219 -9.1961,5.58624 -26.2972,11.70606 -32.8476,11.75482 -2.0306,0.0152 -2.1604,-0.31623 -1.8939,-4.83043 z m -18.1791,-33.97762 c 0,-13.75716 -0.2786,-17.99392 -1.1837,-18.00099 -0.651,-0.005 -3.503,-1.0889 -6.3379,-2.40846 l -5.1543,-2.39923 -12.6012,12.5752 -12.6012,12.5752 -4.4848,-4.48478 -4.4848,-4.48478 12.5753,-12.60113 12.5753,-12.60114 -2.3992,-5.15422 c -1.3197,-2.83482 -2.4035,-5.68686 -2.4085,-6.33789 -0.01,-0.90508 -4.2439,-1.18366 -18.0011,-1.18366 h -17.9919 v -6.15507 -6.15507 h 17.509 17.5088 l 2.8794,-6.35003 2.8792,-6.35003 -12.5632,-12.58899 -12.5631,-12.58899 4.4848,-4.48478 4.4848,-4.48478 12.7147,12.68842 c 12.5449,12.51897 12.745,12.66857 14.9832,11.20209 1.2476,-0.81748 4.0486,-2.01969 6.2244,-2.67158 l 3.956,-1.18525 V 345.9849 328.14305 h 6.1552 6.1551 v 17.99174 c 0,13.75717 0.2785,17.99392 1.1837,18.00099 0.6509,0.005 3.503,1.0889 6.3378,2.40848 l 5.1543,2.39921 12.6012,-12.5752 12.6013,-12.5752 4.4847,4.48478 4.4849,4.48478 -12.5633,12.58899 -12.5632,12.58899 2.8794,6.35003 2.8791,6.35003 h 17.5091 17.509 v 6.15507 6.15507 h -17.9919 c -13.7573,0 -17.9941,0.27858 -18.0011,1.18366 0,0.65103 -1.0889,3.50307 -2.4085,6.33789 l -2.3993,5.15422 12.5753,12.60114 12.5754,12.60113 -4.4849,4.48478 -4.4847,4.48478 -12.6013,-12.5752 -12.6012,-12.5752 -5.1543,2.39923 c -2.8348,1.31956 -5.6869,2.40338 -6.3378,2.40846 -0.9052,0.007 -1.1837,4.24383 -1.1837,18.00099 v 17.99174 h -6.1551 -6.1552 z m -69.1946,-0.23673 c -5.9183,-8.15484 -12.4981,-24.40033 -13.7718,-34.00256 l -0.6225,-4.69292 4.9758,0.29071 4.9759,0.29069 1.6922,6.68101 c 2.1584,8.52045 5.8931,17.38899 10.0783,23.93151 l 3.29,5.14302 -3.0934,3.1915 c -1.7013,1.75533 -3.4332,3.19151 -3.8485,3.19151 -0.4154,0 -2.0696,-1.81102 -3.676,-4.02447 z m 143.1258,0.78233 -3.1425,-3.24213 2.0104,-2.82319 c 3.6169,-5.07942 9.5331,-18.47971 11.3593,-25.72909 l 1.7891,-7.102 4.8467,-0.28622 c 4.5851,-0.27078 4.8467,-0.16151 4.8467,2.02467 0,3.81305 -4.6291,18.63822 -8.0317,25.72262 -3.3326,6.93875 -8.4893,14.67748 -9.7804,14.67748 -0.4152,0 -2.1693,-1.45897 -3.8976,-3.24214 z m -157.2619,-65.16212 c 0,-3.20372 2.5101,-12.53902 5.2863,-19.66057 2.8865,-7.40436 10.7727,-20.83254 12.2348,-20.83254 0.5754,0 2.4603,1.45896 4.1887,3.24214 l 3.1423,3.24213 -2.0103,2.82317 c -3.6168,5.07943 -9.533,18.47971 -11.3592,25.7291 l -1.7891,7.10201 -4.8468,0.28621 c -4.5329,0.26769 -4.8467,0.14263 -4.8467,-1.93165 z m 169.0832,0.93523 c -0.1978,-0.65101 -0.8545,-3.31427 -1.4598,-5.91833 -1.6166,-6.95664 -5.4897,-16.21493 -9.6798,-23.13832 l -3.6877,-6.09352 3.7084,-3.70837 3.7084,-3.70837 4.3952,7.0518 c 5.09,8.16635 8.6536,16.43448 11.1242,25.80904 2.7635,10.4857 2.6529,10.88974 -2.9848,10.88974 -2.9886,0 -4.8985,-0.4412 -5.1241,-1.18367 z m -131.5545,-55.50477 -3.574,-3.66016 6.4205,-4.05491 c 3.5313,-2.2302 8.7227,-5.07302 11.5364,-6.31737 6.2701,-2.77292 20.3792,-6.92768 23.5255,-6.92768 2.1862,0 2.2955,0.26156 2.0247,4.84667 l -0.2862,4.84666 -6.9183,1.75257 c -8.1686,2.06927 -16.7209,5.70295 -23.6389,10.04357 -2.7444,1.72194 -5.1081,3.13081 -5.2528,3.13081 -0.1445,0 -1.8712,-1.64707 -3.8369,-3.66016 z m 94.5694,0.33445 c -5.7493,-3.87473 -14.7706,-7.65362 -23.6734,-9.91647 l -6.6286,-1.68477 -0.2863,-4.84666 c -0.2665,-4.51421 -0.1367,-4.84556 1.8939,-4.83044 2.9913,0.0222 14.331,3.09568 20.6454,5.59553 6.6994,2.65224 19.8858,10.54927 19.8858,11.90916 0,1.02385 -5.8283,7.16495 -6.6738,7.03199 -0.2356,-0.0371 -2.559,-1.50331 -5.163,-3.25834 z"
+ id="path7087"
+ inkscape:connector-curvature="0" />
+ <ellipse
+ style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.49778914;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path7089"
+ cx="1222.4409"
+ cy="396.8504"
+ rx="34.040714"
+ ry="34.040607" />
+ <path
+ style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.49778926;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path7089-3"
+ sodipodi:type="arc"
+ sodipodi:cx="1222.4409"
+ sodipodi:cy="396.8504"
+ sodipodi:rx="34.040714"
+ sodipodi:ry="34.040607"
+ sodipodi:start="4.712389"
+ sodipodi:end="1.5707963"
+ d="m 1222.4409,362.8098 a 34.040714,34.040607 0 0 1 34.0407,34.0406 34.040714,34.040607 0 0 1 -34.0407,34.04061 l 0,-34.04061 z" />
+ </g>
+ </g>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="1352.7787"
+ y="1188.7327"
+ id="text39623-7-4"><tspan
+ sodipodi:role="line"
+ x="1352.7787"
+ y="1188.7327"
+ id="tspan5550-1">Color: R, Y, G, C, B, V, W, Rainbow, Volts</tspan></text>
+ <path
+ style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:5.11919975;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-76-3)"
+ d="m 1555.1266,1141.8934 c -50.2683,-0.2481 -46.5806,-28.9567 -108.0573,-27.528"
+ id="path5213-6-8-4-9-9-1-3-6-3"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:5.11919975;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-76-9-6)"
+ d="m 1555.1266,1141.8934 c -50.2683,0.2481 -46.5806,27.9715 -108.0573,26.5428"
+ id="path5213-6-8-4-9-9-1-3-6-7-0"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <g
+ transform="translate(1258.9411,301.76378)"
+ id="g58162-9-5">
+ <ellipse
+ ry="29.092394"
+ rx="67.643234"
+ cy="838.49103"
+ cx="358.68741"
+ id="path3639-4-4-0-6"
+ style="fill:#505050;fill-opacity:1;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ <text
+ id="text3021-8-4-1-8-8-20-3"
+ y="847.32025"
+ x="310.00983"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#c0c0c0;fill-opacity:1;stroke:none;stroke-width:1.06666672"
+ xml:space="preserve"><tspan
+ style="font-size:25.60000038px;line-height:1.25;fill:#c0c0c0;fill-opacity:1;stroke-width:1.06666672"
+ y="847.32025"
+ x="310.00983"
+ id="tspan3023-4-0-1-9-63-1-9"
+ sodipodi:role="line">Lockout</tspan></text>
+ </g>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="1007.1519"
+ y="1445.0747"
+ id="text39623-7-6"
+ transform="rotate(-15)"><tspan
+ sodipodi:role="line"
+ x="1007.1519"
+ y="1445.0747"
+ id="tspan5550-4">7C</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="1598.1183"
+ y="771.31158"
+ id="text39623-7-6-3"
+ transform="rotate(15)"><tspan
+ sodipodi:role="line"
+ x="1598.1183"
+ y="771.31158"
+ id="tspan5550-4-3">7H</tspan></text>
+ <rect
+ style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect5159-4-9-8"
+ width="642.51971"
+ height="113.38567"
+ x="1058.2677"
+ y="1084.7245" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:29.33333397px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672"
+ x="1067.4176"
+ y="1115.4191"
+ id="text3021-8-4-1-8-8-2-6-8"><tspan
+ sodipodi:role="line"
+ id="tspan3023-4-0-1-9-63-8-1-8"
+ x="1067.4176"
+ y="1115.4191"
+ style="font-size:29.33333397px;line-height:1.25;stroke-width:1.06666672">Aux /</tspan><tspan
+ sodipodi:role="line"
+ x="1067.4176"
+ y="1152.0857"
+ style="font-size:29.33333397px;line-height:1.25;stroke-width:1.06666672"
+ id="tspan10106">Button</tspan><tspan
+ sodipodi:role="line"
+ x="1067.4176"
+ y="1188.7524"
+ style="font-size:29.33333397px;line-height:1.25;stroke-width:1.06666672"
+ id="tspan10108">LEDs</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="1713.5479"
+ y="710.49811"
+ id="text39623-7-6-9"
+ transform="rotate(15)"><tspan
+ sodipodi:role="line"
+ x="1713.5479"
+ y="710.49811"
+ id="tspan5550-4-2">3C</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="1122.6094"
+ y="1505.6223"
+ id="text39623-7-6-3-5"
+ transform="rotate(-15)"><tspan
+ sodipodi:role="line"
+ x="1122.6094"
+ y="1505.6223"
+ id="tspan5550-4-3-4">3H</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="1185.0386"
+ y="185.57895"
+ id="text39623-4-9-0-0"><tspan
+ sodipodi:role="line"
+ x="1185.0386"
+ y="185.57895"
+ id="tspan39625-9-1-3-5">3C</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ id="text39623-4-9-0-9"
+ transform="translate(2.6868986,-3.5825314)"><textPath
+ xlink:href="#path5213-6-8-4-9-9-8-3-7"
+ id="textPath13205"><tspan
+ id="tspan39625-9-1-3-4"> 3 Clicks</tspan></textPath></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="1046.6205"
+ y="1179.0468"
+ id="text39623-4-9-0-6"
+ transform="rotate(-15)"><tspan
+ sodipodi:role="line"
+ x="1046.6205"
+ y="1179.0468"
+ id="tspan39625-9-1-3-9">3C</tspan></text>
+ <path
+ style="fill:none;stroke:#040404;stroke-width:2.18333006;stroke-miterlimit:4;stroke-dasharray:13.09998035, 2.18333006;stroke-dashoffset:1.30999804;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-6-0-0-2)"
+ d="m 1130.3238,305.57915 c 48.1809,3.99296 64.2076,2.68523 79.9712,42.47521 42.8072,108.05255 133.489,146.16407 131.2384,34.5044"
+ id="path5213-6-8-4-9-9-9-29-5-2-7-4"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csc" />
+ <g
+ id="g14919">
+ <g
+ id="g58162-9"
+ transform="translate(861.28782,-266.43715)">
+ <ellipse
+ style="fill:#505050;fill-opacity:1;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path3639-4-4-0"
+ cx="358.68741"
+ cy="838.49103"
+ rx="67.643234"
+ ry="29.092394" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#c0c0c0;fill-opacity:1;stroke:none;stroke-width:1.06666672"
+ x="310.00983"
+ y="847.32025"
+ id="text3021-8-4-1-8-8-20"><tspan
+ sodipodi:role="line"
+ id="tspan3023-4-0-1-9-63-1"
+ x="310.00983"
+ y="847.32025"
+ style="font-size:25.60000038px;line-height:1.25;fill:#c0c0c0;fill-opacity:1;stroke-width:1.06666672">Lockout</tspan></text>
+ </g>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:13.33333302px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#c0c0c0;fill-opacity:1;stroke:none;stroke-width:1.06666672"
+ x="1219.5195"
+ y="560.15283"
+ id="text3021-8-4-1-8-8-20-7"><tspan
+ id="tspan14800"
+ sodipodi:role="line"
+ x="1219.5195"
+ y="560.15283"
+ style="font-size:13.33333302px;line-height:1.25;text-align:center;text-anchor:middle;fill:#c0c0c0;fill-opacity:1;stroke-width:1.06666672">Momentary</tspan><tspan
+ id="tspan14812"
+ sodipodi:role="line"
+ x="1219.5195"
+ y="568.48615"
+ style="font-size:13.33333302px;line-height:1.25;text-align:center;text-anchor:middle;fill:#c0c0c0;fill-opacity:1;stroke-width:1.06666672" /><tspan
+ id="tspan14792"
+ sodipodi:role="line"
+ x="1221.642"
+ y="576.81952"
+ style="font-size:13.33333302px;line-height:1.25;text-align:center;text-anchor:middle;fill:#c0c0c0;fill-opacity:1;stroke-width:1.06666672"> </tspan><tspan
+ id="tspan14814"
+ sodipodi:role="line"
+ x="1219.5195"
+ y="585.15283"
+ style="font-size:13.33333302px;line-height:1.25;text-align:center;text-anchor:middle;fill:#c0c0c0;fill-opacity:1;stroke-width:1.06666672" /><tspan
+ id="tspan14810"
+ sodipodi:role="line"
+ x="1219.5195"
+ y="585.15283"
+ style="font-size:13.33333302px;line-height:1.25;text-align:center;text-anchor:middle;fill:#c0c0c0;fill-opacity:1;stroke-width:1.06666672" /><tspan
+ id="tspan14804"
+ sodipodi:role="line"
+ x="1219.5195"
+ y="585.15283"
+ style="font-size:13.33333302px;line-height:1.25;text-align:center;text-anchor:middle;fill:#c0c0c0;fill-opacity:1;stroke-width:1.06666672" /><tspan
+ id="tspan14808"
+ sodipodi:role="line"
+ x="1219.5195"
+ y="585.15283"
+ style="font-size:13.33333302px;line-height:1.25;text-align:center;text-anchor:middle;fill:#c0c0c0;fill-opacity:1;stroke-width:1.06666672" /><tspan
+ id="tspan14806"
+ sodipodi:role="line"
+ x="1219.5195"
+ y="585.15283"
+ style="font-size:13.33333302px;line-height:1.25;text-align:center;text-anchor:middle;fill:#c0c0c0;fill-opacity:1;stroke-width:1.06666672" /><tspan
+ id="tspan14796"
+ sodipodi:role="line"
+ x="1219.5195"
+ y="585.15283"
+ style="font-size:13.33333302px;line-height:1.25;text-align:center;text-anchor:middle;fill:#c0c0c0;fill-opacity:1;stroke-width:1.06666672" /><tspan
+ id="tspan14798"
+ sodipodi:role="line"
+ x="1219.5195"
+ y="585.15283"
+ style="font-size:13.33333302px;line-height:1.25;text-align:center;text-anchor:middle;fill:#c0c0c0;fill-opacity:1;stroke-width:1.06666672" /><tspan
+ id="tspan14794"
+ sodipodi:role="line"
+ x="1219.5195"
+ y="593.48615"
+ style="font-size:13.33333302px;line-height:1.25;text-align:center;text-anchor:middle;fill:#c0c0c0;fill-opacity:1;stroke-width:1.06666672">Moon / Low</tspan></text>
+ </g>
+ <g
+ id="g14924">
+ <path
+ inkscape:transform-center-y="3.5998252e-06"
+ inkscape:transform-center-x="-3.8865684"
+ transform="matrix(0.92707315,0,0,0.39837284,1506.7537,557.00764)"
+ d="m -228.62935,217.75388 c 0.12785,0.52537 -13.40141,4.84463 -13.59991,5.34758 -0.63708,1.61421 -6.04498,44.84898 -6.81448,46.40442 -0.23976,0.48464 -13.38015,-4.90306 -13.85549,-4.64537 -1.52563,0.82704 -33.45909,30.47067 -35.04838,31.16758 -0.49518,0.21714 -7.09816,-12.35655 -7.62794,-12.4647 -1.70031,-0.34709 -45.21732,1.83481 -46.88275,1.3471 -0.51891,-0.15196 2.50513,-14.02828 2.16882,-14.45166 -1.07941,-1.35883 -35.81787,-27.65959 -36.78017,-29.10372 -0.29983,-0.44995 10.93625,-9.13602 10.95076,-9.67652 0.0466,-1.73476 -9.65884,-44.21176 -9.46774,-45.93658 0.0596,-0.53741 14.25017,0.0311 14.60872,-0.37364 1.15075,-1.29896 21.01967,-40.07675 22.27476,-41.2752 0.39105,-0.37341 10.89628,9.18365 11.43109,9.10408 1.71649,-0.25538 41.86284,-17.18939 43.59465,-17.3007 0.53958,-0.0347 2.4439,14.03907 2.90473,14.32189 1.47906,0.90771 43.11793,13.74108 44.51611,14.769 0.43564,0.32027 -7.152,12.32546 -6.98077,12.83833 0.54955,1.64606 24.19764,38.24195 24.60799,39.92811 z"
+ inkscape:randomized="-6.9388939e-18"
+ inkscape:rounded="0.037"
+ inkscape:flatsided="false"
+ sodipodi:arg2="0.11055917"
+ sodipodi:arg1="0.026660495"
+ sodipodi:r2="68.11689"
+ sodipodi:r1="81.329819"
+ sodipodi:cy="215.58585"
+ sodipodi:cx="-309.93027"
+ sodipodi:sides="9"
+ id="path4327-0-3"
+ style="fill:url(#radialGradient5882-9-2);fill-opacity:1;stroke:#000000;stroke-width:3.75277472;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ sodipodi:type="star" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672"
+ x="1221.3058"
+ y="659.65179"
+ id="text3021-8-4-1-8-8-20-7-5"><tspan
+ id="tspan14794-2"
+ sodipodi:role="line"
+ x="1221.3058"
+ y="659.65179"
+ style="font-size:12px;line-height:1.25;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke-width:1.06666672">On / Strobes</tspan></text>
+ </g>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:13.33333302px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="1091.5458"
+ y="1212.6874"
+ id="text39629-1"><tspan
+ sodipodi:role="line"
+ x="1091.5458"
+ y="1212.6874"
+ id="tspan43995-1">Factory Reset: Loosen tailcap, Hold button, Tighten tailcap, Hold 3s (or 13H from Off)</tspan></text>
</g>
</svg>
diff --git a/spaghetti-monster/anduril/anduril.txt b/spaghetti-monster/anduril/anduril.txt
index 3e0328c..db73cdb 100644
--- a/spaghetti-monster/anduril/anduril.txt
+++ b/spaghetti-monster/anduril/anduril.txt
@@ -20,6 +20,8 @@ From off:
* On hardware with an indicator LED...
* 7 clicks: Change aux LED mode used in "off" mode.
(the modes are usually off/low/high/blinking)
+ * 7 clicks (but hold the last click):
+ Change aux LED color used in "off" mode.
In steady / ramping mode:
* 1 click: off
@@ -28,6 +30,8 @@ In steady / ramping mode:
* 2 clicks: to/from turbo (actual turbo, not just highest ramp level)
* 3 clicks: toggle smooth vs discrete ramping
* 4 clicks: configure current ramp
+ * 5 clicks: activate manual memory and save current brightness
+ * 5 clicks (but hold the last click): go back to automatic memory
Smooth ramp config mode:
* Setting 1: low end
@@ -104,14 +108,18 @@ Discrete ramp config mode:
At buzz, click N times to set thermal limit to roughly 30 C + N.
Lockout mode:
- * Hold: momentary moon
+ * Hold: momentary moon (current ramp floor)
+ * Click, Hold: momentary moon (other ramp floor)
* 4 clicks: exit lockout (return to regular "off" mode)
* On hardware with an indicator LED...
* 3 clicks: Change aux LED brightness used in lockout mode.
(the modes are usually off/low/high/blinking)
+ * 3 clicks (but hold the last click):
+ Change aux LED color used in lockout mode.
Momentary mode:
- * Press button: Light on (at memorized level).
+ * Press button: Light on (at memorized mode/level).
+ (uses either a steady mode or a strobe-group mode)
* Release button: Light off.
* To exit, disconnect power. (loosen/tighten the tailcap)
@@ -148,6 +156,10 @@ Indicator LED / aux LED support:
- High
- Blinking
+ If the aux LEDs can change color, the user can configure the color
+ using exactly the same method... except hold the last click until the
+ desired color is reached.
+
TODO:
* save settings in eeprom
@@ -167,7 +179,7 @@ TODO:
* move all config menus to four clicks
* candle mode timer, with three clicks to add 30 minutes
* diagram updates for 3-click special actions
+ * add a toggle for memory (manual vs automatic memory)
- candle mode: smoother adjustments?
- make sunset mode timer and brightness configurable?
- make beacon mode actually sleep between pulses
- - add a toggle for memory?
diff --git a/spaghetti-monster/anduril/build-all.sh b/spaghetti-monster/anduril/build-all.sh
index c355f1e..56a88bf 100755
--- a/spaghetti-monster/anduril/build-all.sh
+++ b/spaghetti-monster/anduril/build-all.sh
@@ -5,7 +5,9 @@ UI=anduril
for TARGET in cfg-*.h ; do
NAME=$(echo "$TARGET" | perl -ne '/cfg-(.*).h/ && print "$1\n";')
echo "===== $NAME ====="
- echo ../../../bin/build.sh 85 "$UI" "-DCONFIGFILE=${TARGET}"
- ../../../bin/build.sh 85 "$UI" "-DCONFIGFILE=${TARGET}"
+ ATTINY=$(grep 'ATTINY:' $TARGET | awk '{ print $3 }')
+ if [ -z "$ATTINY" ]; then ATTINY=85 ; fi
+ echo ../../../bin/build.sh $ATTINY "$UI" "-DCONFIGFILE=${TARGET}"
+ ../../../bin/build.sh $ATTINY "$UI" "-DCONFIGFILE=${TARGET}"
mv -f "$UI".hex "$UI".$NAME.hex
done
diff --git a/spaghetti-monster/anduril/cfg-emisar-d18.h b/spaghetti-monster/anduril/cfg-emisar-d18.h
index fcea43a..16fbacd 100644
--- a/spaghetti-monster/anduril/cfg-emisar-d18.h
+++ b/spaghetti-monster/anduril/cfg-emisar-d18.h
@@ -43,4 +43,4 @@
// stop panicking at about ~40% power or ~5000 lm
#define THERM_FASTER_LEVEL 125
// optional, makes initial turbo step-down faster so first peak isn't as hot
-#define THERM_HARD_TURBO_DROP
+//#define THERM_HARD_TURBO_DROP
diff --git a/spaghetti-monster/anduril/cfg-emisar-d4.h b/spaghetti-monster/anduril/cfg-emisar-d4.h
index 2f4df49..c86a534 100644
--- a/spaghetti-monster/anduril/cfg-emisar-d4.h
+++ b/spaghetti-monster/anduril/cfg-emisar-d4.h
@@ -9,11 +9,23 @@
#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,4,5,7,8,9,11,12,14,15,17,19,20,22,24,25,27,29,31,33,35,37,39,41,43,45,48,50,52,55,57,59,62,64,67,70,72,75,78,81,84,87,90,93,96,99,102,105,109,112,115,119,122,126,129,133,137,141,144,148,152,156,160,165,169,173,177,182,186,191,195,200,205,209,214,219,224,229,234,239,244,250,255
#define MAX_1x7135 65
#define HALFSPEED_LEVEL 14
-#define QUARTERSPEED_LEVEL 5
+#define QUARTERSPEED_LEVEL 6
+
+#define RAMP_SMOOTH_FLOOR 1
+#define RAMP_SMOOTH_CEIL 120
+// 10, 28, 46, [65], 83, 101, 120
+#define RAMP_DISCRETE_FLOOR 10
+#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
+#define RAMP_DISCRETE_STEPS 7
// optional, makes initial turbo step-down faster so first peak isn't as hot
// the D4 runs very very hot, so be extra careful
-#define THERM_HARD_TURBO_DROP
+//#define THERM_HARD_TURBO_DROP
// stop panicking at ~30% power or ~1200 lm
#define THERM_FASTER_LEVEL 105
+// respond to thermal changes faster
+#define THERMAL_WARNING_SECONDS 3
+#define THERMAL_UPDATE_SPEED 1
+#define THERM_PREDICTION_STRENGTH 4
+
diff --git a/spaghetti-monster/anduril/cfg-emisar-d4s.h b/spaghetti-monster/anduril/cfg-emisar-d4s.h
index e26634a..230ac7c 100644
--- a/spaghetti-monster/anduril/cfg-emisar-d4s.h
+++ b/spaghetti-monster/anduril/cfg-emisar-d4s.h
@@ -36,9 +36,13 @@
#undef MIN_THERM_STEPDOWN // this should be lower, because 3x7135 instead of 1x7135
#endif
#define MIN_THERM_STEPDOWN 60 // lowest value it'll step down to
-#define THERM_FASTER_LEVEL (RAMP_SIZE*9/10) // throttle back faster when high
+#define THERM_FASTER_LEVEL (RAMP_SIZE-20) // don't throttle back faster when high
// no need to be extra-careful on this light
#ifdef THERM_HARD_TURBO_DROP
#undef THERM_HARD_TURBO_DROP
#endif
+
+#define THERMAL_WARNING_SECONDS 3
+#define THERMAL_UPDATE_SPEED 2
+#define THERM_PREDICTION_STRENGTH 4
diff --git a/spaghetti-monster/anduril/cfg-emisar-d4v2-219.h b/spaghetti-monster/anduril/cfg-emisar-d4v2-219.h
new file mode 100644
index 0000000..0770935
--- /dev/null
+++ b/spaghetti-monster/anduril/cfg-emisar-d4v2-219.h
@@ -0,0 +1,8 @@
+// Emisar D4v2-219 config options for Anduril
+#include "cfg-emisar-d4v2.h"
+// ATTINY: 1634
+
+#undef PWM1_LEVELS
+#undef PWM2_LEVELS
+#define PWM1_LEVELS 1,1,2,2,3,3,4,4,5,6,7,8,9,10,12,13,14,15,17,19,20,22,24,26,29,31,34,36,39,42,45,48,51,55,59,62,66,70,75,79,84,89,93,99,104,110,115,121,127,134,140,147,154,161,168,176,184,192,200,209,217,226,236,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
+#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,3,5,6,6,8,9,10,11,12,14,15,16,18,18,20,21,23,24,26,27,29,30,32,33,36,37,39,41,43,44,46,48,50,52,54,56,58,61,63,65,67,70,72,74,77,79,82,84,86,89,92,95,97,100,103,106,108,111,114,117,120,124,127,130,133,137,140,144,147,151,154,157,161,165,169,172,176,180,184,188,192
diff --git a/spaghetti-monster/anduril/cfg-emisar-d4v2.h b/spaghetti-monster/anduril/cfg-emisar-d4v2.h
new file mode 100644
index 0000000..b83c65c
--- /dev/null
+++ b/spaghetti-monster/anduril/cfg-emisar-d4v2.h
@@ -0,0 +1,51 @@
+// Emisar D4 config options for Anduril
+#include "hwdef-Emisar_D4v2.h"
+// ATTINY: 1634
+
+// this light has three aux LED channels: R, G, B
+#define USE_AUX_RGB_LEDS
+// the aux LEDs are front-facing, so turn them off while main LEDs are on
+#ifdef USE_INDICATOR_LED_WHILE_RAMPING
+#undef USE_INDICATOR_LED_WHILE_RAMPING
+#endif
+// enable blinking aux LEDs
+#define TICK_DURING_STANDBY
+#define STANDBY_TICK_SPEED 3 // every 0.128 s
+//#define STANDBY_TICK_SPEED 4 // every 0.256 s
+//#define STANDBY_TICK_SPEED 5 // every 0.512 s
+
+
+// copied from original D4, since it's also a FET+1 and has the same host
+// ../../bin/level_calc.py 1 65 7135 1 0.8 150
+// ... mixed with this:
+// ../../bin/level_calc.py 2 150 7135 4 0.33 150 FET 1 10 1500
+#define RAMP_LENGTH 150
+#define PWM1_LEVELS 1,1,2,2,3,3,4,4,5,6,7,8,9,10,12,13,14,15,17,19,20,22,24,26,29,31,34,36,39,42,45,48,51,55,59,62,66,70,75,79,84,89,93,99,104,110,115,121,127,134,140,147,154,161,168,176,184,192,200,209,217,226,236,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0
+#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,4,5,7,8,9,11,12,14,15,17,19,20,22,24,25,27,29,31,33,35,37,39,41,43,45,48,50,52,55,57,59,62,64,67,70,72,75,78,81,84,87,90,93,96,99,102,105,109,112,115,119,122,126,129,133,137,141,144,148,152,156,160,165,169,173,177,182,186,191,195,200,205,209,214,219,224,229,234,239,244,250,255
+#define MAX_1x7135 65
+#define HALFSPEED_LEVEL 14
+#define QUARTERSPEED_LEVEL 6
+
+#define RAMP_SMOOTH_FLOOR 1
+#define RAMP_SMOOTH_CEIL 120
+// 10, 28, 46, [65], 83, 101, 120
+#define RAMP_DISCRETE_FLOOR 10
+#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
+#define RAMP_DISCRETE_STEPS 7
+
+// optional, makes initial turbo step-down faster so first peak isn't as hot
+// the D4 runs very very hot, so be extra careful
+//#define THERM_HARD_TURBO_DROP
+
+// stop panicking at ~30% power or ~1200 lm
+#define THERM_FASTER_LEVEL 105
+// respond to thermal changes faster
+#define THERMAL_WARNING_SECONDS 3
+#define THERMAL_UPDATE_SPEED 1
+#define THERM_PREDICTION_STRENGTH 4
+//#define THERM_RESPONSE_MAGNITUDE 128
+
+// easier access to thermal config mode, for Emisar
+#define USE_TENCLICK_THERMAL_CONFIG
+
+#define THERM_CAL_OFFSET 5
diff --git a/spaghetti-monster/anduril/cfg-ff-e01.h b/spaghetti-monster/anduril/cfg-ff-e01.h
new file mode 100644
index 0000000..3b47165
--- /dev/null
+++ b/spaghetti-monster/anduril/cfg-ff-e01.h
@@ -0,0 +1,15 @@
+// Fireflies E01 SST-40 thrower config options for Anduril
+// most of the good stuff is in the FFUI config; just copy it
+#include "../fireflies-ui/cfg-ff-e01.h"
+
+#ifndef BLINK_AT_RAMP_CEILING
+#define BLINK_AT_RAMP_CEILING
+#endif
+
+// 20, 38, 56, 75, [93], 111, 130 (93 is highest regulated)
+// (9 / 45 / 116 / 248 / 467 / 742 / 1280 + 2140 lm)
+#undef RAMP_DISCRETE_STEPS
+#define RAMP_DISCRETE_STEPS 7
+
+// shortcut for first-time setup
+#define USE_TENCLICK_THERMAL_CONFIG
diff --git a/spaghetti-monster/anduril/cfg-ff-pl47-219.h b/spaghetti-monster/anduril/cfg-ff-pl47-219.h
index 3ded2aa..ad66adb 100644
--- a/spaghetti-monster/anduril/cfg-ff-pl47-219.h
+++ b/spaghetti-monster/anduril/cfg-ff-pl47-219.h
@@ -3,5 +3,7 @@
// to avoid destroying the LEDs
#include "cfg-ff-pl47.h"
+#undef PWM1_LEVELS
#undef PWM2_LEVELS
+#define PWM1_LEVELS 1,1,2,2,3,3,4,4,5,5,6,6,7,8,8,9,10,10,11,12,13,14,15,16,17,18,19,21,22,23,25,26,27,29,31,32,34,36,38,40,42,44,46,49,51,54,56,59,62,65,68,71,74,78,81,85,89,93,97,101,106,110,115,120,125,130,136,141,147,153,160,166,173,180,187,195,202,210,219,227,236,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,15,16,17,19,20,22,23,25,27,28,30,31,33,35,37,39,41,43,45,47,50,52,55,57,60,63,65,68,71,74,77,80,83,87,90,93,97,101,105,108,112,116,121,125,129,134,139,143,148,153,159,164,169
diff --git a/spaghetti-monster/anduril/cfg-ff-pl47.h b/spaghetti-monster/anduril/cfg-ff-pl47.h
index f9c8974..7a81c25 100644
--- a/spaghetti-monster/anduril/cfg-ff-pl47.h
+++ b/spaghetti-monster/anduril/cfg-ff-pl47.h
@@ -59,10 +59,12 @@
//#define MUGGLE_CEILING 90
// regulate down faster when the FET is active, slower otherwise
-#define THERM_FASTER_LEVEL 130 // throttle back faster when high
+#define THERM_FASTER_LEVEL 135 // throttle back faster when high
// play it safe, don't try to regulate above the recommended safe level
-#define THERM_HARD_TURBO_DROP
+#ifdef THERM_HARD_TURBO_DROP
+#undef THERM_HARD_TURBO_DROP
+#endif
// don't do this
#undef BLINK_AT_RAMP_MIDDLE
diff --git a/spaghetti-monster/anduril/cfg-ff-rot66.h b/spaghetti-monster/anduril/cfg-ff-rot66.h
index 6073ce0..2a90343 100644
--- a/spaghetti-monster/anduril/cfg-ff-rot66.h
+++ b/spaghetti-monster/anduril/cfg-ff-rot66.h
@@ -39,7 +39,7 @@
#define THERM_FASTER_LEVEL 130 // throttle back faster when high
// play it safe, don't try to regulate above the recommended safe level
-#define THERM_HARD_TURBO_DROP
+//#define THERM_HARD_TURBO_DROP
// don't do this
#undef BLINK_AT_RAMP_MIDDLE
diff --git a/spaghetti-monster/anduril/cfg-fw3a.h b/spaghetti-monster/anduril/cfg-fw3a.h
index dd77137..489766c 100644
--- a/spaghetti-monster/anduril/cfg-fw3a.h
+++ b/spaghetti-monster/anduril/cfg-fw3a.h
@@ -15,5 +15,8 @@
// stop panicking at about 3A or ~1100 lm, this light is a hotrod
#define THERM_FASTER_LEVEL MAX_Nx7135
-// optional, makes initial turbo step-down faster so first peak isn't as hot
-#define THERM_HARD_TURBO_DROP
+
+#define USE_TENCLICK_THERMAL_CONFIG
+
+// can't reset the normal way because power is connected before the button
+#define USE_SOFT_FACTORY_RESET
diff --git a/spaghetti-monster/anduril/cfg-mateminco-mf01s.h b/spaghetti-monster/anduril/cfg-mateminco-mf01s.h
new file mode 100644
index 0000000..0585b38
--- /dev/null
+++ b/spaghetti-monster/anduril/cfg-mateminco-mf01s.h
@@ -0,0 +1,45 @@
+// Mateminco/Astrolux MF01S options for Anduril
+#include "hwdef-Mateminco_MF01S.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: low (1)
+// lockout: blinking (3)
+#define INDICATOR_LED_DEFAULT_MODE ((3<<2) + 1)
+
+
+// don't blink during ramp, it's irrelevant and annoying on this light
+#define BLINK_AT_RAMP_CEILING
+#undef BLINK_AT_RAMP_MIDDLE
+#undef BLINK_AT_RAMP_FLOOR
+
+// measured brightness with 4x30Q cells at 4.11V:
+// moon: 2.5 lm
+// channel 1: 617 lm
+// channel 2: 13500 lm
+// ../../../bin/level_calc.py seventh 2 150 7135 1 12 717 FET 1 10 13000
+// (with some manual tweaks afterward)
+#define RAMP_LENGTH 150
+#define PWM1_LEVELS 1,1,2,2,3,3,4,4,5,5,6,7,7,8,9,10,11,12,13,14,15,17,18,19,21,22,24,26,28,30,32,34,36,38,41,44,46,49,52,55,59,62,66,70,74,78,83,87,92,97,102,108,114,120,126,133,139,147,154,162,170,178,187,196,206,215,226,236,248,255,235,255,240,255,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0
+#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,2,3,3,4,4,5,6,7,8,9,10,11,12,13,14,16,17,19,20,22,23,25,26,28,30,31,33,35,37,39,41,43,45,47,49,52,54,57,59,62,65,67,70,73,76,80,83,86,90,93,97,101,105,109,113,117,122,126,131,135,140,145,151,156,161,167,173,179,185,191,197,204,211,218,225,232,239,247,255
+#define MAX_1x7135 70 // ~626 lm
+#define HALFSPEED_LEVEL 23
+#define QUARTERSPEED_LEVEL 6
+
+#define RAMP_SMOOTH_FLOOR 1 // ~2.5 lm
+#define RAMP_SMOOTH_CEIL 120 // ~5400 lm
+// 20, 36, 53, [70], 86, 103, 120
+#define RAMP_DISCRETE_FLOOR 20 // 35 lm
+#define RAMP_DISCRETE_CEIL 120 // ~5400 lm
+#define RAMP_DISCRETE_STEPS 7 // 35, 108, 280, 626, 1500, 2930, 5400 lm
+
+#define USE_TENCLICK_THERMAL_CONFIG // by request
+#define THERM_FASTER_LEVEL 125 // throttle back faster when high (>6000 lm)
+#define THERM_HARD_TURBO_DROP // this light is massively overpowered
+
diff --git a/spaghetti-monster/fireflies-ui/Makefile b/spaghetti-monster/fireflies-ui/Makefile
index 8db198e..0b59898 100644
--- a/spaghetti-monster/fireflies-ui/Makefile
+++ b/spaghetti-monster/fireflies-ui/Makefile
@@ -2,6 +2,6 @@ all:
./build-all.sh
clean:
- rm -f *.hex cfg-*.h *~ *.elf *.o
+ rm -f *.hex cfg-ff-[pr]*.h *~ *.elf *.o
.phony: clean
diff --git a/spaghetti-monster/fireflies-ui/build-all.sh b/spaghetti-monster/fireflies-ui/build-all.sh
index 41d92d0..81ebd97 100755
--- a/spaghetti-monster/fireflies-ui/build-all.sh
+++ b/spaghetti-monster/fireflies-ui/build-all.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-cp -av ../anduril/cfg-ff*.h .
+cp -av --no-clobber ../anduril/cfg-ff*.h .
UI=fireflies-ui
diff --git a/spaghetti-monster/fireflies-ui/cfg-ff-e01.h b/spaghetti-monster/fireflies-ui/cfg-ff-e01.h
new file mode 100644
index 0000000..42c23b2
--- /dev/null
+++ b/spaghetti-monster/fireflies-ui/cfg-ff-e01.h
@@ -0,0 +1,44 @@
+// Fireflies EDC thrower config options for Fireflies UI
+// (uses PL47 driver)
+#include "hwdef-FF_PL47.h"
+
+// disable indicator LED; it's hardwired
+#ifdef USE_INDICATOR_LED
+#undef USE_INDICATOR_LED
+#endif
+
+// don't do this
+#undef BLINK_AT_RAMP_MIDDLE
+#undef BLINK_AT_RAMP_CEILING
+
+// ramp shape and size
+#define RAMP_LENGTH 150
+
+// driver is a FET + 3x7135, ~413 lm at highest regulated level
+// ../../../bin/level_calc.py seventh 2 150 7135 1 12 414 FET 2 10 1930
+#define PWM1_LEVELS 1,1,2,2,3,3,4,4,5,5,6,6,7,8,8,9,10,10,11,12,13,14,15,15,16,17,18,20,21,22,23,24,26,27,28,30,31,33,34,36,38,39,41,43,45,47,49,51,53,56,58,60,63,65,68,71,74,77,80,83,86,89,93,96,100,103,107,111,115,119,124,128,132,137,142,147,152,157,163,168,174,180,186,192,198,204,211,218,225,232,240,247,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0
+#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,5,7,9,12,14,16,19,22,24,27,30,33,36,39,42,45,48,52,55,58,62,66,69,73,77,81,85,90,94,98,103,107,112,117,122,127,132,137,143,148,154,160,166,172,178,184,191,197,204,211,218,225,232,240,247,255
+#define MAX_1x7135 93
+#define HALFSPEED_LEVEL 14
+#define QUARTERSPEED_LEVEL 7
+
+#define MIN_THERM_STEPDOWN 65 // lowest value it'll step down to
+
+
+// ceiling is level 130/150 (50% power)
+#define RAMP_SMOOTH_FLOOR 1
+#define RAMP_SMOOTH_CEIL 130
+
+// 20, 56, [93], 130 (93 is highest regulated)
+// (8 / 102 / 413 / 1163 + 1930 lm)
+#define RAMP_DISCRETE_FLOOR 20
+#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
+#define RAMP_DISCRETE_STEPS 4
+
+// ~25 lm to ~400 lm
+#define MUGGLE_FLOOR 30
+#define MUGGLE_CEILING MAX_1x7135
+
+// throttle back faster when high
+#define THERM_FASTER_LEVEL 130
+
diff --git a/spaghetti-monster/fireflies-ui/cfg-ff-edc-thrower.h b/spaghetti-monster/fireflies-ui/cfg-ff-e07-2.h
index 31be0ef..48f9c15 100644
--- a/spaghetti-monster/fireflies-ui/cfg-ff-edc-thrower.h
+++ b/spaghetti-monster/fireflies-ui/cfg-ff-e07-2.h
@@ -1,20 +1,20 @@
-// Fireflies EDC thrower config options for Fireflies UI
+// Fireflies E07-2 config options for Anduril / FFUI
+// mostly the same as PL47
#include "cfg-ff-pl47.h"
-// disable indicator LED
-#undef USE_INDICATOR_LED
-
-// ceiling is level 130/150 (50% power)
+// ceiling is level 130/150 (50% power)
#undef RAMP_SMOOTH_CEIL
#define RAMP_SMOOTH_CEIL 130
-// 36, 83, 130 (83 is highest regulated)
+// 20, 56, 93, 130 (83 is highest regulated)
+// (requested config is 1%, 5%, 25%, 50%, double-click-turbo)
+// (but this doesn't allow us to hit level 83)
#undef RAMP_DISCRETE_FLOOR
-#define RAMP_DISCRETE_FLOOR 36
+#define RAMP_DISCRETE_FLOOR 20
#undef RAMP_DISCRETE_CEIL
#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
#undef RAMP_DISCRETE_STEPS
-#define RAMP_DISCRETE_STEPS 3
+#define RAMP_DISCRETE_STEPS 4
// regulate down faster when the FET is active, slower otherwise
#undef THERM_FASTER_LEVEL
diff --git a/spaghetti-monster/fireflies-ui/fireflies-ui.c b/spaghetti-monster/fireflies-ui/fireflies-ui.c
index 0fc2a1d..2c3e60b 100644
--- a/spaghetti-monster/fireflies-ui/fireflies-ui.c
+++ b/spaghetti-monster/fireflies-ui/fireflies-ui.c
@@ -33,7 +33,7 @@
// or too short)
#define MOON_TIMING_HINT
// short blips while ramping
-#define BLINK_AT_CHANNEL_BOUNDARIES
+#define BLINK_AT_RAMP_MIDDLE
//#define BLINK_AT_RAMP_FLOOR
#define BLINK_AT_RAMP_CEILING
//#define BLINK_AT_STEPS // whenever a discrete ramp mode is passed in smooth mode
@@ -189,6 +189,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
@@ -226,6 +229,12 @@ typedef enum {
#define USE_PSEUDO_RAND
#endif
+#if defined(USE_CANDLE_MODE)
+#ifndef USE_TRIANGLE_WAVE
+#define USE_TRIANGLE_WAVE
+#endif
+#endif
+
#include "spaghetti-monster.h"
@@ -242,6 +251,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);
@@ -250,6 +263,7 @@ uint8_t strobe_state(Event event, uint16_t arg);
uint8_t boring_strobe_state(Event event, uint16_t arg);
volatile uint8_t boring_strobe_type = 0;
void sos_blink(uint8_t num, uint8_t dah);
+#define strobe_state boring_strobe_state // use the right strobes
#define NUM_BORING_STROBES 2
#endif
#ifdef USE_BATTCHECK
@@ -271,10 +285,12 @@ uint8_t beacon_config_state(Event event, uint16_t arg);
// soft lockout
#define MOON_DURING_LOCKOUT_MODE
// if enabled, 2nd lockout click goes to the other ramp's floor level
-//#define LOCKOUT_MOON_FANCY
+#define LOCKOUT_MOON_FANCY
uint8_t lockout_state(Event event, uint16_t arg);
// momentary / signalling mode
uint8_t momentary_state(Event event, uint16_t arg);
+uint8_t momentary_mode = 0; // 0 = ramping, 1 = strobe
+uint8_t momentary_active = 0; // boolean, true if active *right now*
#ifdef USE_MUGGLE_MODE
// muggle mode, super-simple, hard to exit
uint8_t muggle_state(Event event, uint16_t arg);
@@ -287,6 +303,7 @@ uint8_t number_entry_state(Event event, uint16_t arg);
volatile uint8_t number_entry_value;
void blink_confirm(uint8_t num);
+void blip();
#if defined(USE_INDICATOR_LED) && defined(TICK_DURING_STANDBY)
void indicator_blink(uint8_t arg);
#endif
@@ -299,6 +316,9 @@ void save_config_wl();
#endif
// default ramp options if not overridden earlier per-driver
+#ifndef RAMP_STYLE
+#define RAMP_STYLE 0 // smooth default
+#endif
#ifndef RAMP_SMOOTH_FLOOR
#define RAMP_SMOOTH_FLOOR 1
#endif
@@ -319,10 +339,30 @@ void save_config_wl();
#define RAMP_DISCRETE_STEPS 7
#endif
+// mile marker(s) partway up the ramp
+// default: blink only at border between regulated and FET
+#ifdef BLINK_AT_RAMP_MIDDLE
+ #if PWM_CHANNELS >= 3
+ #ifndef BLINK_AT_RAMP_MIDDLE_1
+ #define BLINK_AT_RAMP_MIDDLE_1 MAX_Nx7135
+ #ifndef BLINK_AT_RAMP_MIDDLE_2
+ #define BLINK_AT_RAMP_MIDDLE_2 MAX_1x7135
+ #endif
+ #endif
+ #else
+ #ifndef BLINK_AT_RAMP_MIDDLE_1
+ #define BLINK_AT_RAMP_MIDDLE_1 MAX_1x7135
+ #endif
+ #endif
+#endif
+
// brightness control
-uint8_t memorized_level = MAX_1x7135;
+#ifndef DEFAULT_LEVEL
+#define DEFAULT_LEVEL MAX_1x7135
+#endif
+uint8_t memorized_level = DEFAULT_LEVEL;
// smooth vs discrete ramping
-volatile uint8_t ramp_style = 0; // 0 = smooth, 1 = discrete
+volatile uint8_t ramp_style = RAMP_STYLE; // 0 = smooth, 1 = discrete
volatile uint8_t ramp_smooth_floor = RAMP_SMOOTH_FLOOR;
volatile uint8_t ramp_smooth_ceil = RAMP_SMOOTH_CEIL;
volatile uint8_t ramp_discrete_floor = RAMP_DISCRETE_FLOOR;
@@ -400,6 +440,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
@@ -448,10 +491,7 @@ uint8_t off_state(Event event, uint16_t arg) {
#ifdef MOON_TIMING_HINT
if (arg == 0) {
// let the user know they can let go now to stay at moon
- uint8_t temp = actual_level;
- set_level(0);
- delay_4ms(2);
- set_level(temp);
+ blip();
} else
#endif
// don't start ramping immediately;
@@ -531,8 +571,26 @@ uint8_t off_state(Event event, uint16_t arg) {
return MISCHIEF_MANAGED;
}
#endif
- // 7 clicks: temperature check
+ #ifdef USE_INDICATOR_LED
+ // 7 clicks: change indicator LED mode
else if (event == EV_7clicks) {
+ uint8_t mode = (indicator_led_mode & 3) + 1;
+ #ifdef TICK_DURING_STANDBY
+ mode = mode & 3;
+ #else
+ mode = mode % 3;
+ #endif
+ #ifdef INDICATOR_LED_SKIP_LOW
+ if (mode == 1) { mode ++; }
+ #endif
+ indicator_led_mode = (indicator_led_mode & 0b11111100) | mode;
+ indicator_led(mode);
+ save_config();
+ return MISCHIEF_MANAGED;
+ }
+ #endif
+ // 8 clicks: temperature check
+ else if (event == EV_8clicks) {
set_state(tempcheck_state, 0);
return MISCHIEF_MANAGED;
}
@@ -562,6 +620,7 @@ uint8_t steady_state(Event event, uint16_t arg) {
// turn LED on when we first enter the mode
if ((event == EV_enter_state) || (event == EV_reenter_state)) {
+ momentary_mode = 0; // 0 = ramping, 1 = strobes
// if we just got back from config mode, go back to memorized level
if (event == EV_reenter_state) {
arg = memorized_level;
@@ -616,8 +675,7 @@ uint8_t steady_state(Event event, uint16_t arg) {
#ifdef START_AT_MEMORIZED_LEVEL
save_config_wl();
#endif
- set_level(0);
- delay_4ms(20/4);
+ blip();
set_level(memorized_level);
return MISCHIEF_MANAGED;
}
@@ -635,9 +693,13 @@ uint8_t steady_state(Event event, uint16_t arg) {
return MISCHIEF_MANAGED;
}
#ifdef USE_REVERSING
- // make it ramp down instead, if already at max
- if ((arg <= 1) && (actual_level >= mode_max)) {
- ramp_direction = -1;
+ // fix ramp direction on first frame if necessary
+ if (!arg) {
+ // make it ramp down instead, if already at max
+ if (actual_level >= mode_max) { ramp_direction = -1; }
+ // make it ramp up if already at min
+ // (off->hold->stepped_min->release causes this state)
+ else if (actual_level <= mode_min) { ramp_direction = 1; }
}
memorized_level = nearest_level((int16_t)actual_level \
+ (ramp_step_size * ramp_direction));
@@ -647,15 +709,15 @@ uint8_t steady_state(Event event, uint16_t arg) {
#ifdef USE_THERMAL_REGULATION
target_level = memorized_level;
#endif
- #if defined(BLINK_AT_RAMP_CEILING) || defined(BLINK_AT_CHANNEL_BOUNDARIES)
+ #if defined(BLINK_AT_RAMP_CEILING) || defined(BLINK_AT_RAMP_MIDDLE)
// only blink once for each threshold
if ((memorized_level != actual_level) && (
0 // for easier syntax below
- #ifdef BLINK_AT_CHANNEL_BOUNDARIES
- || (memorized_level == MAX_1x7135)
- #if PWM_CHANNELS >= 3
- || (memorized_level == MAX_Nx7135)
+ #ifdef BLINK_AT_RAMP_MIDDLE_1
+ || (memorized_level == BLINK_AT_RAMP_MIDDLE_1)
#endif
+ #ifdef BLINK_AT_RAMP_MIDDLE_2
+ || (memorized_level == BLINK_AT_RAMP_MIDDLE_2)
#endif
#ifdef BLINK_AT_RAMP_CEILING
|| (memorized_level == mode_max)
@@ -664,8 +726,7 @@ uint8_t steady_state(Event event, uint16_t arg) {
|| (memorized_level == mode_min)
#endif
)) {
- set_level(0);
- delay_4ms(8/4);
+ blip();
}
#endif
#if defined(BLINK_AT_STEPS)
@@ -679,8 +740,7 @@ uint8_t steady_state(Event event, uint16_t arg) {
(memorized_level == nearest)
)
{
- set_level(0);
- delay_4ms(8/4);
+ blip();
}
#endif
set_level(memorized_level);
@@ -712,22 +772,21 @@ uint8_t steady_state(Event event, uint16_t arg) {
#ifdef USE_THERMAL_REGULATION
target_level = memorized_level;
#endif
- #if defined(BLINK_AT_RAMP_FLOOR) || defined(BLINK_AT_CHANNEL_BOUNDARIES)
+ #if defined(BLINK_AT_RAMP_FLOOR) || defined(BLINK_AT_RAMP_MIDDLE)
// only blink once for each threshold
if ((memorized_level != actual_level) && (
0 // for easier syntax below
- #ifdef BLINK_AT_CHANNEL_BOUNDARIES
- || (memorized_level == MAX_1x7135)
- #if PWM_CHANNELS >= 3
- || (memorized_level == MAX_Nx7135)
+ #ifdef BLINK_AT_RAMP_MIDDLE_1
+ || (memorized_level == BLINK_AT_RAMP_MIDDLE_1)
#endif
+ #ifdef BLINK_AT_RAMP_MIDDLE_2
+ || (memorized_level == BLINK_AT_RAMP_MIDDLE_2)
#endif
#ifdef BLINK_AT_RAMP_FLOOR
|| (memorized_level == mode_min)
#endif
)) {
- set_level(0);
- delay_4ms(8/4);
+ blip();
}
#endif
#if defined(BLINK_AT_STEPS)
@@ -741,8 +800,7 @@ uint8_t steady_state(Event event, uint16_t arg) {
(memorized_level == nearest)
)
{
- set_level(0);
- delay_4ms(8/4);
+ blip();
}
#endif
set_level(memorized_level);
@@ -813,10 +871,7 @@ uint8_t steady_state(Event event, uint16_t arg) {
// overheating: drop by an amount proportional to how far we are above the ceiling
else if (event == EV_temperature_high) {
#if 0
- uint8_t foo = actual_level;
- set_level(0);
- delay_4ms(2);
- set_level(foo);
+ blip();
#endif
#ifdef THERM_HARD_TURBO_DROP
if (actual_level > THERM_FASTER_LEVEL) {
@@ -844,10 +899,7 @@ uint8_t steady_state(Event event, uint16_t arg) {
// (proportional to how low we are)
else if (event == EV_temperature_low) {
#if 0
- uint8_t foo = actual_level;
- set_level(0);
- delay_4ms(2);
- set_level(foo);
+ blip();
#endif
if (actual_level < target_level) {
//int16_t stepup = actual_level + (arg>>1);
@@ -867,12 +919,79 @@ 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;
+ static uint8_t prev_tint = 0;
+ // don't activate auto-tint modes unless the user hits the edge
+ // and keeps pressing for a while
+ static uint8_t past_edge_counter = 0;
+ // bugfix: click-click-hold from off to strobes would invoke tint ramping
+ // in addition to changing state... so ignore any tint-ramp events which
+ // don't look like they were meant to be here
+ static uint8_t active = 0;
+
+ // click, click, hold: change the tint
+ if (event == EV_click3_hold) {
+ // reset at beginning of movement
+ if (! arg) {
+ active = 1; // first frame means this is for us
+ past_edge_counter = 0; // doesn't start until user hits the edge
+ }
+ // ignore event if we weren't the ones who handled the first frame
+ if (! active) return EVENT_HANDLED;
+
+ // change normal tints
+ if ((tint_ramp_direction > 0) && (tint < 254)) {
+ tint += 1;
+ }
+ else if ((tint_ramp_direction < 0) && (tint > 1)) {
+ tint -= 1;
+ }
+ // if the user kept pressing long enough, go the final step
+ if (past_edge_counter == 64) {
+ past_edge_counter ++;
+ tint ^= 1; // 0 -> 1, 254 -> 255
+ blip();
+ }
+ // if tint change stalled, let user know we hit the edge
+ else if (prev_tint == tint) {
+ if (past_edge_counter == 0) blip();
+ // count up but don't wrap back to zero
+ if (past_edge_counter < 255) past_edge_counter ++;
+ }
+ prev_tint = tint;
+ set_level(actual_level);
+ return EVENT_HANDLED;
+ }
+
+ // click, click, hold, release: reverse direction for next ramp
+ else if (event == EV_click3_hold_release) {
+ active = 0; // ignore next hold if it wasn't meant for us
+ // reverse
+ 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) {
+ static int8_t ramp_direction = 1;
+
// 'st' reduces ROM size by avoiding access to a volatile var
// (maybe I should just make it nonvolatile?)
strobe_mode_te st = strobe_type;
+ momentary_mode = 1; // 0 = ramping, 1 = strobes
+
#ifdef USE_CANDLE_MODE
// pass all events to candle mode, when it's active
// (the code is in its own pseudo-state to keep things cleaner)
@@ -882,11 +1001,11 @@ uint8_t strobe_state(Event event, uint16_t arg) {
#endif
if (0) {} // placeholder
- /* not used any more
+ // init anything which needs to be initialized
else if (event == EV_enter_state) {
+ ramp_direction = 1;
return MISCHIEF_MANAGED;
}
- */
// 1 click: off
else if (event == EV_1click) {
set_state(off_state, 0);
@@ -911,7 +1030,11 @@ uint8_t strobe_state(Event event, uint16_t arg) {
else if (st == party_strobe_e) {
#endif
if ((arg & 1) == 0) {
- if (strobe_delays[st] > 8) strobe_delays[st] --;
+ uint8_t d = strobe_delays[st];
+ d -= ramp_direction;
+ if (d < 8) d = 8;
+ else if (d > 254) d = 254;
+ strobe_delays[st] = d;
}
}
#endif
@@ -922,17 +1045,27 @@ uint8_t strobe_state(Event event, uint16_t arg) {
// biking mode brighter
#ifdef USE_BIKE_FLASHER_MODE
else if (st == bike_flasher_e) {
- if (bike_flasher_brightness < MAX_BIKING_LEVEL)
- bike_flasher_brightness ++;
+ bike_flasher_brightness += ramp_direction;
+ if (bike_flasher_brightness < 2) bike_flasher_brightness = 2;
+ else if (bike_flasher_brightness > MAX_BIKING_LEVEL) bike_flasher_brightness = MAX_BIKING_LEVEL;
set_level(bike_flasher_brightness);
}
#endif
return MISCHIEF_MANAGED;
}
+ // reverse ramp direction on hold release
+ // ... and save new strobe settings
+ else if (event == EV_click1_hold_release) {
+ ramp_direction = -ramp_direction;
+ save_config();
+ return MISCHIEF_MANAGED;
+ }
// click, hold: change speed (go slower)
// or change brightness (dimmer)
else if (event == EV_click2_hold) {
+ ramp_direction = 1;
+
if (0) {} // placeholder
// party / tactical strobe slower
@@ -963,14 +1096,16 @@ uint8_t strobe_state(Event event, uint16_t arg) {
return MISCHIEF_MANAGED;
}
// release hold: save new strobe settings
- else if ((event == EV_click1_hold_release)
- || (event == EV_click2_hold_release)) {
+ else if (event == EV_click2_hold_release) {
save_config();
return MISCHIEF_MANAGED;
}
#if defined(USE_LIGHTNING_MODE) || defined(USE_CANDLE_MODE)
// clock tick: bump the random seed
else if (event == EV_tick) {
+ // un-reverse after 1 second
+ if (arg == TICKS_PER_SECOND) ramp_direction = 1;
+
pseudo_rand_seed += arg;
return MISCHIEF_MANAGED;
}
@@ -1012,7 +1147,7 @@ inline void lightning_storm_iter() {
//rand_time = 1 << (pseudo_rand() % 7);
rand_time = pseudo_rand() & 63;
brightness = 1 << (pseudo_rand() % 7); // 1, 2, 4, 8, 16, 32, 64
- brightness += 1 << (pseudo_rand() & 0x03); // 2 to 80 now
+ brightness += 1 << (pseudo_rand() % 5); // 2 to 80 now
brightness += pseudo_rand() % brightness; // 2 to 159 now (w/ low bias)
if (brightness > MAX_LEVEL) brightness = MAX_LEVEL;
set_level(brightness);
@@ -1067,17 +1202,19 @@ 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)
+ static int8_t ramp_direction = 1;
+ #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
@@ -1085,6 +1222,7 @@ uint8_t candle_mode_state(Event event, uint16_t arg) {
if (event == EV_enter_state) {
candle_mode_timer = 0; // in case any time was left over from earlier
+ ramp_direction = 1;
return MISCHIEF_MANAGED;
}
// 2 clicks: cancel timer
@@ -1096,12 +1234,25 @@ uint8_t candle_mode_state(Event event, uint16_t arg) {
}
// hold: change brightness (brighter)
else if (event == EV_click1_hold) {
- if (candle_mode_brightness < MAX_CANDLE_LEVEL)
- candle_mode_brightness ++;
+ // ramp away from extremes
+ if (! arg) {
+ if (candle_mode_brightness >= MAX_CANDLE_LEVEL) { ramp_direction = -1; }
+ else if (candle_mode_brightness <= 1) { ramp_direction = 1; }
+ }
+ // change brightness, but not too far
+ candle_mode_brightness += ramp_direction;
+ if (candle_mode_brightness < 1) candle_mode_brightness = 1;
+ else if (candle_mode_brightness > MAX_CANDLE_LEVEL) candle_mode_brightness = MAX_CANDLE_LEVEL;
+ return MISCHIEF_MANAGED;
+ }
+ // reverse ramp direction on hold release
+ else if (event == EV_click1_hold_release) {
+ ramp_direction = -ramp_direction;
return MISCHIEF_MANAGED;
}
// click, hold: change brightness (dimmer)
else if (event == EV_click2_hold) {
+ ramp_direction = 1;
if (candle_mode_brightness > 1)
candle_mode_brightness --;
return MISCHIEF_MANAGED;
@@ -1119,10 +1270,13 @@ uint8_t candle_mode_state(Event event, uint16_t arg) {
}
// clock tick: animate candle brightness
else if (event == EV_tick) {
+ // un-reverse after 1 second
+ if (arg == TICKS_PER_SECOND) ramp_direction = 1;
+
// 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;
}
@@ -1139,7 +1293,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;
@@ -1147,6 +1301,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;
@@ -1159,8 +1314,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;
}
@@ -1168,17 +1325,13 @@ 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;
}
-
-uint8_t triangle_wave(uint8_t phase) {
- uint8_t result = phase << 1;
- if (phase > 127) result = 255 - result;
- return result;
-}
#endif // #ifdef USE_CANDLE_MODE
@@ -1189,6 +1342,8 @@ uint8_t boring_strobe_state(Event event, uint16_t arg) {
// (maybe I should just make it nonvolatile?)
uint8_t st = boring_strobe_type;
+ momentary_mode = 1; // 0 = ramping, 1 = strobes
+
if (event == EV_enter_state) {
return MISCHIEF_MANAGED;
}
@@ -1492,14 +1647,24 @@ uint8_t lockout_state(Event event, uint16_t arg) {
uint8_t momentary_state(Event event, uint16_t arg) {
// TODO: momentary strobe here? (for light painting)
+ // init strobe mode, if relevant
+ if ((event == EV_enter_state) && (momentary_mode == 1)) {
+ strobe_state(event, arg);
+ }
+
// light up when the button is pressed; go dark otherwise
// button is being held
if ((event & (B_CLICK | B_PRESS)) == (B_CLICK | B_PRESS)) {
- set_level(memorized_level);
+ momentary_active = 1;
+ // 0 = ramping, 1 = strobes
+ if (momentary_mode == 0) {
+ set_level(memorized_level);
+ }
return MISCHIEF_MANAGED;
}
// button was released
else if ((event & (B_CLICK | B_PRESS)) == (B_CLICK)) {
+ momentary_active = 0;
set_level(0);
//go_to_standby = 1; // sleep while light is off
return MISCHIEF_MANAGED;
@@ -1510,10 +1675,18 @@ uint8_t momentary_state(Event event, uint16_t arg) {
// with exiting via tailcap loosen+tighten unless you leave power
// disconnected for several seconds, so we want to be awake when that
// happens to speed up the process)
- else if ((event == EV_tick) && (actual_level == 0)) {
- if (arg > TICKS_PER_SECOND*15) { // sleep after 15 seconds
- go_to_standby = 1; // sleep while light is off
- // TODO: lighted button should use lockout config?
+ else if (event == EV_tick) {
+ if (momentary_active) {
+ // 0 = ramping, 1 = strobes
+ if (momentary_mode == 1) {
+ return strobe_state(event, arg);
+ }
+ }
+ else {
+ if (arg > TICKS_PER_SECOND*15) { // sleep after 15 seconds
+ go_to_standby = 1; // sleep while light is off
+ // TODO: lighted button should use lockout config?
+ }
}
return MISCHIEF_MANAGED;
}
@@ -1647,12 +1820,13 @@ uint8_t muggle_state(Event event, uint16_t arg) {
#ifdef USE_THERMAL_REGULATION
// overheating is handled specially in muggle mode
else if(event == EV_temperature_high) {
- // don't even try...
- // go immediately to the bottom, in case someone put the light on
- // maximum while wrapped in dark-colored flammable insulation
- // or something, because muggles are cool like that
- // memorized_level = MUGGLE_FLOOR; // override memory? maybe not
- set_level(MUGGLE_FLOOR);
+ #if 0
+ blip();
+ #endif
+ // step down proportional to the amount of overheating
+ uint8_t new = actual_level - arg;
+ if (new < MUGGLE_FLOOR) { new = MUGGLE_FLOOR; }
+ set_level(new);
return MISCHIEF_MANAGED;
}
#endif
@@ -1750,14 +1924,15 @@ void thermal_config_save() {
// calibrate room temperature
val = config_state_values[0];
if (val) {
- int8_t rawtemp = (temperature >> 1) - therm_cal_offset;
+ int8_t rawtemp = temperature - therm_cal_offset;
therm_cal_offset = val - rawtemp;
+ reset_thermal_history = 1; // invalidate all recent temperature data
}
val = config_state_values[1];
if (val) {
// set maximum heat limit
- therm_ceil = 30 + val;
+ therm_ceil = 30 + val - 1;
}
if (therm_ceil > MAX_THERM_CEIL) therm_ceil = MAX_THERM_CEIL;
}
@@ -1786,9 +1961,9 @@ uint8_t beacon_config_state(Event event, uint16_t arg) {
inline void beacon_mode_iter() {
// one iteration of main loop()
set_level(memorized_level);
- nice_delay_ms(500);
+ nice_delay_ms(100);
set_level(0);
- nice_delay_ms(((beacon_seconds) * 1000) - 500);
+ nice_delay_ms(((beacon_seconds) * 1000) - 100);
}
#endif // #ifdef USE_BEACON_MODE
@@ -1920,6 +2095,14 @@ void blink_confirm(uint8_t num) {
}
}
+// Just go dark for a moment to indicate to user that something happened
+void blip() {
+ uint8_t temp = actual_level;
+ set_level(0);
+ delay_4ms(3);
+ set_level(temp);
+}
+
#if defined(USE_INDICATOR_LED) && defined(TICK_DURING_STANDBY)
// beacon-like mode for the indicator LED
@@ -1955,6 +2138,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];
@@ -1993,6 +2179,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];
@@ -2092,14 +2281,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
}
@@ -2110,7 +2304,8 @@ void loop() {
if (0) {}
#ifdef USE_STROBE_STATE
- else if (state == strobe_state) {
+ else if ((state == strobe_state)
+ || ((state == momentary_state) && (momentary_mode == 1) && (momentary_active)) ) { // also handle momentary strobes
uint8_t st = strobe_type;
switch(st) {
@@ -2142,7 +2337,8 @@ void loop() {
#endif // #ifdef USE_STROBE_STATE
#ifdef USE_BORING_STROBE_STATE
- else if (state == boring_strobe_state) {
+ else if ((state == boring_strobe_state)
+ || ((state == momentary_state) && (momentary_mode == 1) && (momentary_active)) ) { // also handle momentary strobes
switch(boring_strobe_type) {
#ifdef USE_POLICE_STROBE_MODE
case 0: // police strobe
@@ -2174,7 +2370,7 @@ void loop() {
#ifdef USE_THERMAL_REGULATION
// TODO: blink out therm_ceil during thermal_config_state?
else if (state == tempcheck_state) {
- blink_num(temperature>>1);
+ blink_num(temperature);
nice_delay_ms(1000);
}
#endif
diff --git a/spaghetti-monster/fsm-adc.c b/spaghetti-monster/fsm-adc.c
index 8decd9d..6832e32 100644
--- a/spaghetti-monster/fsm-adc.c
+++ b/spaghetti-monster/fsm-adc.c
@@ -20,27 +20,76 @@
#ifndef FSM_ADC_C
#define FSM_ADC_C
-#ifdef USE_VOLTAGE_DIVIDER
-// 1.1V / pin7
-#define ADMUX_VOLTAGE ADMUX_VOLTAGE_DIVIDER
-#else
-// VCC / 1.1V reference
-#define ADMUX_VOLTAGE ADMUX_VCC
-#endif
+inline void set_admux_therm() {
+ #if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) || (ATTINY == 1634)
+ ADMUX = ADMUX_THERM;
+ #elif (ATTINY == 841)
+ ADMUXA = ADMUXA_THERM;
+ ADMUXB = ADMUXB_THERM;
+ #else
+ #error Unrecognized MCU type
+ #endif
+}
+
+inline void set_admux_voltage() {
+ #if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) || (ATTINY == 1634)
+ #ifdef USE_VOLTAGE_DIVIDER
+ // 1.1V / pin7
+ ADMUX = ADMUX_VOLTAGE_DIVIDER;
+ #else
+ // VCC / 1.1V reference
+ ADMUX = ADMUX_VCC;
+ #endif
+ #elif (ATTINY == 841)
+ #ifdef USE_VOLTAGE_DIVIDER
+ ADMUXA = ADMUXA_VOLTAGE_DIVIDER;
+ ADMUXB = ADMUXB_VOLTAGE_DIVIDER;
+ #else
+ ADMUXA = ADMUXA_VCC;
+ ADMUXB = ADMUXB_VCC;
+ #endif
+ #else
+ #error Unrecognized MCU type
+ #endif
+}
+
+inline void ADC_start_measurement() {
+ #if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) || (ATTINY == 841) || (ATTINY == 1634)
+ ADCSRA |= (1 << ADSC) | (1 << ADIE);
+ #else
+ #error unrecognized MCU type
+ #endif
+}
+
+// set up ADC for reading battery voltage
inline void ADC_on()
{
- // read voltage on VCC by default
- ADMUX = ADMUX_VOLTAGE;
- #ifdef USE_VOLTAGE_DIVIDER
- // disable digital input on divider pin to reduce power consumption
- DIDR0 |= (1 << VOLTAGE_ADC_DIDR);
+ #if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) || (ATTINY == 1634)
+ set_admux_voltage();
+ #ifdef USE_VOLTAGE_DIVIDER
+ // disable digital input on divider pin to reduce power consumption
+ DIDR0 |= (1 << VOLTAGE_ADC_DIDR);
+ #else
+ // disable digital input on VCC pin to reduce power consumption
+ //DIDR0 |= (1 << ADC_DIDR); // FIXME: unsure how to handle for VCC pin
+ #endif
+ #if (ATTINY == 1634)
+ ACSRA |= (1 << ACD); // turn off analog comparator to save power
+ #endif
+ // enable, start, prescale
+ ADCSRA = (1 << ADEN) | (1 << ADSC) | ADC_PRSCL;
+ // end tiny25/45/85
+ #elif (ATTINY == 841)
+ ADCSRB = 0; // Right adjusted, auto trigger bits cleared.
+ //ADCSRA = (1 << ADEN ) | 0b011; // ADC on, prescaler division factor 8.
+ set_admux_voltage();
+ // enable, start, prescale
+ ADCSRA = (1 << ADEN) | (1 << ADSC) | ADC_PRSCL;
+ //ADCSRA |= (1 << ADSC); // start measuring
#else
- // disable digital input on VCC pin to reduce power consumption
- //DIDR0 |= (1 << ADC_DIDR); // FIXME: unsure how to handle for VCC pin
+ #error Unrecognized MCU type
#endif
- // enable, start, prescale
- ADCSRA = (1 << ADEN) | (1 << ADSC) | ADC_PRSCL;
}
inline void ADC_off() {
@@ -89,20 +138,19 @@ ISR(ADC_vect) {
// thermal declarations
#ifdef USE_THERMAL_REGULATION
- #define NUM_THERMAL_VALUES 8
- #define NUM_THERMAL_VALUES_HISTORY 16
- #define NUM_THERMAL_PROJECTED_HISTORY 8
+ #ifndef THERMAL_UPDATE_SPEED
+ #define THERMAL_UPDATE_SPEED 2
+ #endif
+ #define NUM_THERMAL_VALUES_HISTORY 8
#define ADC_STEPS 4
- static int16_t temperature_values[NUM_THERMAL_VALUES]; // last few readings in C
- static int16_t temperature_history[NUM_THERMAL_VALUES_HISTORY]; // 14.1 fixed-point
- static int16_t projected_temperature_history[NUM_THERMAL_PROJECTED_HISTORY]; // 14.1 fixed-point
- static uint8_t projected_temperature_history_counter = 0;
+ static uint8_t history_step = 0; // don't update history as often
+ static int16_t temperature_history[NUM_THERMAL_VALUES_HISTORY];
static uint8_t temperature_timer = 0;
static uint8_t overheat_lowpass = 0;
static uint8_t underheat_lowpass = 0;
- #define TEMPERATURE_TIMER_START (THERMAL_WARNING_SECONDS*ADC_CYCLES_PER_SECOND) // N seconds between thermal regulation events
- #define OVERHEAT_LOWPASS_STRENGTH ADC_CYCLES_PER_SECOND // lowpass for one second
- #define UNDERHEAT_LOWPASS_STRENGTH ADC_CYCLES_PER_SECOND // lowpass for one second
+ #define TEMPERATURE_TIMER_START ((THERMAL_WARNING_SECONDS-2)*ADC_CYCLES_PER_SECOND) // N seconds between thermal regulation events
+ #define OVERHEAT_LOWPASS_STRENGTH (ADC_CYCLES_PER_SECOND*2) // lowpass for 2 seconds
+ #define UNDERHEAT_LOWPASS_STRENGTH (ADC_CYCLES_PER_SECOND*2) // lowpass for 2 seconds
#else
#define ADC_STEPS 2
#endif
@@ -114,6 +162,12 @@ ISR(ADC_vect) {
pseudo_rand_seed += measurement;
#endif
+ #if defined(TICK_DURING_STANDBY) && defined(USE_SLEEP_LVP)
+ // only measure battery voltage while asleep
+ if (go_to_standby) adc_step = 1;
+ else
+ #endif
+
adc_step = (adc_step + 1) & (ADC_STEPS-1);
#ifdef USE_LVP
@@ -124,7 +178,7 @@ ISR(ADC_vect) {
if (voltage == 0) {
for(uint8_t i=0; i<NUM_VOLTAGE_VALUES; i++)
voltage_values[i] = measurement;
- voltage = 42; // Life, the Universe, and Everything (*)
+ voltage = 42; // the answer to life, the universe, and the voltage of a full li-ion cell
} else {
uint16_t total = 0;
uint8_t i;
@@ -185,93 +239,84 @@ ISR(ADC_vect) {
// temperature
else if (adc_step == 3) {
// Convert ADC units to Celsius (ish)
- int16_t temp = measurement - 275 + THERM_CAL_OFFSET + therm_cal_offset;
+ int16_t temp = measurement - 275 + THERM_CAL_OFFSET + (int16_t)therm_cal_offset;
// prime on first execution
if (reset_thermal_history) {
reset_thermal_history = 0;
- for(uint8_t i=0; i<NUM_THERMAL_VALUES; i++)
- temperature_values[i] = temp;
+ temperature = temp;
for(uint8_t i=0; i<NUM_THERMAL_VALUES_HISTORY; i++)
- temperature_history[i] = temp<<1;
- for(uint8_t i=0; i<NUM_THERMAL_PROJECTED_HISTORY; i++)
- projected_temperature_history[i] = temp<<1;
- temperature = temp<<1;
+ temperature_history[i] = temp;
} else { // update our current temperature estimate
- uint8_t i;
- int16_t total=0;
-
- // rotate array
- // FIXME: just move the index, don't move the values?
- for(i=0; i<NUM_THERMAL_VALUES-1; i++) {
- temperature_values[i] = temperature_values[i+1];
- total += temperature_values[i];
+ // crude lowpass filter
+ // (limit rate of change to 1 degree per measurement)
+ if (temp > temperature) {
+ temperature ++;
+ } else if (temp < temperature) {
+ temperature --;
}
- temperature_values[i] = temp;
- total += temp;
-
- // Divide back to original range:
- //temperature = total >> 2;
- // More precise method: use noise as extra precision
- // (values are now basically fixed-point, signed 13.2)
- //temperature = total;
- // 14.1 is less prone to overflows
- temperature = total >> 2;
}
// guess what the temperature will be in a few seconds
int16_t pt;
{
- uint8_t i;
int16_t diff;
int16_t t = temperature;
// algorithm tweaking; not really intended to be modified
// how far ahead should we predict?
+ #ifndef THERM_PREDICTION_STRENGTH
#define THERM_PREDICTION_STRENGTH 4
- // how proportional should the adjustments be?
- #define THERM_DIFF_ATTENUATION 3
+ #endif
+ // how proportional should the adjustments be? (not used yet)
+ #ifndef THERM_RESPONSE_MAGNITUDE
+ #define THERM_RESPONSE_MAGNITUDE 128
+ #endif
// acceptable temperature window size in C
- #define THERM_WINDOW_SIZE 10
+ #define THERM_WINDOW_SIZE 5
// highest temperature allowed
- // (convert configured value to 14.1 fixed-point)
- #define THERM_CEIL (((int16_t)therm_ceil)<<1)
- // bottom of target temperature window (14.1 fixed-point)
- #define THERM_FLOOR (THERM_CEIL - (THERM_WINDOW_SIZE<<1))
-
- // rotate measurements and add a new one
- for (i=0; i<NUM_THERMAL_VALUES_HISTORY-1; i++) {
- temperature_history[i] = temperature_history[i+1];
+ #define THERM_CEIL ((int16_t)therm_ceil)
+ // bottom of target temperature window
+ #define THERM_FLOOR (THERM_CEIL - THERM_WINDOW_SIZE)
+
+ // if it's time to rotate the thermal history, do it
+ history_step ++;
+ #if (THERMAL_UPDATE_SPEED == 4) // new value every 4s
+ #define THERM_HISTORY_STEP_MAX 15
+ #elif (THERMAL_UPDATE_SPEED == 2) // new value every 2s
+ #define THERM_HISTORY_STEP_MAX 7
+ #elif (THERMAL_UPDATE_SPEED == 1) // new value every 1s
+ #define THERM_HISTORY_STEP_MAX 3
+ #elif (THERMAL_UPDATE_SPEED == 0) // new value every 0.5s
+ #define THERM_HISTORY_STEP_MAX 1
+ #endif
+ if (0 == (history_step & THERM_HISTORY_STEP_MAX)) {
+ // rotate measurements and add a new one
+ for (uint8_t i=0; i<NUM_THERMAL_VALUES_HISTORY-1; i++) {
+ temperature_history[i] = temperature_history[i+1];
+ }
+ temperature_history[NUM_THERMAL_VALUES_HISTORY-1] = t;
}
- temperature_history[NUM_THERMAL_VALUES_HISTORY-1] = t;
// guess what the temp will be several seconds in the future
// diff = rate of temperature change
//diff = temperature_history[NUM_THERMAL_VALUES_HISTORY-1] - temperature_history[0];
diff = t - temperature_history[0];
+ // slight bias toward zero; ignore very small changes (noise)
+ for (uint8_t z=0; z<3; z++) {
+ if (diff < 0) diff ++;
+ if (diff > 0) diff --;
+ }
// projected_temperature = current temp extended forward by amplified rate of change
//projected_temperature = temperature_history[NUM_THERMAL_VALUES_HISTORY-1] + (diff<<THERM_PREDICTION_STRENGTH);
pt = projected_temperature = t + (diff<<THERM_PREDICTION_STRENGTH);
-
- // store prediction for later averaging
- projected_temperature_history[projected_temperature_history_counter] = pt;
- projected_temperature_history_counter = (projected_temperature_history_counter + 1) & (NUM_THERMAL_PROJECTED_HISTORY-1);
}
- // average prediction to reduce noise
- int16_t avg_projected_temperature = 0;
- uint8_t i;
- for (i = 0;
- (i < NUM_THERMAL_PROJECTED_HISTORY) && (avg_projected_temperature < 16000);
- i++)
- avg_projected_temperature += projected_temperature_history[i];
- avg_projected_temperature /= NUM_THERMAL_PROJECTED_HISTORY;
- //avg_projected_temperature /= i;
-
// cancel counters if appropriate
if (pt > THERM_FLOOR) {
underheat_lowpass = 0; // we're probably not too cold
- } else if (pt < THERM_CEIL) {
+ }
+ if (pt < THERM_CEIL) {
overheat_lowpass = 0; // we're probably not too hot
}
@@ -280,7 +325,7 @@ ISR(ADC_vect) {
} else { // it has been long enough since the last warning
// Too hot?
- if (avg_projected_temperature > THERM_CEIL) {
+ if (pt > THERM_CEIL) {
if (overheat_lowpass < OVERHEAT_LOWPASS_STRENGTH) {
overheat_lowpass ++;
} else {
@@ -288,16 +333,15 @@ ISR(ADC_vect) {
overheat_lowpass = 0;
temperature_timer = TEMPERATURE_TIMER_START;
// how far above the ceiling?
- int16_t howmuch = (avg_projected_temperature - THERM_CEIL) >> THERM_DIFF_ATTENUATION;
- if (howmuch > 0) {
- // try to send out a warning
- emit(EV_temperature_high, howmuch);
- }
+ //int16_t howmuch = (pt - THERM_CEIL) * THERM_RESPONSE_MAGNITUDE / 128;
+ int16_t howmuch = pt - THERM_CEIL;
+ // try to send out a warning
+ emit(EV_temperature_high, howmuch);
}
}
// Too cold?
- else if (avg_projected_temperature < THERM_FLOOR) {
+ else if (pt < THERM_FLOOR) {
if (underheat_lowpass < UNDERHEAT_LOWPASS_STRENGTH) {
underheat_lowpass ++;
} else {
@@ -305,13 +349,12 @@ ISR(ADC_vect) {
underheat_lowpass = 0;
temperature_timer = TEMPERATURE_TIMER_START;
// how far below the floor?
- int16_t howmuch = (THERM_FLOOR - avg_projected_temperature) >> THERM_DIFF_ATTENUATION;
- if (howmuch > 0) {
- // try to send out a warning (unless voltage is low)
- // (LVP and underheat warnings fight each other)
- if (voltage > VOLTAGE_LOW)
- emit(EV_temperature_low, howmuch);
- }
+ //int16_t howmuch = (THERM_FLOOR - pt) * THERM_RESPONSE_MAGNITUDE / 128;
+ int16_t howmuch = THERM_FLOOR - pt;
+ // try to send out a warning (unless voltage is low)
+ // (LVP and underheat warnings fight each other)
+ if (voltage > VOLTAGE_LOW)
+ emit(EV_temperature_low, howmuch);
}
}
}
@@ -322,16 +365,21 @@ ISR(ADC_vect) {
// set the correct type of measurement for next time
#ifdef USE_THERMAL_REGULATION
#ifdef USE_LVP
- if (adc_step < 2) ADMUX = ADMUX_VOLTAGE;
- else ADMUX = ADMUX_THERM;
+ if (adc_step < 2) set_admux_voltage();
+ else set_admux_therm();
#else
- ADMUX = ADMUX_THERM;
+ set_admux_therm();
#endif
#else
#ifdef USE_LVP
- ADMUX = ADMUX_VOLTAGE;
+ set_admux_voltage();
#endif
#endif
+
+ #ifdef TICK_DURING_STANDBY
+ // if we were asleep, go back to sleep
+ if (go_to_standby) ADC_off();
+ #endif
}
#ifdef USE_BATTCHECK
diff --git a/spaghetti-monster/fsm-adc.h b/spaghetti-monster/fsm-adc.h
index 6256e2c..274fb4d 100644
--- a/spaghetti-monster/fsm-adc.h
+++ b/spaghetti-monster/fsm-adc.h
@@ -38,7 +38,7 @@
#define VOLTAGE_FUDGE_FACTOR 5
#endif
#endif
-volatile uint8_t voltage;
+volatile uint8_t voltage = 0;
volatile uint8_t adcint_enable; // kludge, because adc auto-retrigger won't turn off
void low_voltage();
#ifdef USE_BATTCHECK
@@ -84,6 +84,7 @@ volatile uint8_t reset_thermal_history = 1;
inline void ADC_on();
inline void ADC_off();
+inline void ADC_start_measurement();
#endif
diff --git a/spaghetti-monster/fsm-events.c b/spaghetti-monster/fsm-events.c
index 72216ae..362a5cc 100644
--- a/spaghetti-monster/fsm-events.c
+++ b/spaghetti-monster/fsm-events.c
@@ -20,6 +20,7 @@
#ifndef FSM_EVENTS_C
#define FSM_EVENTS_C
+
void empty_event_sequence() {
current_event = EV_none;
// when the user completes an input sequence, interrupt any running timers
@@ -116,26 +117,26 @@ uint8_t nice_delay_ms(uint16_t ms) {
#ifdef USE_RAMPING
uint8_t level = actual_level; // volatile, avoid repeat access
if (level < QUARTERSPEED_LEVEL) {
- CLKPR = 1<<CLKPCE; CLKPR = 2;
+ clock_prescale_set(clock_div_4);
_delay_loop_2(BOGOMIPS*98/100/4);
}
//else if (level < HALFSPEED_LEVEL) {
- // CLKPR = 1<<CLKPCE; CLKPR = 1;
+ // clock_prescale_set(clock_div_2);
// _delay_loop_2(BOGOMIPS*98/100/2);
//}
else {
- CLKPR = 1<<CLKPCE; CLKPR = 0;
+ clock_prescale_set(clock_div_1);
_delay_loop_2(BOGOMIPS*98/100);
}
// restore regular clock speed
- CLKPR = 1<<CLKPCE; CLKPR = 0;
+ clock_prescale_set(clock_div_1);
#else
// underclock MCU to save power
- CLKPR = 1<<CLKPCE; CLKPR = 2;
+ clock_prescale_set(clock_div_4);
// wait
_delay_loop_2(BOGOMIPS*98/100/4);
// restore regular clock speed
- CLKPR = 1<<CLKPCE; CLKPR = 0;
+ clock_prescale_set(clock_div_1);
#endif // ifdef USE_RAMPING
#else
// wait
@@ -159,11 +160,18 @@ uint8_t nice_delay_ms(uint16_t ms) {
void delay_4ms(uint8_t ms) {
while(ms-- > 0) {
// underclock MCU to save power
- CLKPR = 1<<CLKPCE; CLKPR = 2;
+ clock_prescale_set(clock_div_4);
// wait
_delay_loop_2(BOGOMIPS*98/100);
// restore regular clock speed
- CLKPR = 1<<CLKPCE; CLKPR = 0;
+ clock_prescale_set(clock_div_1);
+ }
+}
+#else
+void delay_4ms(uint8_t ms) {
+ while(ms-- > 0) {
+ // wait
+ _delay_loop_2(BOGOMIPS*398/100);
}
}
#endif
diff --git a/spaghetti-monster/fsm-events.h b/spaghetti-monster/fsm-events.h
index 0ebcfd0..39ad3aa 100644
--- a/spaghetti-monster/fsm-events.h
+++ b/spaghetti-monster/fsm-events.h
@@ -43,7 +43,7 @@ static volatile uint16_t ticks_since_last_event = 0;
#define HOLD_TIMEOUT 24
#endif
#ifndef RELEASE_TIMEOUT
-#define RELEASE_TIMEOUT 24
+#define RELEASE_TIMEOUT 18
#endif
/* Event structure
diff --git a/spaghetti-monster/fsm-main.c b/spaghetti-monster/fsm-main.c
index 6f74e9b..e537a9e 100644
--- a/spaghetti-monster/fsm-main.c
+++ b/spaghetti-monster/fsm-main.c
@@ -36,16 +36,8 @@ ISR(TIMER1_COMPA_vect) {
}
#endif
-int main() {
- // Don't allow interrupts while booting
- cli();
-
- #ifdef HALFSPEED
- // run at half speed
- CLKPR = 1<<CLKPCE;
- CLKPR = 1;
- #endif
-
+#if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85)
+inline void hw_setup() {
// configure PWM channels
#if PWM_CHANNELS >= 1
DDRB |= (1 << PWM1_PIN);
@@ -75,6 +67,45 @@ int main() {
// configure e-switch
PORTB = (1 << SWITCH_PIN); // e-switch is the only input
PCMSK = (1 << SWITCH_PIN); // pin change interrupt uses this pin
+}
+#elif (ATTINY == 1634)
+inline void hw_setup() {
+ // this gets tricky with so many pins...
+ // ... so punt it to the hwdef file
+ hwdef_setup();
+}
+#else
+ #error Unrecognized MCU type
+#endif
+
+
+#ifdef USE_REBOOT
+void prevent_reboot_loop() {
+ // prevent WDT from rebooting MCU again
+ MCUSR &= ~(1<<WDRF); // reset status flag
+ wdt_disable();
+}
+#endif
+
+
+int main() {
+ // Don't allow interrupts while booting
+ cli();
+
+ #ifdef USE_REBOOT
+ prevent_reboot_loop();
+ #endif
+
+ hw_setup();
+
+ #if 0
+ #ifdef HALFSPEED
+ // run at half speed
+ // FIXME: not portable (also not needed)
+ CLKPR = 1<<CLKPCE;
+ CLKPR = 1;
+ #endif
+ #endif
#ifdef USE_DEBUG_BLINK
//debug_blink(1);
diff --git a/spaghetti-monster/fsm-misc.c b/spaghetti-monster/fsm-misc.c
index 9f953fa..8e88cbd 100644
--- a/spaghetti-monster/fsm-misc.c
+++ b/spaghetti-monster/fsm-misc.c
@@ -20,6 +20,7 @@
#ifndef FSM_MISC_C
#define FSM_MISC_C
+
#ifdef USE_DYNAMIC_UNDERCLOCKING
void auto_clock_speed() {
uint8_t level = actual_level; // volatile, avoid repeat access
@@ -27,14 +28,14 @@ void auto_clock_speed() {
// run at quarter speed
// note: this only works when executed as two consecutive instructions
// (don't try to combine them or put other stuff between)
- CLKPR = 1<<CLKPCE; CLKPR = 2;
+ clock_prescale_set(clock_div_4);
}
else if (level < HALFSPEED_LEVEL) {
// run at half speed
- CLKPR = 1<<CLKPCE; CLKPR = 1;
+ clock_prescale_set(clock_div_2);
} else {
// run at full speed
- CLKPR = 1<<CLKPCE; CLKPR = 0;
+ clock_prescale_set(clock_div_1);
}
}
#endif
@@ -146,6 +147,34 @@ void indicator_led_auto() {
*/
#endif // USE_INDICATOR_LED
+#ifdef USE_AUX_RGB_LEDS
+void rgb_led_set(uint8_t value) {
+ // value: 0b00BBGGRR
+ uint8_t pins[] = { AUXLED_R_PIN, AUXLED_G_PIN, AUXLED_B_PIN };
+ for (uint8_t i=0; i<3; i++) {
+ uint8_t lvl = (value >> (i<<1)) & 0x03;
+ uint8_t pin = pins[i];
+ switch (lvl) {
+ case 0: // LED off
+ AUXLED_RGB_DDR &= 0xff ^ (1 << pin);
+ AUXLED_RGB_PUE &= 0xff ^ (1 << pin);
+ AUXLED_RGB_PORT &= 0xff ^ (1 << pin);
+ break;
+ case 1: // LED low
+ AUXLED_RGB_DDR &= 0xff ^ (1 << pin);
+ AUXLED_RGB_PUE |= (1 << pin);
+ AUXLED_RGB_PORT |= (1 << pin);
+ break;
+ default: // LED high
+ AUXLED_RGB_DDR |= (1 << pin);
+ AUXLED_RGB_PUE |= (1 << pin);
+ AUXLED_RGB_PORT |= (1 << pin);
+ break;
+ }
+ }
+}
+#endif // ifdef USE_AUX_RGB_LEDS
+
#ifdef USE_TRIANGLE_WAVE
uint8_t triangle_wave(uint8_t phase) {
uint8_t result = phase << 1;
@@ -154,4 +183,21 @@ uint8_t triangle_wave(uint8_t phase) {
}
#endif
+#ifdef USE_REBOOT
+void reboot() {
+ #if 1 // WDT method, safer but larger
+ cli();
+ WDTCR = 0xD8 | WDTO_15MS;
+ sei();
+ wdt_reset();
+ while (1) {}
+ #else // raw assembly method, doesn't reset registers or anything
+ __asm__ __volatile__ (
+ "cli" "\n\t"
+ "rjmp 0x00" "\n\t"
+ );
+ #endif
+}
+#endif
+
#endif
diff --git a/spaghetti-monster/fsm-misc.h b/spaghetti-monster/fsm-misc.h
index 6e41b6c..a39d31a 100644
--- a/spaghetti-monster/fsm-misc.h
+++ b/spaghetti-monster/fsm-misc.h
@@ -43,11 +43,22 @@ uint8_t blink(uint8_t num, uint8_t speed);
*/
#ifdef USE_INDICATOR_LED
+// lvl: 0=off, 1=low, 2=high
void indicator_led(uint8_t lvl);
#endif
+#ifdef USE_AUX_RGB_LEDS
+// value: 0b00BBGGRR
+// each pair of bits: 0=off, 1=low, 2=high
+void rgb_led_set(uint8_t value);
+#endif
+
#ifdef USE_TRIANGLE_WAVE
uint8_t triangle_wave(uint8_t phase);
#endif
+#ifdef USE_REBOOT
+void reboot();
+#endif
+
#endif
diff --git a/spaghetti-monster/fsm-pcint.c b/spaghetti-monster/fsm-pcint.c
index acb627d..4928980 100644
--- a/spaghetti-monster/fsm-pcint.c
+++ b/spaghetti-monster/fsm-pcint.c
@@ -30,7 +30,7 @@ uint8_t button_is_pressed() {
// and wait for measurements to settle to all zeroes or all ones
do {
// shift past readings and add current value
- readings = (readings << 1) | ((PINB & (1<<SWITCH_PIN)) == 0);
+ readings = (readings << 1) | ((SWITCH_PORT & (1<<SWITCH_PIN)) == 0);
// wait a moment
_delay_loop_2(BOGOMIPS/16); // up to 2ms to stabilize
}
@@ -40,21 +40,45 @@ uint8_t button_is_pressed() {
}
inline void PCINT_on() {
- // enable pin change interrupt for pin N
- GIMSK |= (1 << PCIE);
- // only pay attention to the e-switch pin
- //PCMSK = (1 << SWITCH_PCINT);
- // set bits 1:0 to 0b01 (interrupt on rising *and* falling edge) (default)
- // MCUCR &= 0b11111101; MCUCR |= 0b00000001;
+ #if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85)
+ // enable pin change interrupt
+ GIMSK |= (1 << PCIE);
+ // only pay attention to the e-switch pin
+ #if 0 // this is redundant; was already done in main()
+ PCMSK = (1 << SWITCH_PCINT);
+ #endif
+ // set bits 1:0 to 0b01 (interrupt on rising *and* falling edge) (default)
+ // MCUCR &= 0b11111101; MCUCR |= 0b00000001;
+ #elif (ATTINY == 1634)
+ // enable pin change interrupt
+ #ifdef SWITCH2_PCIE
+ GIMSK |= ((1 << SWITCH_PCIE) | (1 << SWITCH2_PCIE));
+ #else
+ GIMSK |= (1 << SWITCH_PCIE);
+ #endif
+ #else
+ #error Unrecognized MCU type
+ #endif
}
inline void PCINT_off() {
- // disable all pin-change interrupts
- GIMSK &= ~(1 << PCIE);
+ #if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85)
+ // disable all pin-change interrupts
+ GIMSK &= ~(1 << PCIE);
+ #elif (ATTINY == 1634)
+ // disable all pin-change interrupts
+ GIMSK &= ~(1 << SWITCH_PCIE);
+ #else
+ #error Unrecognized MCU type
+ #endif
}
//void button_change_interrupt() {
+#if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) || (ATTINY == 1634)
EMPTY_INTERRUPT(PCINT0_vect);
+#else
+ #error Unrecognized MCU type
+#endif
/*
ISR(PCINT0_vect) {
diff --git a/spaghetti-monster/fsm-ramping.c b/spaghetti-monster/fsm-ramping.c
index 082f8c9..efa07e4 100644
--- a/spaghetti-monster/fsm-ramping.c
+++ b/spaghetti-monster/fsm-ramping.c
@@ -30,17 +30,25 @@ void set_level(uint8_t level) {
gradual_target = level;
#endif
- #ifdef USE_INDICATOR_LED
#ifdef USE_INDICATOR_LED_WHILE_RAMPING
- if (! go_to_standby)
- indicator_led((level > 0) + (level > MAX_1x7135));
- //if (level > MAX_1x7135) indicator_led(2);
- //else if (level > 0) indicator_led(1);
- //else if (! go_to_standby) indicator_led(0);
+ #ifdef USE_INDICATOR_LED
+ if (! go_to_standby)
+ indicator_led((level > 0) + (level > MAX_1x7135));
+ #endif
+ //if (level > MAX_1x7135) indicator_led(2);
+ //else if (level > 0) indicator_led(1);
+ //else if (! go_to_standby) indicator_led(0);
#else
- if (! go_to_standby)
- indicator_led(0);
- #endif
+ #if defined(USE_INDICATOR_LED) || defined(USE_AUX_RGB_LEDS)
+ if (! go_to_standby) {
+ #ifdef USE_INDICATOR_LED
+ indicator_led(0);
+ #endif
+ #ifdef USE_AUX_RGB_LEDS
+ rgb_led_set(0);
+ #endif
+ }
+ #endif
#endif
//TCCR0A = PHASE;
diff --git a/spaghetti-monster/fsm-standby.c b/spaghetti-monster/fsm-standby.c
index 7d60c1d..44b047a 100644
--- a/spaghetti-monster/fsm-standby.c
+++ b/spaghetti-monster/fsm-standby.c
@@ -56,7 +56,9 @@ void sleep_until_eswitch_pressed()
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
+ #ifdef BODCR // only do this on MCUs which support it
sleep_bod_disable();
+ #endif
sleep_cpu(); // wait here
// something happened; wake up
diff --git a/spaghetti-monster/fsm-wdt.c b/spaghetti-monster/fsm-wdt.c
index d5bbdb9..6e61e87 100644
--- a/spaghetti-monster/fsm-wdt.c
+++ b/spaghetti-monster/fsm-wdt.c
@@ -25,38 +25,65 @@
void WDT_on()
{
- // interrupt every 16ms
- //cli(); // Disable interrupts
- wdt_reset(); // Reset the WDT
- WDTCR |= (1<<WDCE) | (1<<WDE); // Start timed sequence
- WDTCR = (1<<WDIE); // Enable interrupt every 16ms
- //sei(); // Enable interrupts
+ #if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85)
+ // interrupt every 16ms
+ //cli(); // Disable interrupts
+ wdt_reset(); // Reset the WDT
+ WDTCR |= (1<<WDCE) | (1<<WDE); // Start timed sequence
+ WDTCR = (1<<WDIE); // Enable interrupt every 16ms
+ //sei(); // Enable interrupts
+ #elif (ATTINY == 1634)
+ wdt_reset(); // Reset the WDT
+ WDTCSR = (1<<WDIE); // Enable interrupt every 16ms
+ #else
+ #error Unrecognized MCU type
+ #endif
}
#ifdef TICK_DURING_STANDBY
inline void WDT_slow()
{
- // interrupt slower
- //cli(); // Disable interrupts
- wdt_reset(); // Reset the WDT
- WDTCR |= (1<<WDCE) | (1<<WDE); // Start timed sequence
- WDTCR = (1<<WDIE) | STANDBY_TICK_SPEED; // Enable interrupt every so often
- //sei(); // Enable interrupts
+ #if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85)
+ // interrupt slower
+ //cli(); // Disable interrupts
+ wdt_reset(); // Reset the WDT
+ WDTCR |= (1<<WDCE) | (1<<WDE); // Start timed sequence
+ WDTCR = (1<<WDIE) | STANDBY_TICK_SPEED; // Enable interrupt every so often
+ //sei(); // Enable interrupts
+ #elif (ATTINY == 1634)
+ wdt_reset(); // Reset the WDT
+ WDTCSR = (1<<WDIE) | STANDBY_TICK_SPEED;
+ #else
+ #error Unrecognized MCU type
+ #endif
}
#endif
inline void WDT_off()
{
- //cli(); // Disable interrupts
- wdt_reset(); // Reset the WDT
- MCUSR &= ~(1<<WDRF); // Clear Watchdog reset flag
- WDTCR |= (1<<WDCE) | (1<<WDE); // Start timed sequence
- WDTCR = 0x00; // Disable WDT
- //sei(); // Enable interrupts
+ #if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85)
+ //cli(); // Disable interrupts
+ wdt_reset(); // Reset the WDT
+ MCUSR &= ~(1<<WDRF); // Clear Watchdog reset flag
+ WDTCR |= (1<<WDCE) | (1<<WDE); // Start timed sequence
+ WDTCR = 0x00; // Disable WDT
+ //sei(); // Enable interrupts
+ #elif (ATTINY == 1634)
+ cli(); // needed because CCP, below
+ wdt_reset(); // Reset the WDT
+ MCUSR &= ~(1<<WDRF); // clear watchdog reset flag
+ CCP = 0xD8; // enable config changes
+ WDTCSR = 0; // disable and clear all WDT settings
+ sei();
+ #else
+ #error Unrecognized MCU type
+ #endif
}
// clock tick -- this runs every 16ms (62.5 fps)
ISR(WDT_vect) {
+ static uint8_t adc_trigger = 0;
+
#ifdef TICK_DURING_STANDBY
f_wdt = 1; // WDT event happened
@@ -68,9 +95,16 @@ ISR(WDT_vect) {
// wrap around from 65535 to 32768, not 0
sleep_counter = (sleep_counter + 1) | (sleep_counter & 0x8000);
process_emissions();
- return;
+
+ #if defined(USE_SLEEP_LVP)
+ // stop here, usually... but proceed often enough for sleep LVP to work
+ if (0 != (sleep_counter & 0x7f)) return;
+ adc_trigger = 255; // make sure a measurement will happen
+ #else
+ return; // no sleep LVP needed if nothing drains power while off
+ #endif
}
- sleep_counter = 0;
+ else { sleep_counter = 0; }
#endif
// detect and emit button change events
@@ -136,10 +170,14 @@ ISR(WDT_vect) {
#if defined(USE_LVP) || defined(USE_THERMAL_REGULATION)
// start a new ADC measurement every 4 ticks
- static uint8_t adc_trigger = 0;
adc_trigger ++;
if (0 == (adc_trigger & 3)) {
- ADCSRA |= (1 << ADSC) | (1 << ADIE);
+ #if defined(TICK_DURING_STANDBY) && defined(USE_SLEEP_LVP)
+ // we shouldn't be here unless it woke up for a LVP check...
+ // so enable ADC voltage measurement functions temporarily
+ if (go_to_standby) ADC_on();
+ #endif
+ ADC_start_measurement();
adcint_enable = 1;
}
#endif
diff --git a/spaghetti-monster/fsm-wdt.h b/spaghetti-monster/fsm-wdt.h
index 3c395c1..78fe791 100644
--- a/spaghetti-monster/fsm-wdt.h
+++ b/spaghetti-monster/fsm-wdt.h
@@ -27,6 +27,11 @@ inline void WDT_off();
#ifdef TICK_DURING_STANDBY
volatile uint8_t f_wdt = 0;
+
+ #if defined(USE_INDICATOR_LED) || defined(USE_AUX_RGB_LEDS)
+ // measure battery charge while asleep
+ #define USE_SLEEP_LVP
+ #endif
#endif
#endif
diff --git a/spaghetti-monster/rampingios/rampingiosv3.c b/spaghetti-monster/rampingios/rampingiosv3.c
index e4eb2fa..d72e971 100644
--- a/spaghetti-monster/rampingios/rampingiosv3.c
+++ b/spaghetti-monster/rampingios/rampingiosv3.c
@@ -148,9 +148,6 @@ void blink_confirm(uint8_t num);
#if defined(USE_INDICATOR_LED) && defined(TICK_DURING_STANDBY)
void indicator_blink(uint8_t arg);
#endif
-#ifdef USE_INDICATOR_LED
-uint8_t auxled_next_state(Event event, uint16_t arg);
-#endif
// remember stuff even after battery was changed
void load_config();
@@ -347,7 +344,18 @@ uint8_t off_state(Event event, uint16_t arg) {
// 7 clicks: next aux LED mode
else if (event == EV_7clicks) {
blink_confirm(1);
- set_state(auxled_next_state, 0);
+ uint8_t mode = (indicator_led_mode & 3) + 1;
+ #ifdef TICK_DURING_STANDBY
+ mode = mode & 3;
+ #else
+ mode = mode % 3;
+ #endif
+ #ifdef INDICATOR_LED_SKIP_LOW
+ if (mode == 1) { mode ++; }
+ #endif
+ indicator_led_mode = (indicator_led_mode & 0b11111100) | mode;
+ indicator_led(mode);
+ save_config();
return MISCHIEF_MANAGED;
}
#endif
@@ -811,33 +819,6 @@ uint8_t lockout_state(Event event, uint16_t arg) {
}
-#ifdef USE_INDICATOR_LED
-uint8_t auxled_next_state(Event event, uint16_t arg) {
- if (event == EV_enter_state) {
- uint8_t mode = indicator_led_mode & 3;
- #ifdef TICK_DURING_STANDBY
- mode = (mode + 1) & 3;
- #else
- mode = (mode + 1) % 3;
- #endif
- #ifdef INDICATOR_LED_SKIP_LOW
- if (mode == 1) { mode ++; }
- #endif
- indicator_led_mode = mode + (indicator_led_mode & 0b00001100);
- indicator_led(mode);
- save_config();
- return MISCHIEF_MANAGED;
- }
- else if (event == EV_tick) {
- set_state(off_state, 0);
- return MISCHIEF_MANAGED;
- }
-
- return EVENT_NOT_HANDLED;
-}
-#endif
-
-
uint8_t momentary_state(Event event, uint16_t arg) {
// TODO: momentary strobe here? (for light painting)
diff --git a/spaghetti-monster/spaghetti-monster.h b/spaghetti-monster/spaghetti-monster.h
index 08690b4..853eac3 100644
--- a/spaghetti-monster/spaghetti-monster.h
+++ b/spaghetti-monster/spaghetti-monster.h
@@ -25,6 +25,7 @@
#include "tk-attiny.h"
#include <avr/eeprom.h>
+#include <avr/power.h>
// include project definitions to help with recognizing symbols
#include "fsm-events.h"
diff --git a/tk-attiny.h b/tk-attiny.h
index 3c985f2..947a87c 100644
--- a/tk-attiny.h
+++ b/tk-attiny.h
@@ -28,24 +28,26 @@
/******************** hardware-specific values **************************/
#if (ATTINY == 13)
#define F_CPU 4800000UL
- #define EEPSIZE 64
+ //#define EEPSIZE 64
#define V_REF REFS0
#define BOGOMIPS 950
#define ADMUX_VCC 0b00001100
#define DELAY_ZERO_TIME 252
+ #define SWITCH_PORT PINB // PINA or PINB or PINC
#elif (ATTINY == 25)
// TODO: Use 6.4 MHz instead of 8 MHz?
#define F_CPU 8000000UL
- #define EEPSIZE 128
+ //#define EEPSIZE 128
#define V_REF REFS1
#define BOGOMIPS (F_CPU/4000)
#define ADMUX_VCC 0b00001100
#define ADMUX_THERM 0b10001111
#define DELAY_ZERO_TIME 1020
+ #define SWITCH_PORT PINB // PINA or PINB or PINC
#elif (ATTINY == 85)
// TODO: Use 6.4 MHz instead of 8 MHz?
#define F_CPU 8000000UL
- #define EEPSIZE 512
+ //#define EEPSIZE 512
#define V_REF REFS1
#define BOGOMIPS (F_CPU/4000)
// (1 << V_REF) | (0 << ADLAR) | (VCC_CHANNEL)
@@ -53,10 +55,30 @@
// (1 << V_REF) | (0 << ADLAR) | (THERM_CHANNEL)
#define ADMUX_THERM 0b10001111
#define DELAY_ZERO_TIME 1020
+ #define SWITCH_PORT PINB // PINA or PINB or PINC
+#elif (ATTINY == 1634)
+ #define F_CPU 8000000UL
+ #define V_REF REFS1
+ #define BOGOMIPS (F_CPU/4000)
+ // (1 << V_REF) | (0 << ADLAR) | (VCC_CHANNEL)
+ #define ADMUX_VCC 0b00001101
+ // (1 << V_REF) | (0 << ADLAR) | (THERM_CHANNEL)
+ #define ADMUX_THERM 0b10001110
+ #define DELAY_ZERO_TIME 1020
+ //#define SWITCH_PORT PINA // set this in hwdef
#else
#error Hey, you need to define ATTINY.
#endif
+// auto-detect eeprom size from avr-libc headers
+#ifndef EEPSIZE
+#ifdef E2SIZE
+#define EEPSIZE E2SIZE
+#else
+#define EEPSIZE (E2END+1)
+#endif
+#endif
+
#include <avr/interrupt.h>
@@ -86,4 +108,31 @@
#error Hey, you need to define an I/O pin layout.
#endif
+#if (ATTINY==25) || (ATTINY==45) || (ATTINY==85)
+ // use clock_prescale_set(n) instead; it's safer
+ //#define CLOCK_DIVIDER_SET(n) {CLKPR = 1<<CLKPCE; CLKPR = n;}
+#elif (ATTINY==1634)
+ // make it a NOP for now
+ // FIXME
+ //#define clock_prescale_set(x) ((void)0)
+ //#define clock_prescale_set(n) {cli(); CCP = 0xD8; CLKPR = n; sei();}
+ //#define clock_prescale_set(n) {cli(); CCP = 0xD8; CLKPR = n; sei();}
+ inline void clock_prescale_set(uint8_t n) {cli(); CCP = 0xD8; CLKPR = n; sei();}
+ typedef enum
+ {
+ clock_div_1 = 0,
+ clock_div_2 = 1,
+ clock_div_4 = 2,
+ clock_div_8 = 3,
+ clock_div_16 = 4,
+ clock_div_32 = 5,
+ clock_div_64 = 6,
+ clock_div_128 = 7,
+ clock_div_256 = 8
+ } clock_div_t;
+
+#else
+#error Unable to define MCU macros.
+#endif
+
#endif // TK_ATTINY_H