Simple neopixel (WS2812) library, tuned for stm32 (L432) at 80 MHz Should be compatible with any stm32, different clock speed may require timing adjustments in neopixel.c

Dependents:   NEOPIXEL_SAMPLE ppd

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers colorspace.cpp Source File

colorspace.cpp

00001 #include "mbed.h"
00002 #include "colorspace.h"
00003 #include "math.h"
00004 
00005 #define max(a,b) ((a)>(b)?(a):(b))
00006 #define min(a,b) ((a)>(b)?(b):(a))
00007 
00008 static float threeway_max(float a, float b, float c) {
00009     return max(a, max(b, c));
00010 }
00011 
00012 
00013 static float threeway_min(float a, float b, float c) {
00014     return min(a, min(b, c));
00015 }
00016 
00017 
00018 static float hue2rgb(float p, float q, float t) {
00019     if(t < 0) t += 1;
00020     if(t > 1) t -= 1;
00021     if(t < 1/6.0f) return p + (q - p) * 6 * t;
00022     if(t < 1/2.0f) return q;
00023     if(t < 2/3.0f) return p + (q - p) * (2/3.0f - t) * 6;
00024     return p;
00025 }
00026 
00027 
00028 void hsl2rgb(const FloatHSL *hsl, FloatRGB *rgb)
00029 {
00030     float h = hsl->h;
00031     float s = hsl->s;
00032     float l = hsl->l;
00033     
00034     if (s == 0) {
00035         rgb->r = rgb->g = rgb->b = l; // achromatic
00036     } else {
00037         float q = l < 0.5f ? l * (1 + s) : l + s - l * s;
00038         float p = 2 * l - q;
00039         rgb->r = hue2rgb(p, q, h + 1/3.0f);
00040         rgb->g = hue2rgb(p, q, h);
00041         rgb->b = hue2rgb(p, q, h - 1/3.0f);
00042     }
00043 }
00044 
00045 
00046 void hsv2rgb(const FloatHSV *hsv, FloatRGB *rgb)
00047 {
00048     float r, g, b;
00049 
00050     int i = floor(hsv->h * 6);
00051     float f = hsv->h * 6 - i;
00052     float p = hsv->v * (1 - hsv->s);
00053     float q = hsv->v * (1 - f * hsv->s);
00054     float t = hsv->v * (1 - (1 - f) * hsv->s);
00055 
00056     switch(i % 6) {
00057         case 0:
00058             r = hsv->v;
00059             g = t;
00060             b = p;
00061             break;
00062         case 1:
00063             r = q;
00064             g = hsv->v;
00065             b = p;
00066             break;
00067         case 2:
00068             r = p;
00069             g = hsv->v;
00070             b = t;
00071             break;
00072         case 3:
00073             r = p;
00074             g = q;
00075             b = hsv->v;
00076             break;
00077         case 4:
00078             r = t;
00079             g = p;
00080             b = hsv->v;
00081             break;
00082         case 5:
00083             r = hsv->v;
00084             g = p;
00085             b = q;
00086             break;
00087     }
00088     
00089     rgb->r = r;
00090     rgb->g = g;
00091     rgb->b = b;
00092 }
00093 
00094 void rgb2hsl(const FloatRGB *rgb, FloatHSL *hsl)
00095 { 
00096     float rd = rgb->r;
00097     float gd = rgb->g;
00098     float bd = rgb->b;
00099     float max = threeway_max(rd, gd, bd);
00100     float min = threeway_min(rd, gd, bd);
00101     float h, s, l = (max + min) / 2.0f;
00102 
00103     if (max == min) {
00104         h = s = 0; // achromatic
00105     } else {
00106         float d = max - min;
00107         s = l > 0.5f ? d / (2 - max - min) : d / (max + min);
00108         if (max == rd) {
00109             h = (gd - bd) / d + (gd < bd ? 6 : 0);
00110         } else if (max == gd) {
00111             h = (bd - rd) / d + 2;
00112         } else if (max == bd) {
00113             h = (rd - gd) / d + 4;
00114         }
00115         h /= 6;
00116     }
00117     hsl->h = h;
00118     hsl->s = s;
00119     hsl->l = l;
00120 }
00121 
00122 
00123 
00124 /** Convert from HSV to HSL  (this is possibly wrong) */
00125 void hsv2hsl(const FloatHSV *hsv, FloatHSL *hsl)
00126 { 
00127     float l = (2 - hsv->s) * hsv->v / 2.0f;
00128     float s = hsv->s;
00129 
00130     if (l != 0) {
00131         if (l == 1) {
00132             s = 0;
00133         } else if (l < 0.5f) {
00134             s = s * hsv->v / (l * 2);
00135         } else {
00136             s = s * hsv->v / (2 - l * 2);
00137         }
00138     }
00139         
00140     hsl->h = hsv->h;
00141     hsl->s = s;
00142     hsl->l = l;
00143 }
00144 
00145 /** Convert from HSL to HSV */
00146 void hsl2hsv(const FloatHSL *hsl, FloatHSV *hsv)
00147 {
00148     float sat = hsv->s * ((hsl->l < 0.5f) ? hsl->l : (1 - hsl->l));
00149     hsv->s = 2*sat / (hsl->l + sat);
00150     hsv->h = hsl->h;
00151     hsv->v = hsl->l + sat;  
00152 }
00153 
00154 
00155 uint32_t hsl2hex(const FloatHSL *hsl)
00156 {
00157     FloatRGB rgb;
00158     hsl2rgb(hsl, &rgb);
00159     return rgb2hex(&rgb);    
00160 }
00161 
00162 uint32_t hsv2hex(const FloatHSV *hsv)
00163 {
00164     FloatRGB rgb;
00165     hsv2rgb(hsv, &rgb);
00166     return rgb2hex(&rgb); 
00167 }
00168 
00169 
00170 uint32_t rgb2hex(FloatRGB *rgb)
00171 {
00172     return ((int)floor(rgb->r*255 + 0.5f) << 16) | ((int)floor(rgb->g*255 + 0.5f) << 8) | ((int)floor(rgb->b*255 + 0.5f));
00173 }
00174