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

main.cpp

Committer:
frankvnk
Date:
2014-02-02
Revision:
3:afa2c73359fa
Parent:
0:562d0087dd7f

File content as of revision 3:afa2c73359fa:

/*
***************************************************
* 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");
    color.s = 1;
    color.i = 1;
    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};
    color.s = 1;
    color.i = 1;
    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()  {
    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);
    }
}