From 565fb109ec5e7cf195914834523b1723da374e40 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Mon, 15 Oct 2018 15:08:17 -0600 Subject: cleaned up fsm baton UI a little, added a short manual --- spaghetti-monster/baton/baton.c | 112 +++++++++++++++++++++++----------------- 1 file changed, 65 insertions(+), 47 deletions(-) (limited to 'spaghetti-monster/baton/baton.c') diff --git a/spaghetti-monster/baton/baton.c b/spaghetti-monster/baton/baton.c index 1266ddd..59a7196 100644 --- a/spaghetti-monster/baton/baton.c +++ b/spaghetti-monster/baton/baton.c @@ -20,22 +20,17 @@ #define FSM_EMISAR_D4_DRIVER #define USE_LVP #define USE_THERMAL_REGULATION -#define DEFAULT_THERM_CEIL 45 #define USE_DEBUG_BLINK #define USE_DELAY_MS #define USE_DELAY_4MS #define USE_DELAY_ZERO #include "spaghetti-monster.h" -// moon + ../../bin/level_calc.py 2 6 7135 18 10 150 FET 1 10 1500 -uint8_t pwm1_modes[] = { 3, 18, 110, 255, 255, 255, 0, }; -uint8_t pwm2_modes[] = { 0, 0, 0, 9, 58, 138, 255, }; -#define MAX_LEVEL (sizeof(pwm1_modes)-1) - // FSM states uint8_t off_state(EventPtr event, uint16_t arg); uint8_t steady_state(EventPtr event, uint16_t arg); uint8_t party_strobe_state(EventPtr event, uint16_t arg); +uint8_t lockout_state(EventPtr event, uint16_t arg); // brightness control uint8_t memorized_level = 1; @@ -44,93 +39,100 @@ uint8_t actual_level = 0; uint8_t target_level = 0; #endif +// moon + ../../bin/level_calc.py 2 6 7135 18 10 150 FET 1 10 1500 +uint8_t pwm1_levels[] = { 3, 18, 110, 255, 255, 255, 0, }; +uint8_t pwm2_levels[] = { 0, 0, 0, 9, 58, 138, 255, }; +#define MAX_LEVEL (sizeof(pwm1_levels)-1) + +// set LED brightness void set_level(uint8_t lvl) { actual_level = lvl; - PWM1_LVL = pwm1_modes[lvl]; - PWM2_LVL = pwm2_modes[lvl]; + PWM1_LVL = pwm1_levels[lvl]; + PWM2_LVL = pwm2_levels[lvl]; } uint8_t off_state(EventPtr event, uint16_t arg) { // turn emitter off when entering state if (event == EV_enter_state) { - PWM1_LVL = 0; - PWM2_LVL = 0; - // sleep while off (lower power use) - go_to_standby = 1; - return 0; + go_to_standby = 1; // sleep while off (lower power use) + return EVENT_HANDLED; } // hold (initially): go to lowest level, but allow abort for regular click else if (event == EV_click1_press) { set_level(0); - return 0; + return EVENT_HANDLED; + } + // hold (longer): go to lowest level + else if (event == EV_click1_hold) { + set_state(steady_state, 0); + return EVENT_HANDLED; } // 1 click (before timeout): go to memorized level, but allow abort for double click else if (event == EV_click1_release) { set_level(memorized_level); - return 0; + return EVENT_HANDLED; } // 1 click: regular mode else if (event == EV_1click) { set_state(steady_state, memorized_level); - return 0; + return EVENT_HANDLED; } // 2 clicks: highest mode else if (event == EV_2clicks) { set_state(steady_state, MAX_LEVEL); - return 0; + return EVENT_HANDLED; } // 3 clicks: strobe mode else if (event == EV_3clicks) { set_state(party_strobe_state, 255); - return 0; + return EVENT_HANDLED; } - // hold: go to lowest level - else if (event == EV_click1_hold) { - set_state(steady_state, 0); - return 0; + // 4 clicks: soft lockout + else if (event == EV_4clicks) { + set_state(lockout_state, 0); + return EVENT_HANDLED; } - return 1; + return EVENT_NOT_HANDLED; } uint8_t steady_state(EventPtr event, uint16_t arg) { // turn LED on when we first enter the mode if (event == EV_enter_state) { // remember this level, unless it's moon or turbo - if ((arg > 0) && (arg < MAX_LEVEL)) - memorized_level = arg; + if ((arg > 0) && (arg < MAX_LEVEL)) memorized_level = arg; // use the requested level even if not memorized #ifdef USE_THERMAL_REGULATION target_level = arg; #endif set_level(arg); - return 0; + return EVENT_HANDLED; } // 1 click: off else if (event == EV_1click) { set_state(off_state, 0); - return 0; + return EVENT_HANDLED; } // 2 clicks: go to/from highest level else if (event == EV_2clicks) { - if (actual_level < MAX_LEVEL) { + if (actual_level < MAX_LEVEL) { // go to turbo memorized_level = actual_level; // in case we're on moon #ifdef USE_THERMAL_REGULATION target_level = MAX_LEVEL; #endif set_level(MAX_LEVEL); } - else { + else { // return from turbo #ifdef USE_THERMAL_REGULATION target_level = memorized_level; #endif set_level(memorized_level); } - return 0; + return EVENT_HANDLED; } // 3 clicks: go to strobe modes else if (event == EV_3clicks) { set_state(party_strobe_state, 0xff); - return 0; + return EVENT_HANDLED; } // hold: change brightness else if (event == EV_click1_hold) { @@ -141,25 +143,21 @@ uint8_t steady_state(EventPtr event, uint16_t arg) { #endif set_level(memorized_level); } - return 0; + return EVENT_HANDLED; } #ifdef USE_THERMAL_REGULATION // overheating: drop by 1 level else if (event == EV_temperature_high) { - if (actual_level > 1) { - set_level(actual_level - 1); - } - return 0; + if (actual_level > 1) { set_level(actual_level - 1); } + return EVENT_HANDLED; } // underheating: increase by 1 level if we're lower than the target else if (event == EV_temperature_low) { - if (actual_level < target_level) { - set_level(actual_level + 1); - } - return 0; + if (actual_level < target_level) { set_level(actual_level + 1); } + return EVENT_HANDLED; } #endif - return 1; + return EVENT_NOT_HANDLED; } uint8_t party_strobe_state(EventPtr event, uint16_t arg) { @@ -168,7 +166,7 @@ uint8_t party_strobe_state(EventPtr event, uint16_t arg) { if (event == EV_enter_state) { if (arg < 64) between = arg; frames = 0; - return 0; + return MISCHIEF_MANAGED; } // tick: strobe the emitter else if (event == EV_tick) { @@ -182,17 +180,17 @@ uint8_t party_strobe_state(EventPtr event, uint16_t arg) { //frames = (frames + 1) % between; frames++; if (frames > between) frames = 0; - return 0; + return MISCHIEF_MANAGED; } // 1 click: off else if (event == EV_1click) { set_state(off_state, 0); - return 0; + return MISCHIEF_MANAGED; } // 2 clicks: go back to regular modes else if (event == EV_2clicks) { set_state(steady_state, memorized_level); - return 0; + return MISCHIEF_MANAGED; } // hold: change speed else if (event == EV_click1_hold) { @@ -200,9 +198,25 @@ uint8_t party_strobe_state(EventPtr event, uint16_t arg) { between = (between+1)%6; frames = 0; } - return 0; + return MISCHIEF_MANAGED; + } + return EVENT_NOT_HANDLED; +} + +uint8_t lockout_state(EventPtr event, uint16_t arg) { + // stay asleep while locked + if (event == EV_tick) { + PWM1_LVL = 0; PWM2_LVL = 0; // make sure emitters are off + // sleep 1 second after user stops pressing + if (arg > TICKS_PER_SECOND) { go_to_standby = 1; } + return MISCHIEF_MANAGED; + } + // 4 clicks: exit, and turn on at "low" level + else if (event == EV_4clicks) { + set_state(steady_state, 1); + return MISCHIEF_MANAGED; } - return 1; + return EVENT_NOT_HANDLED; } void low_voltage() { @@ -214,6 +228,10 @@ void low_voltage() { else if (current_state == steady_state) { if (actual_level > 0) { set_level(actual_level - 1); + #ifdef USE_THERMAL_REGULATION + target_level = actual_level; // don't let low temperature override LVP + #endif + } else { set_state(off_state, 0); -- cgit v1.2.3 From fa9baf747b32e77e4a753dec99b7b6dc4795af1b Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Mon, 15 Oct 2018 15:09:34 -0600 Subject: removed more-complex baton UI (which only different by having a party strobe mode), replaced it with the simpler version (since this UI exists mostly as an example) --- spaghetti-monster/baton/baton.c | 86 +++++++---------------------------------- 1 file changed, 13 insertions(+), 73 deletions(-) (limited to 'spaghetti-monster/baton/baton.c') diff --git a/spaghetti-monster/baton/baton.c b/spaghetti-monster/baton/baton.c index 59a7196..d4725ef 100644 --- a/spaghetti-monster/baton/baton.c +++ b/spaghetti-monster/baton/baton.c @@ -20,16 +20,12 @@ #define FSM_EMISAR_D4_DRIVER #define USE_LVP #define USE_THERMAL_REGULATION -#define USE_DEBUG_BLINK #define USE_DELAY_MS -#define USE_DELAY_4MS -#define USE_DELAY_ZERO #include "spaghetti-monster.h" // FSM states uint8_t off_state(EventPtr event, uint16_t arg); uint8_t steady_state(EventPtr event, uint16_t arg); -uint8_t party_strobe_state(EventPtr event, uint16_t arg); uint8_t lockout_state(EventPtr event, uint16_t arg); // brightness control @@ -82,11 +78,6 @@ uint8_t off_state(EventPtr event, uint16_t arg) { set_state(steady_state, MAX_LEVEL); return EVENT_HANDLED; } - // 3 clicks: strobe mode - else if (event == EV_3clicks) { - set_state(party_strobe_state, 255); - return EVENT_HANDLED; - } // 4 clicks: soft lockout else if (event == EV_4clicks) { set_state(lockout_state, 0); @@ -129,11 +120,6 @@ uint8_t steady_state(EventPtr event, uint16_t arg) { } return EVENT_HANDLED; } - // 3 clicks: go to strobe modes - else if (event == EV_3clicks) { - set_state(party_strobe_state, 0xff); - return EVENT_HANDLED; - } // hold: change brightness else if (event == EV_click1_hold) { if ((arg % HOLD_TIMEOUT) == 0) { @@ -160,54 +146,11 @@ uint8_t steady_state(EventPtr event, uint16_t arg) { return EVENT_NOT_HANDLED; } -uint8_t party_strobe_state(EventPtr event, uint16_t arg) { - static volatile uint8_t frames = 0; - static volatile uint8_t between = 2; - if (event == EV_enter_state) { - if (arg < 64) between = arg; - frames = 0; - return MISCHIEF_MANAGED; - } - // tick: strobe the emitter - else if (event == EV_tick) { - if (frames == 0) { - PWM1_LVL = 0; - PWM2_LVL = 255; - if (between < 3) delay_zero(); - else delay_ms(1); - PWM2_LVL = 0; - } - //frames = (frames + 1) % between; - frames++; - if (frames > between) frames = 0; - return MISCHIEF_MANAGED; - } - // 1 click: off - else if (event == EV_1click) { - set_state(off_state, 0); - return MISCHIEF_MANAGED; - } - // 2 clicks: go back to regular modes - else if (event == EV_2clicks) { - set_state(steady_state, memorized_level); - return MISCHIEF_MANAGED; - } - // hold: change speed - else if (event == EV_click1_hold) { - if ((arg % HOLD_TIMEOUT) == 0) { - between = (between+1)%6; - frames = 0; - } - return MISCHIEF_MANAGED; - } - return EVENT_NOT_HANDLED; -} - uint8_t lockout_state(EventPtr event, uint16_t arg) { // stay asleep while locked if (event == EV_tick) { PWM1_LVL = 0; PWM2_LVL = 0; // make sure emitters are off - // sleep 1 second after user stops pressing + // sleep 1 second after user stops pressing buttons if (arg > TICKS_PER_SECOND) { go_to_standby = 1; } return MISCHIEF_MANAGED; } @@ -220,29 +163,26 @@ uint8_t lockout_state(EventPtr event, uint16_t arg) { } void low_voltage() { - // "step down" from strobe to level 2 - if (current_state == party_strobe_state) { - set_state(steady_state, 1); - } - // in normal mode, step down by one level or turn off - else if (current_state == steady_state) { - if (actual_level > 0) { - set_level(actual_level - 1); + // step down by one level or turn off + if (actual_level > 0) { + set_level(actual_level - 1); #ifdef USE_THERMAL_REGULATION target_level = actual_level; // don't let low temperature override LVP #endif - - } - else { - set_state(off_state, 0); - } + } + else { + set_state(off_state, 0); } } void setup() { - debug_blink(2); + // blink when power is connected + set_level(MAX_LEVEL/2); + delay_ms(10); + set_level(0); push_state(off_state, 0); } -void loop() { } +void loop() { +} -- cgit v1.2.3 From 453199bfab1b9c431ce07b5b32aabdd115dcd6e6 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Sun, 11 Nov 2018 16:03:07 -0700 Subject: Updated most of the UIs to use the new event API. --- spaghetti-monster/baton/baton.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'spaghetti-monster/baton/baton.c') diff --git a/spaghetti-monster/baton/baton.c b/spaghetti-monster/baton/baton.c index d4725ef..d138297 100644 --- a/spaghetti-monster/baton/baton.c +++ b/spaghetti-monster/baton/baton.c @@ -24,9 +24,9 @@ #include "spaghetti-monster.h" // FSM states -uint8_t off_state(EventPtr event, uint16_t arg); -uint8_t steady_state(EventPtr event, uint16_t arg); -uint8_t lockout_state(EventPtr event, uint16_t arg); +uint8_t off_state(Event event, uint16_t arg); +uint8_t steady_state(Event event, uint16_t arg); +uint8_t lockout_state(Event event, uint16_t arg); // brightness control uint8_t memorized_level = 1; @@ -47,7 +47,7 @@ void set_level(uint8_t lvl) { PWM2_LVL = pwm2_levels[lvl]; } -uint8_t off_state(EventPtr event, uint16_t arg) { +uint8_t off_state(Event event, uint16_t arg) { // turn emitter off when entering state if (event == EV_enter_state) { go_to_standby = 1; // sleep while off (lower power use) @@ -86,7 +86,7 @@ uint8_t off_state(EventPtr event, uint16_t arg) { return EVENT_NOT_HANDLED; } -uint8_t steady_state(EventPtr event, uint16_t arg) { +uint8_t steady_state(Event event, uint16_t arg) { // turn LED on when we first enter the mode if (event == EV_enter_state) { // remember this level, unless it's moon or turbo @@ -146,7 +146,7 @@ uint8_t steady_state(EventPtr event, uint16_t arg) { return EVENT_NOT_HANDLED; } -uint8_t lockout_state(EventPtr event, uint16_t arg) { +uint8_t lockout_state(Event event, uint16_t arg) { // stay asleep while locked if (event == EV_tick) { PWM1_LVL = 0; PWM2_LVL = 0; // make sure emitters are off -- cgit v1.2.3