From cdf17c544718e6cc0eaec4b62108cd7413bc709f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beat=20K=C3=BCng?= Date: Thu, 5 Oct 2017 13:14:24 +0200 Subject: [PATCH] led: add MODE_FLASH --- msg/led_control.msg | 5 +-- src/lib/led/led.cpp | 36 +++++++++++++------ src/lib/led/led.h | 42 +++++++++++++++++++++- src/systemcmds/led_control/led_control.cpp | 4 +++ 4 files changed, 73 insertions(+), 14 deletions(-) diff --git a/msg/led_control.msg b/msg/led_control.msg index ce5d3f56fb..6189d22c15 100644 --- a/msg/led_control.msg +++ b/msg/led_control.msg @@ -20,6 +20,7 @@ uint8 MODE_BLINK_SLOW = 3 uint8 MODE_BLINK_NORMAL = 4 uint8 MODE_BLINK_FAST = 5 uint8 MODE_BREATHE = 6 # continuously increase & decrease brightness (solid color if driver does not support it) +uint8 MODE_FLASH = 7 # two fast blinks (on/off) with timing as in MODE_BLINK_FAST and then off for a while uint8 MAX_PRIORITY = 2 # maxium priority (minimum is 0) @@ -27,6 +28,6 @@ uint8 MAX_PRIORITY = 2 # maxium priority (minimum is 0) uint8 led_mask # bitmask which LED(s) to control, set to 0xff for all uint8 color # see COLOR_* uint8 mode # see MODE_* -uint8 num_blinks # how many times to blink (number of on-off cycles if mode is one of MODE_BLINK_*). Set to 0 for infinite +uint8 num_blinks # how many times to blink (number of on-off cycles if mode is one of MODE_BLINK_*) . Set to 0 for infinite + # in MODE_FLASH it is the number of cycles (infinite is not possible) uint8 priority # priority: higher priority events will override current lower priority events (see MAX_PRIORITY) - diff --git a/src/lib/led/led.cpp b/src/lib/led/led.cpp index 9daca56cea..1791e7409d 100644 --- a/src/lib/led/led.cpp +++ b/src/lib/led/led.cpp @@ -60,7 +60,21 @@ int LedController::update(LedControlData &control_data) // don't apply the new state just yet to avoid interrupting an ongoing blinking state for (int i = 0; i < BOARD_MAX_LEDS; ++i) { if (led_control.led_mask & (1 << i)) { - _states[i].next_state.set(led_control); + // if next state has already a higher priority state than + // led_control, set lower prio state directly, so that this + // information is not lost + if (_states[i].next_state.is_valid() && led_control.priority < _states[i].next_state.priority) { + _states[i].set(led_control); + + } else { + // if a lower prio event is already in next state and a + // higher prio event is coming in + if (_states[i].next_state.is_valid() && led_control.priority > _states[i].next_state.priority) { + _states[i].apply_next_state(); + } + + _states[i].next_state.set(led_control); + } } } } @@ -96,6 +110,7 @@ int LedController::update(LedControlData &control_data) uint16_t current_blink_duration = 0; switch (cur_data.mode) { + case led_control_s::MODE_FLASH: case led_control_s::MODE_BLINK_FAST: current_blink_duration = BLINK_FAST_DURATION / 100; break; @@ -168,15 +183,7 @@ int LedController::update(LedControlData &control_data) had_changes = true; } - _states[i].priority[next_priority].color = _states[i].next_state.color; - _states[i].priority[next_priority].mode = _states[i].next_state.mode; - _states[i].priority[next_priority].blink_times_left = _states[i].next_state.num_blinks * 2; - - if (_states[i].priority[next_priority].blink_times_left == 0) { - // handle infinite case - _states[i].priority[next_priority].blink_times_left = 254; - } - + _states[i].apply_next_state(); _states[i].next_state.reset(); } @@ -204,6 +211,7 @@ void LedController::get_control_data(LedControlData &control_data) control_data.leds[i].brightness = 255; for (int priority = led_control_s::MAX_PRIORITY; priority >= 0; --priority) { + bool flash_output_active = true; const PerPriorityData &cur_data = _states[i].priority[priority]; if (cur_data.mode == led_control_s::MODE_DISABLED) { @@ -225,10 +233,16 @@ void LedController::get_control_data(LedControlData &control_data) break; } + case led_control_s::MODE_FLASH: + if (cur_data.blink_times_left % 10 < 6) { // 2 blinks, then turn off for the rest of the cycle + flash_output_active = false; + } + + /* FALLTHROUGH */ case led_control_s::MODE_BLINK_FAST: case led_control_s::MODE_BLINK_NORMAL: case led_control_s::MODE_BLINK_SLOW: - if (cur_data.blink_times_left % 2 == 0) { + if (cur_data.blink_times_left % 2 == 0 && flash_output_active) { control_data.leds[i].color = cur_data.color; } diff --git a/src/lib/led/led.h b/src/lib/led/led.h index 1de903c8ef..001d421d35 100644 --- a/src/lib/led/led.h +++ b/src/lib/led/led.h @@ -141,6 +141,47 @@ private: PerPriorityData priority[led_control_s::MAX_PRIORITY + 1]; uint16_t current_blinking_time = 0; ///< how long the Led was in current state (in 0.1 ms, wraps if > 6.5s) NextState next_state; + + void set(const led_control_s &led_control) + { + int next_priority = (int)led_control.priority; + priority[next_priority].color = led_control.color; + priority[next_priority].mode = led_control.mode; + + // initialise the flash counter + if (led_control.mode == led_control_s::MODE_FLASH) { + priority[next_priority].blink_times_left = led_control.num_blinks * 10; + + } else { + priority[next_priority].blink_times_left = led_control.num_blinks * 2; + } + + if (priority[next_priority].blink_times_left == 0) { + // handle infinite case + priority[next_priority].blink_times_left = 254; + } + + + } + + void apply_next_state() + { + int next_priority = (int)next_state.priority; + priority[next_priority].color = next_state.color; + priority[next_priority].mode = next_state.mode; + + if (next_state.mode == led_control_s::MODE_FLASH) { + priority[next_priority].blink_times_left = next_state.num_blinks * 10; + + } else { + priority[next_priority].blink_times_left = next_state.num_blinks * 2; + } + + if (priority[next_priority].blink_times_left == 0) { + // handle infinite case + priority[next_priority].blink_times_left = 254; + } + } }; PerLedData _states[BOARD_MAX_LEDS]; ///< keep current LED states @@ -150,4 +191,3 @@ private: bool _force_update = true; ///< force an orb_copy in the beginning bool _breathe_enabled = false; ///< true if at least one of the led's is currently in breathe mode }; - diff --git a/src/systemcmds/led_control/led_control.cpp b/src/systemcmds/led_control/led_control.cpp index a7678536c4..1981e4c267 100644 --- a/src/systemcmds/led_control/led_control.cpp +++ b/src/systemcmds/led_control/led_control.cpp @@ -82,6 +82,7 @@ $ led_control blink -c blue -l 0 -n 5 PRINT_MODULE_USAGE_PARAM_INT('n', 3, 1, 20, "Number of blinks", true); PRINT_MODULE_USAGE_PARAM_STRING('s', "normal", "fast|normal|slow", "Set blinking speed", true); PRINT_MODULE_USAGE_COMMAND_DESCR("breathe", "Continuously fade LED in & out"); + PRINT_MODULE_USAGE_COMMAND_DESCR("flash", "Two fast blinks and then off with frequency of 1Hz"); PRINT_MODULE_USAGE_PARAM_COMMENT("The following arguments apply to all of the above commands except for 'test':"); PRINT_MODULE_USAGE_PARAM_STRING('c', "white", "red|blue|green|yellow|purple|amber|cyan|white", "color", true); @@ -259,6 +260,9 @@ led_control_main(int argc, char *argv[]) } else if (!strcmp(argv[myoptind], "breathe")) { led_control.mode = led_control_s::MODE_BREATHE; + } else if (!strcmp(argv[myoptind], "flash")) { + led_control.mode = led_control_s::MODE_FLASH; + } else { usage(); return 1;