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.

Dependents:   RedButton

Revision:
0:dda7f6f55dc1
Child:
1:bcddb9898625
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Pulsator.cpp	Fri Apr 24 03:56:51 2015 +0000
@@ -0,0 +1,49 @@
+#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
+
+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;
+}
+
+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();
+}
+
+Pulsator& Pulsator::operator=(bool state)
+{
+    state ? enable() : disable();
+    return *this;
+}