Jesus Christ
/
ws2811_Izebel
simple program to control Izebel's lights for Firefly
Revision 0:02f4f92c778a, committed 2016-06-19
- 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
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