Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: KL25Z_HSI2RGBW_PWM KL25Z_HSI2RGBW_PWM_local KL25Z_FFT_Demo FFT_BUENA ... more
hsi2rgbw_pwm.cpp
- Committer:
- frankvnk
- Date:
- 2013-12-30
- Revision:
- 3:dda6914d713f
- Parent:
- 2:d164d60999c4
- Child:
- 4:a16b9c09561e
File content as of revision 3:dda6914d713f:
/************************************************************************************************************** ***** ***** ***** Name: hsi2rgbw.cpp ***** ***** Date: 22/12/2013 ***** ***** Auth: Frank Vannieuwkerke ***** ***** Func: library for converting HSI color space values to RGBW ***** ***** ***** ***** Code ported from http://saikoled.com - Copyright 2013, Brian Neltner ***** ***** http://blog.saikoled.com/post/44677718712/how-to-convert-from-hsi-to-rgb-white ***** ***** http://blog.saikoled.com/post/43693602826/why-every-led-light-should-be-using-hsi-colorspace ***** ***** 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 ***** ***** ***** ***** This program is free software: you can redistribute it and/or modify ***** ***** it under the terms of the GNU General Public License as published by ***** ***** the Free Software Foundation, version 3 of the License. ***** ***** ***** ***** This program is distributed in the hope that it will be useful, ***** ***** but WITHOUT ANY WARRANTY; without even the implied warranty of ***** ***** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ***** ***** GNU General Public License for more details. ***** ***** ***** ***** A copy of the GNU General Public License can be found at ***** ***** http://www.gnu.org/licenses/gpl.html ***** **************************************************************************************************************/ #include "hsi2rgbw_pwm.h" #define PI 3.14159265 hsi2rgbw_pwm::hsi2rgbw_pwm(PinName red, PinName green, PinName blue, PinName white) : _red(red), _green(green), _blue(blue), _white(white) { parabol = 1; use_rgbw = RGBW; if(_red == NC && _green == NC && _blue == NC) { use_pwm = 0; } else { use_pwm = 1; //Setup PWM channels - default period = 4 ms (250Hz) _red.period_ms(4); _green.period_ms(4); _blue.period_ms(4); if(_white != NC) _white.period_ms(4); // Initial RGB values. _red = 0.0f; _green = 0.0f; _blue = 0.0f; if(_white != NC) _white = 0.0f; } } void hsi2rgbw_pwm::hsi2rgbw(float H, float S, float I, float* rgbw) { float _rgbw[4]; if(rgbw == NULL) rgbw = _rgbw; float cos_h, Srgb; H = fmod(H,360); // cycle H around to 0-360 degrees H = PI*H/(float)180; // Convert to radians. S = S>0?(S<1?S:1):0; // clamp S and I to interval [0,1] I = I>0?(I<1?I:1):0; if(use_rgbw) Srgb = 1; else { Srgb = S; S = 1; } // This section is modified by the addition of white so that it assumes // fully saturated colors, and then scales with white to lower saturation. // // Next, scale appropriately the pure color by mixing with the white channel. // Saturation is defined as "the ratio of colorfulness to brightness" so we will // do this by a simple ratio wherein the color values are scaled down by (1-S) // while the white LED is placed at S. // This will maintain constant brightness because in HSI, R+B+G = I. Thus, // S*(R+B+G) = S*I. If we add to this (1-S)*I, where I is the total intensity, // the sum intensity stays constant while the ratio of colorfulness to brightness // goes down by S linearly relative to total Intensity, which is constant. if(H < 2.09439) { cos_h = cos(H) / cos(1.047196667-H); rgbw[0] = S*I/3*(1+Srgb*cos_h); rgbw[1] = S*I/3*(1+Srgb*(1-cos_h)); if(use_rgbw) { rgbw[2] = 0; rgbw[3] = (1-S)*I; } else rgbw[2] = I/3*(1-Srgb); } else if(H < 4.188787) { H = H - 2.09439; cos_h = cos(H) / cos(1.047196667-H); rgbw[1] = S*I/3*(1+Srgb*cos_h); rgbw[2] = S*I/3*(1+Srgb*(1-cos_h)); if(use_rgbw) { rgbw[0] = 0; rgbw[3] = (1-S)*I; } else rgbw[0] = I/3*(1-Srgb); } else { H = H - 4.188787; cos_h = cos(H) / cos(1.047196667-H); rgbw[2] = S*I/3*(1+Srgb*cos_h); rgbw[0] = S*I/3*(1+Srgb*(1-cos_h)); if(use_rgbw) { rgbw[1] = 0; rgbw[3] = (1-S)*I; } else rgbw[1] = I/3*(1-Srgb); } // parabolic mapping. if(parabol) { rgbw[0] *= rgbw[0]; // RED rgbw[1] *= rgbw[1]; // GREEN rgbw[2] *= rgbw[2]; // BLUE if(use_rgbw) rgbw[3] *= rgbw[3]; // WHITE } if(use_pwm) { _red = rgbw[0]; _green = rgbw[1]; _blue = rgbw[2]; if(_white != NC) _white = rgbw[3]; } } void hsi2rgbw_pwm::period(uint32_t per) { if(use_pwm) { _red.period_us(per); _green.period_us(per); _blue.period_us(per); if(_white != NC) _white.period_us(per); } } void hsi2rgbw_pwm::pwm(float* rgbw) { if(use_pwm) { _red = rgbw[0]; _green = rgbw[1]; _blue = rgbw[2]; if(_white != NC) _white = rgbw[3]; } } void hsi2rgbw_pwm::parabolic(bool para) { parabol = para; } void hsi2rgbw_pwm::colorMode(bool como) { use_rgbw = como; }