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:   Nucleo_neopixel_ovgu Nucleo_neopixel_ovgu1 Nucleo_neopixel_ovgu3

Fork of NeoPixel by Ondřej Hruška

Files at this revision

API Documentation at this revision

Comitter:
Hinz
Date:
Mon Dec 11 12:54:00 2017 +0000
Parent:
0:a81364d9a67b
Commit message:
ok

Changed in this revision

colorspace.cpp Show diff for this revision Revisions of this file
colorspace.h Show diff for this revision Revisions of this file
neopixel.cpp Show annotated file Show diff for this revision Revisions of this file
neopixel.h Show annotated file Show diff for this revision Revisions of this file
diff -r a81364d9a67b -r 037882a8e193 colorspace.cpp
--- a/colorspace.cpp	Tue Mar 21 21:17:08 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,174 +0,0 @@
-#include "mbed.h"
-#include "colorspace.h"
-#include "math.h"
-
-#define max(a,b) ((a)>(b)?(a):(b))
-#define min(a,b) ((a)>(b)?(b):(a))
-
-static float threeway_max(float a, float b, float c) {
-    return max(a, max(b, c));
-}
-
-
-static float threeway_min(float a, float b, float c) {
-    return min(a, min(b, c));
-}
-
-
-static float hue2rgb(float p, float q, float t) {
-    if(t < 0) t += 1;
-    if(t > 1) t -= 1;
-    if(t < 1/6.0f) return p + (q - p) * 6 * t;
-    if(t < 1/2.0f) return q;
-    if(t < 2/3.0f) return p + (q - p) * (2/3.0f - t) * 6;
-    return p;
-}
-
-
-void hsl2rgb(const FloatHSL *hsl, FloatRGB *rgb)
-{
-    float h = hsl->h;
-    float s = hsl->s;
-    float l = hsl->l;
-    
-    if (s == 0) {
-        rgb->r = rgb->g = rgb->b = l; // achromatic
-    } else {
-        float q = l < 0.5f ? l * (1 + s) : l + s - l * s;
-        float p = 2 * l - q;
-        rgb->r = hue2rgb(p, q, h + 1/3.0f);
-        rgb->g = hue2rgb(p, q, h);
-        rgb->b = hue2rgb(p, q, h - 1/3.0f);
-    }
-}
-
-
-void hsv2rgb(const FloatHSV *hsv, FloatRGB *rgb)
-{
-    float r, g, b;
-
-    int i = floor(hsv->h * 6);
-    float f = hsv->h * 6 - i;
-    float p = hsv->v * (1 - hsv->s);
-    float q = hsv->v * (1 - f * hsv->s);
-    float t = hsv->v * (1 - (1 - f) * hsv->s);
-
-    switch(i % 6) {
-        case 0:
-            r = hsv->v;
-            g = t;
-            b = p;
-            break;
-        case 1:
-            r = q;
-            g = hsv->v;
-            b = p;
-            break;
-        case 2:
-            r = p;
-            g = hsv->v;
-            b = t;
-            break;
-        case 3:
-            r = p;
-            g = q;
-            b = hsv->v;
-            break;
-        case 4:
-            r = t;
-            g = p;
-            b = hsv->v;
-            break;
-        case 5:
-            r = hsv->v;
-            g = p;
-            b = q;
-            break;
-    }
-    
-    rgb->r = r;
-    rgb->g = g;
-    rgb->b = b;
-}
-
-void rgb2hsl(const FloatRGB *rgb, FloatHSL *hsl)
-{ 
-    float rd = rgb->r;
-    float gd = rgb->g;
-    float bd = rgb->b;
-    float max = threeway_max(rd, gd, bd);
-    float min = threeway_min(rd, gd, bd);
-    float h, s, l = (max + min) / 2.0f;
-
-    if (max == min) {
-        h = s = 0; // achromatic
-    } else {
-        float d = max - min;
-        s = l > 0.5f ? d / (2 - max - min) : d / (max + min);
-        if (max == rd) {
-            h = (gd - bd) / d + (gd < bd ? 6 : 0);
-        } else if (max == gd) {
-            h = (bd - rd) / d + 2;
-        } else if (max == bd) {
-            h = (rd - gd) / d + 4;
-        }
-        h /= 6;
-    }
-    hsl->h = h;
-    hsl->s = s;
-    hsl->l = l;
-}
-
-
-
-/** Convert from HSV to HSL  (this is possibly wrong) */
-void hsv2hsl(const FloatHSV *hsv, FloatHSL *hsl)
-{ 
-    float l = (2 - hsv->s) * hsv->v / 2.0f;
-    float s = hsv->s;
-
-    if (l != 0) {
-        if (l == 1) {
-            s = 0;
-        } else if (l < 0.5f) {
-            s = s * hsv->v / (l * 2);
-        } else {
-            s = s * hsv->v / (2 - l * 2);
-        }
-    }
-        
-    hsl->h = hsv->h;
-    hsl->s = s;
-    hsl->l = l;
-}
-
-/** Convert from HSL to HSV */
-void hsl2hsv(const FloatHSL *hsl, FloatHSV *hsv)
-{
-    float sat = hsv->s * ((hsl->l < 0.5f) ? hsl->l : (1 - hsl->l));
-    hsv->s = 2*sat / (hsl->l + sat);
-    hsv->h = hsl->h;
-    hsv->v = hsl->l + sat;  
-}
-
-
-uint32_t hsl2hex(const FloatHSL *hsl)
-{
-    FloatRGB rgb;
-    hsl2rgb(hsl, &rgb);
-    return rgb2hex(&rgb);    
-}
-
-uint32_t hsv2hex(const FloatHSV *hsv)
-{
-    FloatRGB rgb;
-    hsv2rgb(hsv, &rgb);
-    return rgb2hex(&rgb); 
-}
-
-
-uint32_t rgb2hex(FloatRGB *rgb)
-{
-    return ((int)floor(rgb->r*255 + 0.5f) << 16) | ((int)floor(rgb->g*255 + 0.5f) << 8) | ((int)floor(rgb->b*255 + 0.5f));
-}
-
diff -r a81364d9a67b -r 037882a8e193 colorspace.h
--- a/colorspace.h	Tue Mar 21 21:17:08 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-#ifndef HSL_H
-#define HSL_H
-
-//
-// Utilities for working with colors in different color spaces
-//
-
-#include "mbed.h"
-
-// all values 0 to 1
-
-// adapted from: https://github.com/ratkins/RGBConverter
-
-struct FloatRGB {
-    float r;
-    float g;
-    float b;
-};
-
-
-struct FloatHSL {
-    float h;
-    float s;
-    float l;
-};
-
-
-struct FloatHSV {
-    float h;
-    float s;
-    float v;
-};
-
-
-// --- Converting to RGB hex ---
-
-/** Convert HSL to RGB hex */
-uint32_t hsl2hex(const FloatHSL *hsl);
-
-/** Convert HSV to RGB hex */
-uint32_t hsv2hex(const FloatHSV *hsv);
-
-/** Convert RGB to RGB hex */
-uint32_t rgb2hex(FloatRGB *rgb);
-
-
-// --- Itner-space conversion functions ---
-
-/** Convert HSL to RGB */
-void hsl2rgb(const FloatHSL *hsl, FloatRGB *rgb);
-
-/** Convert RGB to HSL */
-void rgb2hsl(const FloatRGB *rgb, FloatHSL *hsl);
-
-/** Convert from HSV to HSL */
-void hsv2hsl(const FloatHSV *hsv, FloatHSL *hsl);
-
-/** Convert from HSL to HSV */
-void hsl2hsv(const FloatHSL *hsl, FloatHSV *hsv);
-
-/** Convert HSV to RGB ("handy" algo) */
-void hsv2rgb(const FloatHSV *hsv, FloatRGB *rgb);
-
-#endif /* HSL_H */
\ No newline at end of file
diff -r a81364d9a67b -r 037882a8e193 neopixel.cpp
--- a/neopixel.cpp	Tue Mar 21 21:17:08 2017 +0000
+++ b/neopixel.cpp	Mon Dec 11 12:54:00 2017 +0000
@@ -1,14 +1,15 @@
 #include "mbed.h"
 #include "neopixel.h"
 
-NeoPixelOut::NeoPixelOut(PinName pin) : DigitalOut(pin)
+NeoPixel::NeoPixel(PinName pin, int n) : DigitalOut(pin)
 {
-     normalize = false;
-     global_scale = 1.0f;
+        _pixels = (Pixel*)malloc(n*sizeof(Pixel));
+        memset(_pixels, 0, n*sizeof(Pixel)); 
+        _npixels = n;
 }
 
 // The timing should be approximately 800ns/300ns, 300ns/800ns
-void NeoPixelOut::byte(register uint32_t byte)
+void NeoPixel::byte(register uint32_t byte)
 {        
     for (int i = 0; i < 8; i++) {
         gpio_write(&gpio, 1);
@@ -34,45 +35,20 @@
     
 }
 
-void NeoPixelOut::send(Pixel *colors, uint32_t count, bool flipwait)
+void NeoPixel::show(void)
 {
     // Disable interrupts in the critical section
     __disable_irq();
-
-    Pixel* rgb;
-    float fr,fg,fb;
-    for (int i = 0; i < count; i++) {
-        rgb = colors++;
-        fr = (int)rgb->r;
-        fg = (int)rgb->g;
-        fb = (int)rgb->b;
-        
-        if (normalize) {
-            float scale = 255.0f/(fr+fg+fb);           
-            fr *= scale;
-            fg *= scale;
-            fb *= scale;            
-        }
-        
-        fr *= global_scale;
-        fg *= global_scale;
-        fb *= global_scale;
-        
-        if (fr > 255) fr = 255; 
-        if (fg > 255) fg = 255;
-        if (fb > 255) fb = 255;
-        if (fr < 0) fr = 0; 
-        if (fg < 0) fg = 0;
-        if (fb < 0) fb = 0;
-        
+ 
+   for (int i = 0; i < _npixels; i++) {
         // Black magic to fix distorted timing
         #ifdef __HAL_FLASH_INSTRUCTION_CACHE_DISABLE
         __HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
         #endif
         
-        byte((int)fg);
-        byte((int)fr);
-        byte((int)fb);
+        byte((_pixels+i)->g);
+        byte((_pixels+i)->r);
+        byte((_pixels+i)->b);
         
         #ifdef __HAL_FLASH_INSTRUCTION_CACHE_ENABLE
         __HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
@@ -80,12 +56,19 @@
     }
 
     __enable_irq();
-
-    if (flipwait) flip();   
+    wait_us(50);    
 }
 
 
-void NeoPixelOut::flip(void)
+void NeoPixel::setColor(int i, uint32_t color)
 {
-    wait_us(50);    
+    if ((i>=0) && (i<_npixels))
+        (_pixels+i)->hex = color;
 }
+
+
+void NeoPixel::clear(void)
+{
+    for (int i=0; i<_npixels; i++)
+        (_pixels+i)->hex = 0;
+}
\ No newline at end of file
diff -r a81364d9a67b -r 037882a8e193 neopixel.h
--- a/neopixel.h	Tue Mar 21 21:17:08 2017 +0000
+++ b/neopixel.h	Mon Dec 11 12:54:00 2017 +0000
@@ -2,68 +2,27 @@
 #define NEOPIXEL_H
 #include "mbed.h"
 
-/*
-// Example
-
-NeoPixelOut npx(D12);
-
-int main() {
-    wait(0.2); // wait for HSE to stabilize
-    
-    npx.global_scale = 1.0f; // Adjust brightness
-    npx.normalize = true; // Equalize brightness to make r + g + b = 255
-    
-    Pixel strip[6];
-    strip[0].hex = 0xFF0000;
-    strip[1].hex = 0xFFFF00;
-    strip[2].hex = 0x00FF00;
-    strip[3].hex = 0x00FFFF;
-    strip[4].hex = 0x0000FF;
-    strip[5].hex = 0xFF00FF;
-    
-    npx.send(strip, 6);
-    
-    while(1);
-}
-*/
-
-
-
-/**
- * @brief Struct for easy manipulation of RGB colors.
- *
- * Set components in the xrgb.r (etc.) and you will get
- * the hex in xrgb.num.
- */
 union Pixel {
-    /** Struct for access to individual color components */
     struct __attribute__((packed)) {
         uint8_t b;
         uint8_t g;
         uint8_t r;
         uint8_t a; // unused
     };
+    uint32_t hex;
+};
 
-    /** RGB color as a single uint32_t */
-    uint32_t hex;
+class NeoPixel : DigitalOut {
+private:
+    void byte(uint32_t b);   
+    int _npixels;
+    Pixel *_pixels;
+public:
+    NeoPixel(PinName, int );
+    void show(void);
+    void setColor(int, uint32_t);
+    void clear(void);
 };
 
 
-class NeoPixelOut : DigitalOut {
-private:
-    void byte(uint32_t b);    
-    
-public:
-    bool normalize;
-    float global_scale; 
-
-    NeoPixelOut(PinName pin);
-    
-    void send(Pixel *colors, uint32_t count, bool flipwait=true);
-    
-    /** Wait long enough to make the colors show up */
-    void flip(void);
-};
-
-
-#endif /* NEOPIXEL_H */
\ No newline at end of file
+#endif /* NEOPIXEL_H */