diff --git a/pixelprojektor/pixelprojektor.ino b/pixelprojektor/pixelprojektor.ino index 65505f8..0abad6b 100644 --- a/pixelprojektor/pixelprojektor.ino +++ b/pixelprojektor/pixelprojektor.ino @@ -7,10 +7,35 @@ #define PIN 2 //data pin for ws2812 -Adafruit_NeoPixel strip = Adafruit_NeoPixel(64, PIN, NEO_GRB + NEO_KHZ800); +#define NUMPIXELS 64 + +#define FPS 15 + +uint8_t effect=0; +#define EFFECT_NONE 0 +#define EFFECT_SMOOTH 1 +uint8_t movingPoint_x=3; +uint8_t movingPoint_y=3; +uint8_t wheelPos=0; +#define EFFECT_SPIRAL 2 + + + +Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); HomieNode homieNode("pixel", "commands"); +uint8_t pixelR[NUMPIXELS]; +uint8_t pixelG[NUMPIXELS]; +uint8_t pixelB[NUMPIXELS]; +//write to buffer, flip with showBuffer() +uint8_t pixelR_buffer[NUMPIXELS]; +uint8_t pixelG_buffer[NUMPIXELS]; +uint8_t pixelB_buffer[NUMPIXELS]; + +long lastMillis=0; +long fpsdelay=1000/FPS; + int xyToPos(int x, int y){ //convert x y pixel position to matrix position if (y%2==0){ return (y*8+x); @@ -55,6 +80,169 @@ void led_random() strip.show(); } + +void showBuffer() +{ + for (int i=0; i < strip.numPixels(); i++) { + pixelR[i]=pixelR_buffer[i]; + pixelG[i]=pixelG_buffer[i]; + pixelB[i]=pixelB_buffer[i]; + strip.setPixelColor(i, pixelR[i], pixelG[i], pixelB[i]); + } + strip.show(); +} + +uint8_t getAverage(uint8_t array[NUMPIXELS], uint8_t i, int x, int y) +{ + uint16_t sum=0; + uint8_t count=0; + if (i>=8){ //up + sum+=array[i-8]; + count++; + } + if (i<(64-8)){ //down + sum+=array[i+8]; + count++; + } + if (i>=1){ //left + sum+=array[i-1]; + count++; + } + if (i<(64-1)){ //right + sum+=array[i+1]; + count++; + } + + /* + if (i>=(8+1)){ //up left + sum+=array[i-8-1]; + count++; + } + if (i<(64-8-1)){ //down left + sum+=array[i+8-1]; + count++; + } + if (i>=(8-1)){ //up right + sum+=array[i-8+1]; + count++; + } + if (i<(64-8+1)){ //down right + sum+=array[i+8+1]; + count++; + }*/ + return sum/count; +} + + +void led_smooth() +{ + for (int i=0; i < strip.numPixels(); i++) { + uint8_t avgbrightness=pixelR_buffer[i]/3+pixelG_buffer[i]/3+pixelB_buffer[i]/3; + pixelR_buffer[i]=0.8*pixelR[i] + 0.2*getAverage(pixelR,i, 0,0); + pixelG_buffer[i]=0.8*pixelG[i] + 0.2*getAverage(pixelG,i, 0,0); + pixelB_buffer[i]=0.8*pixelB[i] + 0.2*getAverage(pixelB,i, 0,0); + + } + showBuffer(); +} + +void led_movingPoint() +{ + uint32_t c=wheel(wheelPos); + wheelPos=(wheelPos+1)%255; + uint8_t r = (uint8_t)(c >> 16); + uint8_t g = (uint8_t)(c >> 8); + uint8_t b = (uint8_t)c; + + movingPoint_x=movingPoint_x+8+random(-random(0,1+1),random(0,1+1)+1); + movingPoint_y=movingPoint_y+8+random(-random(0,1+1),random(0,1+1)+1); + if (movingPoint_x<8){ + movingPoint_x=8-movingPoint_x; + }else if (movingPoint_x>=16){ + movingPoint_x=22-movingPoint_x; + }else{ + movingPoint_x-=8; + } + + if (movingPoint_y<8){ + movingPoint_y=8-movingPoint_y; + }else if (movingPoint_y>=16){ + movingPoint_y=22-movingPoint_y; + }else{ + movingPoint_y-=8; + } + uint8_t startx=movingPoint_x; + uint8_t starty=movingPoint_y; + + for (int i=0;i<50;i++){ + + movingPoint_x=startx+8+random(-random(0,2+1),random(0,2+1)+1); + movingPoint_y=starty+8+random(-random(0,2+1),random(0,2+1)+1); + + if (movingPoint_x<8){ + movingPoint_x=8-movingPoint_x; + }else if (movingPoint_x>=16){ + movingPoint_x=22-movingPoint_x; + }else{ + movingPoint_x-=8; + } + + if (movingPoint_y<8){ + movingPoint_y=8-movingPoint_y; + }else if (movingPoint_y>=16){ + movingPoint_y=22-movingPoint_y; + }else{ + movingPoint_y-=8; + } + + + + if (pixelR[xyToPos(movingPoint_x,movingPoint_y)]r){ + pixelR[xyToPos(movingPoint_x,movingPoint_y)]--; + } + if (pixelG[xyToPos(movingPoint_x,movingPoint_y)]g){ + pixelG[xyToPos(movingPoint_x,movingPoint_y)]--; + } + if (pixelB[xyToPos(movingPoint_x,movingPoint_y)]b){ + pixelB[xyToPos(movingPoint_x,movingPoint_y)]--; + } + } + + + //pixelR[xyToPos(movingPoint_x,movingPoint_y)]=0.5*pixelR[xyToPos(movingPoint_x,movingPoint_y)]+0.5*r; + //pixelG[xyToPos(movingPoint_x,movingPoint_y)]=0.5*pixelG[xyToPos(movingPoint_x,movingPoint_y)]+0.5*g; + //pixelB[xyToPos(movingPoint_x,movingPoint_y)]=0.5*pixelB[xyToPos(movingPoint_x,movingPoint_y)]+0.5*b; + + movingPoint_x=startx; + movingPoint_y=starty; + +} +void bufferClear() +{ + for (int i=0; i < strip.numPixels(); i++) { + pixelR_buffer[i]=0; + pixelG_buffer[i]=0; + pixelB_buffer[i]=0; + } +} + +void led_spiral() +{ + wheelPos++; + for (int i=0; i < strip.numPixels(); i++) { + strip.setPixelColor(i,wheel((wheelPos+i*10)%255)); + } + strip.show(); +} + + + uint32_t parseColor(String value){ if (value.charAt(0)=='#'){ //solid fill String color=value.substring(1); @@ -85,18 +273,33 @@ bool effectHandler(const HomieRange& range, const String& value) { Homie.getLogger() << "command=" << command << " parameters=" << parameters << endl; if (command.equals("fill")){ + effect=EFFECT_NONE; led_fill(parseColor(parameters)); }else if (command.equals("off")){ + effect=EFFECT_NONE; led_fill(strip.Color(0, 0, 0)); }else if (command.equals("random")){ + effect=EFFECT_NONE; led_random(); }else if (command.equals("set")){ + effect=EFFECT_NONE; int x=parameters.substring(0,1).toInt(); int y=parameters.substring(1,2).toInt(); String cstr=parameters.substring(2,9); strip.setPixelColor(xyToPos(x,y), parseColor(cstr)); strip.show(); + }else if (command.equals("smooth")){ + effect=EFFECT_SMOOTH; + bufferClear(); + showBuffer(); + strip.show(); + }else if (command.equals("spiral")){ + effect=EFFECT_SPIRAL; + bufferClear(); + showBuffer(); + strip.show(); } + @@ -107,6 +310,7 @@ bool pixelsHandler(const HomieRange& range, const String& value) { String remaining=value; int i=0; + effect=EFFECT_NONE; do{ String current=remaining.substring(0,7); Homie.getLogger() << i << ":" << current << endl; @@ -153,6 +357,22 @@ void loop() { Homie.loop(); long currentMillis = millis(); + + if (lastMillis+fpsdelay