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.

BreathLed.cpp

Committer:
steeven
Date:
2015-04-06
Revision:
0:13c83a6b336f

File content as of revision 0:13c83a6b336f:

/*
 * 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