simple program to control Izebel's lights for Firefly

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
bollocks
Date:
Sun Jun 19 00:10:54 2016 +0000
Commit message:
simple program for Izebel's lights, for the ST F072RB

Changed in this revision

ColorConversion.cpp Show annotated file Show diff for this revision Revisions of this file
ColorConversion.h Show annotated file Show diff for this revision Revisions of this file
SimpleWS2811.cpp Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
ws2811BitBang.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 02f4f92c778a ColorConversion.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ColorConversion.cpp	Sun Jun 19 00:10:54 2016 +0000
@@ -0,0 +1,48 @@
+#include "ColorConversion.h"
+
+
+/*
+this function converts all len pixels from HSV colorspace to RGB colorspace. Value is constant and assumed to be the same for all pixels 
+in hsBuf [HSHSHS...] All HSV values are integers, multiplied by a constant factor of 1000, so that integer math works (in case there's no
+FPU).
+*/
+void convertHSVtoRGB(const int* hsBuf, uint8_t* rgbBuf,size_t len,int CVALUE){
+    for(size_t i=0;i<len;i++){
+        int hue = hsBuf[2*i];
+        hue = hue%360000;
+        int saturation = hsBuf[2*i+1];
+        int c = CVALUE*saturation/1000;
+        //float unused;
+        int x = c * (1000-abs((hue/60)%2000-1000))/1000;
+        int m = CVALUE-c;
+        int rprime,gprime,bprime;
+        if (0 <= hue && hue < 60000){
+            rprime=c;
+            gprime=x;
+            bprime=0;
+        }else if(60000 <= hue && hue < 120000){
+            rprime=x;
+            gprime=c;
+            bprime=0;
+        }else if(120000 <= hue && hue < 180000){
+            rprime=0.0f;
+            gprime=c;
+            bprime=x;
+        }else if(180000 <= hue && hue < 240000){
+            rprime=0;
+            gprime=x;
+            bprime=c;
+        }else if(240000 <= hue && hue < 300000){
+            rprime=x;
+            gprime=0;
+            bprime=c;
+        }else{// if(300f <= hue && hue < 360f){
+            rprime=c;
+            gprime=0;
+            bprime=x;
+        }
+        rgbBuf[3*i]=uint8_t((rprime+m)*255/1000);
+        rgbBuf[3*i+1]=uint8_t((gprime+m)*255/1000);
+        rgbBuf[3*i+2]=uint8_t((bprime+m)*255/1000);
+    }
+}
\ No newline at end of file
diff -r 000000000000 -r 02f4f92c778a ColorConversion.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ColorConversion.h	Sun Jun 19 00:10:54 2016 +0000
@@ -0,0 +1,5 @@
+#ifndef COLORCONVERSION_H 
+#define COLORCONVERSION_H 1
+#include "mbed.h"
+void convertHSVtoRGB(const int* hsBuf, uint8_t* rgbBuf,size_t len,int CVALUE);
+#endif
\ No newline at end of file
diff -r 000000000000 -r 02f4f92c778a SimpleWS2811.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SimpleWS2811.cpp	Sun Jun 19 00:10:54 2016 +0000
@@ -0,0 +1,43 @@
+#include "ws2811BitBang.h"
+
+static inline void send0(DigitalOut& ws2811Data){
+    ws2811Data=1;
+    WAIT0H();
+    ws2811Data=0;
+    WAIT0L();
+}
+static inline void send1(DigitalOut& ws2811Data){
+    ws2811Data=1;
+    WAIT1H();
+    ws2811Data=0;
+    WAIT1L();
+}
+
+static inline void sendByte(uint8_t b, DigitalOut& ws2811Data){
+    for(int i=0;i<8;i++){
+        if(b & (uint8_t)0x80){
+            send1(ws2811Data);
+        }else{
+            send0(ws2811Data);
+        }
+        b = b << 1;
+    }
+}
+
+static inline void sendLED(uint8_t red, uint8_t green, uint8_t blue,DigitalOut& ws2811Data){
+    sendByte(red,ws2811Data);
+    sendByte(green,ws2811Data);
+    sendByte(blue,ws2811Data);
+}
+
+static inline void sendLED(uint8_t *p,DigitalOut& ws2811Data){
+    sendLED(*p,*(p+1), *(p+2),ws2811Data);
+}
+
+void sendBuffer(uint8_t* rgbBuf,size_t len,DigitalOut& ws2812Data){
+    __disable_irq();
+    for(size_t i=0;i<len;i++){
+        sendLED(rgbBuf+3*i,ws2812Data);
+    }
+    __enable_irq();
+}
\ No newline at end of file
diff -r 000000000000 -r 02f4f92c778a main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Jun 19 00:10:54 2016 +0000
@@ -0,0 +1,103 @@
+#include "mbed.h"
+#include "ws2811BitBang.h"
+#include "ColorConversion.h"
+
+#define NLED (50*6)
+
+DigitalIn button(USER_BUTTON);
+
+DigitalOut boardLED(LED1);
+
+DigitalOut ws2811Data(PA_8);
+
+uint8_t bufferRGB[NLED*3];
+
+int bufferHS0[NLED*2]; //hue & saturation; value is constant. all variables are fixed precision with scale factor 1000.
+int bufferHS1[NLED*2]; //double buffer, for manipulation & swap
+#define CVALUE 1000
+
+
+#define max(a,b) ((a)>=(b)?(a):(b))
+
+    
+void fillHS0(int hue, int saturation,int hinc){
+    int hadd=0;
+    for(size_t i=0;i<NLED;i++){
+        bufferHS0[2*i]=(hue+hadd)%360000;
+        bufferHS0[2*i+1]=saturation;
+        hadd+=hinc;
+    }
+}
+
+/*
+I made up this shimmer function as I went along; the idea is to make the lights whiteish (low saturation) most of the time
+but occasionally have local patches of lights shimmer with color in a way that travels along the string of lights in a wave
+and slowly settles down. 1/splashArrival is the probability that a splash of color will be added to the chain during this
+call.
+*/
+void shimmer(int *buf0, int *buf1, size_t len, 
+             int splashArrival = 10,
+             int restingSaturation=0,
+             int restingWeight=1,
+             int neighborWeight=99){
+    int totalWeight = restingWeight+neighborWeight;
+    int event = rand() % splashArrival;
+    if(event==0){
+        int led = rand() % (len-5);
+        int hue = rand() % (10*360000);
+        int sat = 600;//rand() % 1000;
+        for(size_t i=0;i<5;i++){
+            buf0[2*(led+i)] = hue;
+            buf0[2*(led+i)+1]=sat;
+        }
+    }
+    for(size_t i=0;i<len;i++){
+        int hl,hc,hr,sl,sc,sr;
+        if(i==0){
+            hl=buf0[2*(len-1)];
+            sl=restingSaturation;
+            hr=buf0[2*(i+1)];
+            sr=buf0[2*(i+1)+1];
+        }else if(i==len-1){
+            hl=buf0[2*(i-1)];
+            sl=buf0[2*(i-1)+1];
+            hr=buf0[0];
+            sr=restingSaturation;
+        }else{
+            hl=buf0[2*(i-1)];
+            sl=buf0[2*(i-1)+1];
+            hr=buf0[2*(i+1)];
+            sr=buf0[2*(i+1)+1];
+        }
+        hc = buf0[2*i];
+        sc = buf0[2*i+1];
+        buf1[2*i] = (((2*hl+hc+2*hr)/5)*99+300000*1)/100;
+        //printf("baz: %d\n\r",buf1[2*i]);
+        buf1[2*i+1]=(max(sl,max(sc,sr))*neighborWeight+restingSaturation*restingWeight)/totalWeight;
+    }
+}
+
+int main() {
+    
+    int hue = 0;
+    int arrival=1;
+    fillHS0(hue,1000,60000);
+    while(true){
+        if(!button){
+            arrival=1;
+        }
+        shimmer(bufferHS0,bufferHS1,NLED,arrival);
+        convertHSVtoRGB(bufferHS1,bufferRGB,NLED,CVALUE);
+        sendBuffer(bufferRGB,NLED,ws2811Data);
+        boardLED = !boardLED;
+    
+        shimmer(bufferHS1,bufferHS0,NLED,arrival);
+        convertHSVtoRGB(bufferHS0,bufferRGB,NLED,CVALUE);
+        sendBuffer(bufferRGB,NLED,ws2811Data);
+        boardLED = !boardLED;
+        
+        if(arrival < 10){
+            arrival++;
+        }
+    }
+}
diff -r 000000000000 -r 02f4f92c778a mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sun Jun 19 00:10:54 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/6c34061e7c34
\ No newline at end of file
diff -r 000000000000 -r 02f4f92c778a ws2811BitBang.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ws2811BitBang.h	Sun Jun 19 00:10:54 2016 +0000
@@ -0,0 +1,68 @@
+//this is a very silly, platform-specific way of getting the timing right for the WS2811 chips. Obviously there are more thoughtful ways to solve this problem, but this was expedient
+
+#ifndef WS2811BITBANG
+#define WS2811BITBANG 1
+#include "mbed.h"
+#define WAIT0H() asm volatile{nop;}
+#define WAIT0L() asm volatile{nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+    }
+    
+#define WAIT1L() WAIT0L()
+#define WAIT1H() asm volatile{\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+        nop;\
+    }
+    
+void sendBuffer(uint8_t* rgbBuf,size_t len,DigitalOut& ws2812Data);
+
+#endif
\ No newline at end of file