HSI to RGB/RGBW conversion library with optional direct PWM output

Dependents:   KL25Z_HSI2RGBW_PWM KL25Z_HSI2RGBW_PWM_local KL25Z_FFT_Demo FFT_BUENA ... more

HSI to RGB / RGBW with optional PWM output

Library for converting HSI color space values to RGB or RGBW and, optionally, directly send the converted values to PWM outputs.

Code ported from http://saikoled.com - Copyright 2013, Brian Neltner
http://blog.saikoled.com/post/44677718712/how-to-convert-from-hsi-to-rgb-white

Info on the HSI color space can be found here and here.

KL25Z PTA4 as PWM output

By default, PTA4 is defined as the NMI input in the the mbed library. When PTA4 is to be used as a PWM output, we MUST disable the NMI assignment, otherwise the system will lock-up when this pin is pulled low. Read this page for more information.
The easiest way (without changing mbed-src) to disable the NMI input is by adding following code at the start of your main program (this is present in the demo program mentioned below):

// Dummy ISR for disabling NMI on PTA4 - !! DO NOT REMOVE THIS !!
extern "C" void NMI_Handler() {
    DigitalIn test(PTA4);
}

Demo code using the KL25Z-FRDM board:

Import programKL25Z_HSI2RGBW_PWM

SaikoLED fade demo using the HSI2RGBW_PWM libary


Constructor & conversion function
When 3 PWM ouptuts are declared, the library automatically selects RGB mode.
When 4 PWM ouptuts are declared, the library automatically selects RGBW mode.
When no PWM outputs are declared, the library defaults to RGBW mode. Use .colorMode(RGB) to switch to RGB mode.
depending on the way you want to use this library, you can call the conversion function in different ways

// Assign 4 PWM outputs and also allow to return the converted RGBW value.
hsi2rgbw_pwm led(PTD4, PTA12, PTA4, PTA5);
// Call to the conversion function
float H, S, I;
float rgbw[4];
led.hsi2rgbw(H, S, I, rgbw);

// Assign 4 PWM outputs, no converted RGBW value will be returned.
hsi2rgbw_pwm led(PTD4, PTA12, PTA4, PTA5);
// Call to the conversion function
float H, S, I;
led.hsi2rgbw(H, S, I);

// No PWM outputs are assigned, only the converted RGBW value will be returned.
hsi2rgbw_pwm led(NC);
// Call to the conversion function
float H, S, I;
float rgbw[4];
led.hsi2rgbw(H, S, I, rgbw);

// Assign 3 PWM outputs and also allow to return the converted RGB value.
hsi2rgbw_pwm led(PTD4, PTA12, PTA4);
// Call to the conversion function
float H, S, I;
float rgb[4];
led.hsi2rgbw(H, S, I, rgbw);

// Assign 3 PWM outputs, no converted RGB value will be returned.
hsi2rgbw_pwm led(PTD4, PTA12, PTA4);
// Call to the conversion function
float H, S, I;
led.hsi2rgbw(H, S, I);

// No PWM outputs are assigned, only the converted RGB value will be returned.
hsi2rgbw_pwm led(NC);
//Set RGB mode
led.colorMode(RGB);
// Call to the conversion function
float H, S, I;
float rgb[4];
led.hsi2rgbw(H, S, I, rgb);


Hue, Saturation and Intesity range

Hue0...360Color value : 0 or 360 = red, 120 = green, 240 = blue, 60 = yellow, 300 = magenta, ...
Saturation0...1Color saturation : 0 = white, 1 = max. color, 0.7 is a nice pastel
Intensity0...1Color intensity : 0 = off, 1 = full intensity


RGB(W) return value
In your main program, declare an array of 4 float values and pass the pointer to this array to the function:
Even when RGB is used, do declare an array of 4 float values.

float rgbw[4];

Upon exit, the function will return the values in rgbw[], representing the red, green, blue and white component that corresponds to the chosen HSI values. Range : 0...1 where 0 = minimum and 1 = maximum.

rgbw[0]RED
rgbw[1]GREEN
rgbw[2]BLUE
rgbw[3]WHITENote : this value has no significance when RGB mode is used.


parabolic mode
By default, each component of the RGB(W) return value is mapped to a parabolic scale.
Call led.parabolic(0); to disable the parabolic mapping.

Choose RGB or RGBW mode
By default, the conversion return value is set to RGBW.
Call led.colorMode(RGB); to change to RGB mode.
Call led.colorMode(RGBW); to go back to RGBW mode.

Change PWM period
By default, the PWM period is set to 4ms (250Hz).
Call led.period(n); to change the PWM period (replace n with a value in ms).

Change PWM values
We can alter the PWM outputs directly, without passing through the HSI to RGB(W) conversion.
declare float rgbw[4]; and set each value of this array.
Call led.pwm(rgbw); to write the values directly to the PWM outputs.

Invert PWM channels
When common anode LEDs are used, we need to invert the PWM signal..
Call led.invertpwm(1); to use the inverted PWM signal.

NOTES
period() and pwm() will not change any value if no PWM pins are declared.
Do not forget to replace led. with the declared function name.

Committer:
frankvnk
Date:
Mon Dec 23 20:24:17 2013 +0000
Revision:
0:dd0e7a8a4572
Child:
1:191c9b17351c
Initial release

Who changed what in which revision?

UserRevisionLine numberNew contents of line
frankvnk 0:dd0e7a8a4572 1 /**************************************************************************************************************
frankvnk 0:dd0e7a8a4572 2 ***** *****
frankvnk 0:dd0e7a8a4572 3 ***** Name: hsi2rgbw.h *****
frankvnk 0:dd0e7a8a4572 4 ***** Date: 22/12/2013 *****
frankvnk 0:dd0e7a8a4572 5 ***** Auth: Frank Vannieuwkerke *****
frankvnk 0:dd0e7a8a4572 6 ***** Func: library for converting HSI color space values to RGBW *****
frankvnk 0:dd0e7a8a4572 7 ***** *****
frankvnk 0:dd0e7a8a4572 8 ***** Code ported from http://saikoled.com - Copyright 2013, Brian Neltner *****
frankvnk 0:dd0e7a8a4572 9 ***** http://blog.saikoled.com/post/44677718712/how-to-convert-from-hsi-to-rgb-white *****
frankvnk 0:dd0e7a8a4572 10 ***** http://blog.saikoled.com/post/43693602826/why-every-led-light-should-be-using-hsi-colorspace *****
frankvnk 0:dd0e7a8a4572 11 ***** https://github.com/saikoLED/MyKi/blob/master/myki_16_bit_random_fade/myki_16_bit_random_fade.ino *****
frankvnk 0:dd0e7a8a4572 12 ***** https://github.com/saikoLED/MyKi/blob/master/myki_16_bit_fade/myki_16_bit_fade.ino *****
frankvnk 0:dd0e7a8a4572 13 ***** *****
frankvnk 0:dd0e7a8a4572 14 ***** This program is free software: you can redistribute it and/or modify *****
frankvnk 0:dd0e7a8a4572 15 ***** it under the terms of the GNU General Public License as published by *****
frankvnk 0:dd0e7a8a4572 16 ***** the Free Software Foundation, version 3 of the License. *****
frankvnk 0:dd0e7a8a4572 17 ***** *****
frankvnk 0:dd0e7a8a4572 18 ***** This program is distributed in the hope that it will be useful, *****
frankvnk 0:dd0e7a8a4572 19 ***** but WITHOUT ANY WARRANTY; without even the implied warranty of *****
frankvnk 0:dd0e7a8a4572 20 ***** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *****
frankvnk 0:dd0e7a8a4572 21 ***** GNU General Public License for more details. *****
frankvnk 0:dd0e7a8a4572 22 ***** *****
frankvnk 0:dd0e7a8a4572 23 ***** A copy of the GNU General Public License can be found at *****
frankvnk 0:dd0e7a8a4572 24 ***** http://www.gnu.org/licenses/gpl.html *****
frankvnk 0:dd0e7a8a4572 25 **************************************************************************************************************/
frankvnk 0:dd0e7a8a4572 26
frankvnk 0:dd0e7a8a4572 27 #include "mbed.h"
frankvnk 0:dd0e7a8a4572 28
frankvnk 0:dd0e7a8a4572 29 #ifndef HSI2RGBW_PWM_H
frankvnk 0:dd0e7a8a4572 30 #define HSI2RGBW_PWM_H
frankvnk 0:dd0e7a8a4572 31
frankvnk 0:dd0e7a8a4572 32 #define RGBW 1
frankvnk 0:dd0e7a8a4572 33 #define RGB 0
frankvnk 0:dd0e7a8a4572 34
frankvnk 0:dd0e7a8a4572 35 /** Class to convert HSI colorspace value to its corresponding RGBW value.
frankvnk 0:dd0e7a8a4572 36 * 'red', 'green', 'blue' and 'white' pin can be any PWM pin.
frankvnk 0:dd0e7a8a4572 37 */
frankvnk 0:dd0e7a8a4572 38
frankvnk 0:dd0e7a8a4572 39 class hsi2rgbw_pwm {
frankvnk 0:dd0e7a8a4572 40 public:
frankvnk 0:dd0e7a8a4572 41 /** Create a HSI2RGBW object connected to 4 PWM pins.
frankvnk 0:dd0e7a8a4572 42 *
frankvnk 0:dd0e7a8a4572 43 * @param red = RED PWM pin\n
frankvnk 0:dd0e7a8a4572 44 * @param blue = BLUE PWM pin\n
frankvnk 0:dd0e7a8a4572 45 * @param green = GREEN PWM pin\n
frankvnk 0:dd0e7a8a4572 46 * @param white = WHITE PWM pin\n
frankvnk 0:dd0e7a8a4572 47 * @return none\n
frankvnk 0:dd0e7a8a4572 48 * When you want to use hsi2rgbw standalone (no PWMout), use following initializer:\n
frankvnk 0:dd0e7a8a4572 49 * hsi2rgbw_pwm led; OR hsi2rgbw_pwm led(NC, NC, NC, NC);\n
frankvnk 0:dd0e7a8a4572 50 * Create a float array in your program to return the rgbw values, eg : float rgbw[4]\n
frankvnk 0:dd0e7a8a4572 51 * Call hsi2rgbw with the rgbw pointer : hsi2rgbw(H, S, I, rgbw)\n
frankvnk 0:dd0e7a8a4572 52 */
frankvnk 0:dd0e7a8a4572 53 hsi2rgbw_pwm(PinName red = NC, PinName green = NC, PinName blue = NC, PinName white = NC);
frankvnk 0:dd0e7a8a4572 54
frankvnk 0:dd0e7a8a4572 55 /** Convert HSI to RGBW or RGB.
frankvnk 0:dd0e7a8a4572 56 *
frankvnk 0:dd0e7a8a4572 57 * @param Hue = float (0..1)\n
frankvnk 0:dd0e7a8a4572 58 * @param Saturation = float (0..1)\n
frankvnk 0:dd0e7a8a4572 59 * @param Intensity = float (0..1)\n
frankvnk 0:dd0e7a8a4572 60 * @param rgbw = Optional pointer to float array[4]\n
frankvnk 0:dd0e7a8a4572 61 * This parameter can be omitted when PWM output is enabled:\n
frankvnk 0:dd0e7a8a4572 62 * hsi2rgbw(H, S, I)\n
frankvnk 0:dd0e7a8a4572 63 * This function can be used to convert HSI to RGBW or RGB:\n
frankvnk 0:dd0e7a8a4572 64 * call colorMode(RGBW) to enable HSI->RGBW\n
frankvnk 0:dd0e7a8a4572 65 * call colorMode(RGB) to enable HSI->RGBW\n
frankvnk 0:dd0e7a8a4572 66 * IMPORTANT NOTE : When RGB is selected and you want the function to return\n
frankvnk 0:dd0e7a8a4572 67 * the converted value, do declare a 4 element array!!\n
frankvnk 0:dd0e7a8a4572 68 * The value in the 4th element can be discarded.\n
frankvnk 0:dd0e7a8a4572 69 */
frankvnk 0:dd0e7a8a4572 70 void hsi2rgbw(float H, float S, float I, float* rgbw = NULL);
frankvnk 0:dd0e7a8a4572 71
frankvnk 0:dd0e7a8a4572 72 /** Change PWM period.
frankvnk 0:dd0e7a8a4572 73 *
frankvnk 0:dd0e7a8a4572 74 * @param Period (in ms)\n
frankvnk 0:dd0e7a8a4572 75 * @return none\n
frankvnk 0:dd0e7a8a4572 76 */
frankvnk 0:dd0e7a8a4572 77 void period(uint32_t per);
frankvnk 0:dd0e7a8a4572 78
frankvnk 0:dd0e7a8a4572 79 /** Change PWM value.
frankvnk 0:dd0e7a8a4572 80 *
frankvnk 0:dd0e7a8a4572 81 * @param pointer to float array[4]\n
frankvnk 0:dd0e7a8a4572 82 * @param array[0] = RED PWM value (0...1)\n
frankvnk 0:dd0e7a8a4572 83 * @param array[1] = BLUE PWM value (0...1)\n
frankvnk 0:dd0e7a8a4572 84 * @param array[2] = GREEN PWM value (0...1)\n
frankvnk 0:dd0e7a8a4572 85 * @param array[3] = WHITE PWM value (0...1)\n
frankvnk 0:dd0e7a8a4572 86 * Use this function to set the PWM values without conversion.\n
frankvnk 0:dd0e7a8a4572 87 * @return none\n
frankvnk 0:dd0e7a8a4572 88 */
frankvnk 0:dd0e7a8a4572 89 void pwm(float* rgbw);
frankvnk 0:dd0e7a8a4572 90
frankvnk 0:dd0e7a8a4572 91 /** Set parabolic mode.
frankvnk 0:dd0e7a8a4572 92 *
frankvnk 0:dd0e7a8a4572 93 * @param Parabolic : 1 = map rgbw output value to a parabolic curve (default).\n
frankvnk 0:dd0e7a8a4572 94 * 0 = linear mapping.\n
frankvnk 0:dd0e7a8a4572 95 * @return none\n
frankvnk 0:dd0e7a8a4572 96 */
frankvnk 0:dd0e7a8a4572 97 void parabolic(bool para);
frankvnk 0:dd0e7a8a4572 98
frankvnk 0:dd0e7a8a4572 99 /** Set color conversion mode.
frankvnk 0:dd0e7a8a4572 100 *
frankvnk 0:dd0e7a8a4572 101 * @param Colormode : RGBW (1) = convert HSI to RGBW (default).\n
frankvnk 0:dd0e7a8a4572 102 * RGB (0) = convert HSI to RGB.\n
frankvnk 0:dd0e7a8a4572 103 * @return none\n
frankvnk 0:dd0e7a8a4572 104 */
frankvnk 0:dd0e7a8a4572 105 void colorMode(bool como);
frankvnk 0:dd0e7a8a4572 106
frankvnk 0:dd0e7a8a4572 107 private:
frankvnk 0:dd0e7a8a4572 108 PwmOut _red;
frankvnk 0:dd0e7a8a4572 109 PwmOut _green;
frankvnk 0:dd0e7a8a4572 110 PwmOut _blue;
frankvnk 0:dd0e7a8a4572 111 PwmOut _white;
frankvnk 0:dd0e7a8a4572 112 bool parabol;
frankvnk 0:dd0e7a8a4572 113 bool use_pwm;
frankvnk 0:dd0e7a8a4572 114 bool use_rgbw;
frankvnk 0:dd0e7a8a4572 115 };
frankvnk 0:dd0e7a8a4572 116 #endif