diff options
Diffstat (limited to 'spaghetti-monster')
| -rw-r--r-- | spaghetti-monster/anduril/anduril.c | 16 | ||||
| -rw-r--r-- | spaghetti-monster/anduril/battcheck-mode.c | 8 | ||||
| -rw-r--r-- | spaghetti-monster/anduril/candle-mode.c | 58 | ||||
| -rw-r--r-- | spaghetti-monster/anduril/config-default.h | 8 | ||||
| -rw-r--r-- | spaghetti-monster/anduril/goodnight-mode.c | 72 | ||||
| -rw-r--r-- | spaghetti-monster/anduril/ramp-mode.c | 37 | ||||
| -rw-r--r-- | spaghetti-monster/anduril/sunset-timer.c | 68 | ||||
| -rw-r--r-- | spaghetti-monster/anduril/sunset-timer.h (renamed from spaghetti-monster/anduril/goodnight-mode.h) | 18 |
8 files changed, 155 insertions, 130 deletions
diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c index 1faf1be..9fe8aee 100644 --- a/spaghetti-monster/anduril/anduril.c +++ b/spaghetti-monster/anduril/anduril.c @@ -97,6 +97,10 @@ #include "aux-leds.h" #include "misc.h" +#ifdef USE_SUNSET_TIMER +#include "sunset-timer.h" +#endif + #ifdef USE_VERSION_CHECK #include "version-check-mode.h" #endif @@ -105,10 +109,6 @@ #include "battcheck-mode.h" #endif -#ifdef USE_GOODNIGHT_MODE -#include "goodnight-mode.h" -#endif - #ifdef USE_BEACON_MODE #include "beacon-mode.h" #endif @@ -152,6 +152,10 @@ #include "aux-leds.c" #include "misc.c" +#ifdef USE_SUNSET_TIMER +#include "sunset-timer.c" +#endif + #ifdef USE_VERSION_CHECK #include "version-check-mode.c" #endif @@ -160,10 +164,6 @@ #include "battcheck-mode.c" #endif -#ifdef USE_GOODNIGHT_MODE -#include "goodnight-mode.c" -#endif - #ifdef USE_BEACON_MODE #include "beacon-mode.c" #endif diff --git a/spaghetti-monster/anduril/battcheck-mode.c b/spaghetti-monster/anduril/battcheck-mode.c index 3755249..c468332 100644 --- a/spaghetti-monster/anduril/battcheck-mode.c +++ b/spaghetti-monster/anduril/battcheck-mode.c @@ -35,13 +35,7 @@ uint8_t battcheck_state(Event event, uint16_t arg) { set_state(off_state, 0); return MISCHIEF_MANAGED; } - #ifdef USE_GOODNIGHT_MODE - // 2 clicks: goodnight mode - else if (event == EV_2clicks) { - set_state(goodnight_state, 0); - return MISCHIEF_MANAGED; - } - #elif defined(USE_BEACON_MODE) + #if defined(USE_BEACON_MODE) // 2 clicks: beacon mode else if (event == EV_2clicks) { set_state(beacon_state, 0); diff --git a/spaghetti-monster/anduril/candle-mode.c b/spaghetti-monster/anduril/candle-mode.c index d0a4eb2..70f5e0e 100644 --- a/spaghetti-monster/anduril/candle-mode.c +++ b/spaghetti-monster/anduril/candle-mode.c @@ -21,6 +21,9 @@ #define CANDLE_MODE_C #include "candle-mode.h" +#ifdef USE_SUNSET_TIMER +#include "sunset-timer.h" +#endif uint8_t candle_mode_state(Event event, uint16_t arg) { static int8_t ramp_direction = 1; @@ -37,22 +40,35 @@ uint8_t candle_mode_state(Event event, uint16_t arg) { 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 - #define MINUTES_PER_CANDLE_HALFHOUR 27 // ish + + #ifdef USE_SUNSET_TIMER + // let the candle "burn out" and shut itself off + // if the user told it to + // cache this in case it changes when the timer is called + uint8_t sunset_active = sunset_timer; + // clock tick + sunset_timer_state(event, arg); + // if the timer just expired, shut off + if (sunset_active && (! sunset_timer)) { + set_state(off_state, 0); + return MISCHIEF_MANAGED; + } + #endif // ifdef USE_SUNSET_TIMER + if (event == EV_enter_state) { - candle_mode_timer = 0; // in case any time was left over from earlier ramp_direction = 1; return MISCHIEF_MANAGED; } + #ifdef USE_SUNSET_TIMER // 2 clicks: cancel timer else if (event == EV_2clicks) { // parent state just rotated through strobe/flasher modes, // so cancel timer... in case any time was left over from earlier - candle_mode_timer = 0; + sunset_timer = 0; return MISCHIEF_MANAGED; } + #endif // ifdef USE_SUNSET_TIMER // hold: change brightness (brighter) else if (event == EV_click1_hold) { // ramp away from extremes @@ -78,17 +94,6 @@ uint8_t candle_mode_state(Event event, uint16_t arg) { candle_mode_brightness --; return MISCHIEF_MANAGED; } - // 3 clicks: add 30m to candle timer - else if (event == EV_3clicks) { - if (candle_mode_timer < (255 - MINUTES_PER_CANDLE_HALFHOUR)) { - // add 30m to the timer - candle_mode_timer += MINUTES_PER_CANDLE_HALFHOUR; - // blink to confirm - set_level(actual_level + 32); - delay_4ms(2); - } - return MISCHIEF_MANAGED; - } // clock tick: animate candle brightness else if (event == EV_tick) { // un-reverse after 1 second @@ -96,22 +101,13 @@ uint8_t candle_mode_state(Event event, uint16_t arg) { // self-timer dims the light during the final minute uint8_t subtract = 0; - if (candle_mode_timer == 1) { - subtract = ((candle_mode_brightness+CANDLE_AMPLITUDE) - * ((arg & (TICKS_PER_CANDLE_MINUTE-1)) >> 4)) - >> 8; - } - // we passed a minute mark, decrease timer if it's running - if ((arg & (TICKS_PER_CANDLE_MINUTE-1)) == (TICKS_PER_CANDLE_MINUTE - 1)) { - if (candle_mode_timer > 0) { - candle_mode_timer --; - //set_level(0); delay_4ms(2); - // if the timer ran out, shut off - if (! candle_mode_timer) { - set_state(off_state, 0); - } - } + #ifdef USE_SUNSET_TIMER + if (sunset_timer == 1) { + subtract = (candle_mode_brightness+CANDLE_AMPLITUDE) + * sunset_ticks / TICKS_PER_MINUTE; } + #endif // ifdef USE_SUNSET_TIMER + // 3-oscillator synth for a relatively organic pattern uint8_t add; add = ((triangle_wave(candle_wave1) * candle_wave1_depth) >> 8) diff --git a/spaghetti-monster/anduril/config-default.h b/spaghetti-monster/anduril/config-default.h index f055425..f037648 100644 --- a/spaghetti-monster/anduril/config-default.h +++ b/spaghetti-monster/anduril/config-default.h @@ -90,11 +90,9 @@ // enable beacon mode #define USE_BEACON_MODE -// enable sunset (goodnight) mode -// TODO: replace goodnight mode with a sunset timer in the regular ramp -#define USE_GOODNIGHT_MODE -#define GOODNIGHT_TIME 60 // minutes (approximately) -#define GOODNIGHT_LEVEL 24 // ~11 lm +// enable sunset timer (ramp-down and automatic shutoff) +// timer is available in regular ramp mode and candle mode +#define USE_SUNSET_TIMER // enable/disable various strobe modes #define USE_BIKE_FLASHER_MODE diff --git a/spaghetti-monster/anduril/goodnight-mode.c b/spaghetti-monster/anduril/goodnight-mode.c deleted file mode 100644 index 2fe90e9..0000000 --- a/spaghetti-monster/anduril/goodnight-mode.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * goodnight-mode.c: Goodnight / sunset mode for Anduril. - * - * Copyright (C) 2017 Selene ToyKeeper - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef GOODNIGHT_MODE_C -#define GOODNIGHT_MODE_C - -#include "goodnight-mode.h" - -#define GOODNIGHT_TICKS_PER_STEPDOWN (GOODNIGHT_TIME*TICKS_PER_SECOND*60L/GOODNIGHT_LEVEL) -uint8_t goodnight_state(Event event, uint16_t arg) { - static uint16_t ticks_since_stepdown = 0; - // blink on start - if (event == EV_enter_state) { - ticks_since_stepdown = 0; - blink_confirm(2); - set_level(GOODNIGHT_LEVEL); - return MISCHIEF_MANAGED; - } - // 1 click: off - else if (event == EV_1click) { - set_state(off_state, 0); - return MISCHIEF_MANAGED; - } - // 2 clicks: next mode - else if (event == EV_2clicks) { - #ifdef USE_BEACON_MODE - set_state(beacon_state, 0); - #elif defined(USE_SOS_MODE_IN_BLINKY_GROUP) - set_state(sos_state, 0); - #elif defined(USE_THERMAL_REGULATION) - set_state(tempcheck_state, 0); - #endif - return MISCHIEF_MANAGED; - } - // tick: step down (maybe) or off (maybe) - else if (event == EV_tick) { - if (++ticks_since_stepdown > GOODNIGHT_TICKS_PER_STEPDOWN) { - ticks_since_stepdown = 0; - set_level(actual_level-1); - if (! actual_level) { - #if 0 // test blink, to help measure timing - set_level(MAX_LEVEL>>2); - delay_4ms(8/2); - set_level(0); - #endif - set_state(off_state, 0); - } - } - return MISCHIEF_MANAGED; - } - return EVENT_NOT_HANDLED; -} - - -#endif - diff --git a/spaghetti-monster/anduril/ramp-mode.c b/spaghetti-monster/anduril/ramp-mode.c index b870550..a0a123d 100644 --- a/spaghetti-monster/anduril/ramp-mode.c +++ b/spaghetti-monster/anduril/ramp-mode.c @@ -21,6 +21,9 @@ #define RAMP_MODE_C #include "ramp-mode.h" +#ifdef USE_SUNSET_TIMER +#include "sunset-timer.h" +#endif uint8_t steady_state(Event event, uint16_t arg) { #ifdef USE_REVERSING @@ -43,6 +46,23 @@ uint8_t steady_state(Event event, uint16_t arg) { if (ramp_style) { step_size = ramp_discrete_step_size; } else { step_size = 1; } + #ifdef USE_SUNSET_TIMER + // handle the shutoff timer first + static uint8_t timer_orig_level = 0; + uint8_t sunset_active = sunset_timer; // save for comparison + // clock tick + sunset_timer_state(event, arg); + // if the timer was just turned on + if (sunset_timer && (! sunset_active)) { + timer_orig_level = actual_level; + } + // if the timer just expired, shut off + else if (sunset_active && (! sunset_timer)) { + set_state(off_state, 0); + return MISCHIEF_MANAGED; + } + #endif // ifdef USE_SUNSET_TIMER + // turn LED on when we first enter the mode if ((event == EV_enter_state) || (event == EV_reenter_state)) { #if defined(USE_MOMENTARY_MODE) && defined(USE_STROBE_STATE) @@ -232,8 +252,20 @@ uint8_t steady_state(Event event, uint16_t arg) { } #endif - #if defined(USE_SET_LEVEL_GRADUALLY) || defined(USE_REVERSING) else if (event == EV_tick) { + #ifdef USE_SUNSET_TIMER + // reduce output if shutoff timer is active + if (sunset_timer) { + uint8_t dimmed_level = timer_orig_level * (sunset_timer-1) / sunset_timer_peak; + if (dimmed_level < 1) dimmed_level = 1; + #ifdef USE_SET_LEVEL_GRADUALLY + set_level_gradually(dimmed_level); + target_level = dimmed_level; + #else + set_level_and_therm_target(dimmed_level); + #endif + } + #endif #ifdef USE_REVERSING // un-reverse after 1 second if (arg == TICKS_PER_SECOND) ramp_direction = 1; @@ -270,7 +302,6 @@ uint8_t steady_state(Event event, uint16_t arg) { #endif // ifdef USE_SET_LEVEL_GRADUALLY return MISCHIEF_MANAGED; } - #endif #ifdef USE_THERMAL_REGULATION // overheating: drop by an amount proportional to how far we are above the ceiling else if (event == EV_temperature_high) { @@ -453,6 +484,8 @@ void set_level_and_therm_target(uint8_t level) { target_level = level; set_level(level); } +#else +#define set_level_and_therm_target(level) set_level(level) #endif diff --git a/spaghetti-monster/anduril/sunset-timer.c b/spaghetti-monster/anduril/sunset-timer.c new file mode 100644 index 0000000..0687993 --- /dev/null +++ b/spaghetti-monster/anduril/sunset-timer.c @@ -0,0 +1,68 @@ +/* + * sunset-timer.c: Sunset / candle auto-shutoff functions for Anduril. + * + * Copyright (C) 2017 Selene ToyKeeper + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef SUNSET_TIMER_C +#define SUNSET_TIMER_C + +#include "sunset-timer.h" + +uint8_t sunset_timer_state(Event event, uint16_t arg) { + + // blink on start + if (event == EV_enter_state) { + sunset_timer = 0; + sunset_ticks = 0; + return MISCHIEF_MANAGED; + } + // 3 clicks: add 30m to timer + else if (event == EV_3clicks) { + if (sunset_timer < (255 - SUNSET_TIMER_UNIT)) { + // add 30m to the timer + sunset_timer += SUNSET_TIMER_UNIT; + sunset_timer_peak = sunset_timer; // reset ceiling + sunset_ticks = 0; // reset phase + // blink to confirm + uint8_t brightness = actual_level; + uint8_t bump = actual_level + 32; + if (bump > MAX_LEVEL) bump = 0; + set_level(bump); + delay_4ms(2); + set_level(brightness); + } + return MISCHIEF_MANAGED; + } + // tick: step down (maybe) or off (maybe) + else if (event == EV_tick) { + // time passed + sunset_ticks ++; + // did we reach a minute mark? + if (sunset_ticks >= TICKS_PER_MINUTE) { + sunset_ticks = 0; + if (sunset_timer > 0) { + sunset_timer --; + } + } + return MISCHIEF_MANAGED; + } + return EVENT_NOT_HANDLED; +} + + +#endif + diff --git a/spaghetti-monster/anduril/goodnight-mode.h b/spaghetti-monster/anduril/sunset-timer.h index 3bb5272..2e39e5d 100644 --- a/spaghetti-monster/anduril/goodnight-mode.h +++ b/spaghetti-monster/anduril/sunset-timer.h @@ -1,5 +1,5 @@ /* - * goodnight-mode.h: Goodnight / sunset for Anduril. + * sunset-timer.h: Sunset / candle auto-shutoff functions for Anduril. * * Copyright (C) 2017 Selene ToyKeeper * @@ -17,11 +17,19 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef GOODNIGHT_MODE_H -#define GOODNIGHT_MODE_H +#ifndef SUNSET_TIMER_H +#define SUNSET_TIMER_H -// 1-hour ramp down from low, then automatic off -uint8_t goodnight_state(Event event, uint16_t arg); +// how many minutes to add each time the user "bumps" the timer? +#define SUNSET_TIMER_UNIT 10 + +#define TICKS_PER_MINUTE (TICKS_PER_SECOND*60) + +// automatic shutoff timer +uint8_t sunset_timer = 0; +uint8_t sunset_timer_peak = 0; +uint16_t sunset_ticks = 0; +uint8_t sunset_timer_state(Event event, uint16_t arg); #endif |
