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-23
- Revision:
- 0:dd0e7a8a4572
- Child:
- 2:d164d60999c4
File content as of revision 0:dd0e7a8a4572:
#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; }