Use the hardware PwmOut to pulsate an LED (or something else), with selectable active high/low, customisable intensity function, gamma correction, and number of brightness levels.
Pulsator.cpp
- Committer:
- huliyang
- Date:
- 2015-04-24
- Revision:
- 2:e351afc2a3a8
- Parent:
- 1:bcddb9898625
- Child:
- 3:a789d816b3a2
File content as of revision 2:e351afc2a3a8:
/* Copyright (c) 2015 Liyang HU, MIT License * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software * and associated documentation files (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, publish, distribute, * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or * substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include <math.h> #include <mbed.h> #include <Pulsator.h> #ifndef M_PI # define M_PI 3.14159265358979323846 #endif #ifndef M_PI_2 # define M_PI_2 1.57079632679489661923 #endif /*! \class Pulsator * \brief Pulsate an LED using hardware \a PwmOut and \a Ticker. * \code #include <mbed.h> #include <Pulsator.h> Pulsator led(LED1, 2.0, false); int main(void) { led = true; while(1) wait(1); } * \endcode * \see \a PwmOut, \a Ticker */ void Pulsator::step(void) { // sinf(phase_2)^2 == (1 - cosf(phase)) / 2 float s = sinf(phase_2); float level = powf(s * s, gamma); out = active_high ? level : 1.0 - level; phase_2 += M_PI_2 / (float)(levels - 1); if(phase_2 >= M_PI) phase_2 = 0.0; } void Pulsator::enable(void) { out.period(1.0 / 1024.0); phase_2 = 0.0; step(); ticker.attach(this, &Pulsator::step, 0.5 * period / levels); } void Pulsator::disable(void) { ticker.detach(); out = active_high ? 0.0 : 1.0; } /*! Create a \a Pulsator object. * \param pin Pin to pulsate. Note that some platforms can only * drive certain pins with the hardware PWM. * \param period Duration of each cycle, in seconds. * \param active_high Should the output pin be active high (\a true), * or active low (\a false)? * \param gamma Gamma correction for the output LED. * \param levels Number of distinct brightness levels: a minimum of 2. */ Pulsator::Pulsator(PinName pin, float period, bool active_high, float gamma, int levels) : out(pin), period(period), active_high(active_high), gamma(gamma), levels(levels) { disable(); } /*! Enable or disable the output. * \param state Pulsate the output? * \note Passing \a false deactivates the output completely, rather than * keeping the LED brightness at the point where this is called. * Conversely, \a true starts pulsating from the inactive state. */ Pulsator& Pulsator::operator=(bool state) { state ? enable() : disable(); return *this; }