Breath LED that turn on/off or loop the brightness smoothly.

Dependents:   BreathLed-demo EPD_GDE021A1_demo mbed_esp8266_demo NUCLEO_uart_flow_control

This breathing-led uses Ticker and PWM which consumes few CPU, and most important, you can use it to tell system hang.

Just init it with a PWM pin which connected to a LED.

Revision:
0:13c83a6b336f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BreathLed.cpp	Mon Apr 06 11:02:16 2015 +0000
@@ -0,0 +1,81 @@
+/*
+ * BreathLed.cpp
+ *
+ *  Created on: 2015/4/6
+ *      Author: steeven@gmail.com
+ */
+
+#include <BreathLed/BreathLed.h>
+
+namespace steeven {
+BreathLed::BreathLed(PinName pin, float time, float hold) :
+        _pin(pin), _ticker() {
+    _pin = 0;
+    _time = time;
+    _hold = hold;
+    _mode = 0;
+    _off = 0;
+    _step = 0;
+}
+void BreathLed::hold_tick() {
+    _ticker.attach(this, &BreathLed::step_tick, _time / BREATH_STEPS);
+}
+void BreathLed::step_tick() {
+
+    if (_off) {
+        if (_step <= 0) {
+            if (_mode == 0) { //loop
+                _off = !_off;
+                if (_hold)
+                    _ticker.attach(this, &BreathLed::hold_tick, _hold);
+            } else
+                _ticker.detach();
+            return;
+        } else {
+            _step--;
+        }
+    } else {
+        if (_step >= BREATH_STEPS) {
+            if (_mode == 0) { //loop
+                _off = !_off;
+                if (_hold)
+                    _ticker.attach(this, &BreathLed::hold_tick, _hold);
+            } else
+                _ticker.detach();
+            return;
+        } else {
+            _step++;
+        }
+    }
+
+    _pin =  (float)(1 << _step) /  (1 << BREATH_STEPS);
+}
+void BreathLed::loop(float time, float hold) {
+    _time = time;
+    _hold = hold;
+    _mode = 0;
+    _ticker.attach(this, &BreathLed::step_tick, _time / BREATH_STEPS);
+}
+
+
+void BreathLed::on() {
+    _mode = 1;
+    _off = 0;
+    if (_pin < 1)
+        _ticker.attach(this, &BreathLed::step_tick, _time / BREATH_STEPS);
+    else
+        _ticker.detach();
+}
+void BreathLed::off() {
+    _mode = 2;
+    _off = 1;
+    if (_pin > 0)
+        _ticker.attach(this, &BreathLed::step_tick, _time / BREATH_STEPS);
+    else
+        _ticker.detach();
+}
+BreathLed::~BreathLed() {
+    if (!_pin != 0)
+        _pin = 0;
+}
+}// namespace steeven