SaikoLED fade demo using the HSI2RGBW_PWM libary

Dependencies:   HSI2RGBW_PWM mbed

HSI to RGBW demo with direct PWM output

Code and library based on SaikoLED code :
https://github.com/saikoLED/MyKi/blob/master/myki_16_bit_random_fade/myki_16_bit_random_fade.ino
https://github.com/saikoLED/MyKi/blob/master/myki_16_bit_fade/myki_16_bit_fade.ino
http://blog.saikoled.com/post/44677718712/how-to-convert-from-hsi-to-rgb-white

Revision:
0:562d0087dd7f
Child:
3:afa2c73359fa
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Dec 23 21:36:33 2013 +0000
@@ -0,0 +1,165 @@
+/*
+***************************************************
+* Code ported from http://saikoled.com            *
+* Licensed under GPL3                             *
+* Created 14 February 2013                        *
+* Original MCU board : Arduino Leonardo           *
+* Original CPU       : ATmega32u4                 *
+* Copyright 2013, Brian Neltner                   *
+***************************************************
+
+Sources
+-------
+https://github.com/saikoLED/MyKi/blob/master/myki_16_bit_random_fade/myki_16_bit_random_fade.ino
+https://github.com/saikoLED/MyKi/blob/master/myki_16_bit_fade/myki_16_bit_fade.ino
+Above files are combined into this file using defines.
+
+http://blog.saikoled.com/post/44677718712/how-to-convert-from-hsi-to-rgb-white
+
+Other demos : Psychadelic demo
+DO NOT TRY THIS IF YOU ARE EPILEPTIC! THESE FREQUENCIES ARE EVEN WORSE THAN MOST STROBING LIGHTS!
+http://blog.saikoled.com/post/45760195354/generating-vivid-geometric-hallucinations-using-flicker
+
+This software implements 4x 16-bit PWM with a filtered fading algorithm
+in HSI color space and HSI -> RGBW conversion to allow for better
+pastel color.
+*/
+  
+#include "mbed.h"
+#include "hsi2rgbw_pwm.h"
+
+#define RANDOM_FADE       // Disable this define to set Normal fade.
+
+// Constants
+#define steptime        1       // Color transition time in ms.
+#define maxsaturation   1.0
+
+#ifdef RANDOM_FADE
+    #define propgain        0.0005 // "Small Constant"
+    #define minsaturation   0.9
+#else
+    #define hue_increment   0.01
+#endif
+
+Serial pc(USBTX, USBRX);
+
+// HSI to RGBW conversion with direct output to PWM channels
+hsi2rgbw_pwm led(PTD4, PTA12, PTA4, PTA5);
+
+// Dummy ISR for disabling NMI on PTA4 - !! DO NOT REMOVE THIS !!
+// More info at https://mbed.org/questions/1387/How-can-I-access-the-FTFA_FOPT-register-/
+extern "C" void NMI_Handler() {
+    DigitalIn test(PTA4);
+}
+
+struct HSI {
+    float h;
+    float s;
+    float i;
+#ifdef RANDOM_FADE
+    float htarget;
+    float starget;
+#endif
+} color;
+
+void updatehue() {
+#ifdef RANDOM_FADE
+    color.htarget += ((rand()%360)-180)*.1;
+    color.htarget = fmod(color.htarget, 360);
+    color.h += propgain*(color.htarget-color.h);
+    color.h = fmod(color.h, 360);
+#else
+    color.h = color.h + hue_increment;
+    if(color.h > 360)
+        color.h = 0;
+#endif
+}
+
+void updatesaturation() {
+#ifdef RANDOM_FADE
+    color.starget += ((rand()%10000)-5000)/0.00001;
+    if (color.starget > maxsaturation) color.starget = maxsaturation;
+    else if (color.starget < minsaturation) color.starget = minsaturation;
+    color.s += propgain*(color.starget-color.s);
+    if (color.s > maxsaturation) color.s = maxsaturation;
+    else if (color.s < minsaturation) color.s = minsaturation;
+#else
+    color.s = maxsaturation;
+#endif
+}
+
+void primary_colors() {
+    printf("briefly show RED - GREEN - BLUE using hsi2rgbw.\r\n");
+    for (color.h = 0 ; color.h < 360 ; color.h += 120)
+    {
+        led.hsi2rgbw(color.h, color.s, color.i);
+        wait(1);
+    }
+}
+
+void cycle_rgbw() {
+    float rgbw[4] = {0,0,0,0};
+    printf("briefly show RED - GREEN - BLUE - WHITE using direct PWM output.\r\n");
+    rgbw[0] = 1.0f;
+    led.pwm(rgbw);
+    wait(1);
+    rgbw[0] = 0.0f;
+    rgbw[1] = 1.0f;
+    led.pwm(rgbw);
+    wait(1);
+    rgbw[1] = 0.0f;
+    rgbw[2] = 1.0f;
+    led.pwm(rgbw);
+    wait(1);
+    rgbw[2] = 0.0f;
+    rgbw[3] = 1.0f;
+    led.pwm(rgbw);
+    wait(1);
+}
+
+void sendcolor() {
+    while (color.h >=360) color.h = color.h - 360;
+    while (color.h < 0) color.h = color.h + 360;
+    if (color.i > 1) color.i = 1;
+    if (color.i < 0) color.i = 0;
+    if (color.s > 1) color.s = 1;
+    if (color.s < 0) color.s = 0;
+    // Fix ranges (somewhat redundantly).
+    led.hsi2rgbw(color.h, color.s, color.i);
+}
+ 
+ void setup()  {
+    led.colorMode(RGBW);
+    color.h = 0;
+    color.s = maxsaturation;
+    color.i = 0;
+#ifdef RANDOM_FADE
+    color.htarget = 0;
+    color.starget = maxsaturation;
+#endif
+  
+    // Initial color = off, hue of red fully saturated.
+    while (color.i < 1) {
+        sendcolor();
+        color.i = color.i + 0.001; // Increase Intensity
+        updatehue();
+        updatesaturation();
+        wait_ms(steptime);
+    }
+}
+
+int main()  {
+    pc.baud (115200);
+    printf("HSI to RGBW random fade.\r\n");
+    printf("Initialize.\r\n");
+    setup();
+    primary_colors();
+    cycle_rgbw();
+    printf("Run.\r\n");
+    while(1) {
+        sendcolor();
+        updatehue();
+        updatesaturation();
+        wait_ms(steptime);
+    }
+}