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
Diff: hsi2rgbw_pwm.cpp
- Revision:
- 0:dd0e7a8a4572
- Child:
- 2:d164d60999c4
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hsi2rgbw_pwm.cpp Mon Dec 23 20:24:17 2013 +0000 @@ -0,0 +1,148 @@ +#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_ms(per); + _green.period_ms(per); + _blue.period_ms(per); + if(_white != NC) + _white.period_ms(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; +}