#include // homie lib from: https://github.com/marvinroger/homie-esp8266/ #include #ifdef __AVR__ #include #endif #define PIN 2 //data pin for ws2812 #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; uint8_t wheelPosSlow=0; //for slower wheelPos increment than 1 int wheelSpeed=16; //16=+1/frame int smoothing=80; //0 to 100. 100=no change (ultrasmooth), 0=no smoothing. int strength=50; //how much pixels to apply color to #define EFFECT_SPIRAL 2 #define EFFECT_RANDOMFADE 3 int fadespeedmax=5; //1 to 255 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); }else{ return (y*8+(7-x)); } } int numToPos(int num){ //convert pixel number to actual 8x8 matrix position int x=num%8; int y=num/8; return xyToPos(x,y); } uint32_t wheel(byte WheelPos) { WheelPos = 255 - WheelPos; if(WheelPos < 85) { return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3); } if(WheelPos < 170) { WheelPos -= 85; return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3); } WheelPos -= 170; return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0); } void led_fill(uint32_t c) { for (int i=0; i < strip.numPixels(); i++) { strip.setPixelColor(i, c); } strip.show(); } void led_random() { for (int i=0; i < strip.numPixels(); i++) { strip.setPixelColor(i, wheel(random(0,255))); } 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]=(smoothing/100.0)*pixelR[i] + (1.0-(smoothing/100.0))*getAverage(pixelR,i, 0,0); pixelG_buffer[i]=(smoothing/100.0)*pixelG[i] + (1.0-(smoothing/100.0))*getAverage(pixelG,i, 0,0); pixelB_buffer[i]=(smoothing/100.0)*pixelB[i] + (1.0-(smoothing/100.0))*getAverage(pixelB,i, 0,0); } showBuffer(); } void led_movingPoint() { uint32_t c=wheel(wheelPos); wheelPosSlow+=wheelSpeed; wheelPos=(wheelPos+ (wheelPosSlow/10) )%255; wheelPosSlow=wheelPosSlow%16; 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=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*5)%255)); } strip.show(); } void led_randomfade() { for (int i=0; i < strip.numPixels(); i++) { pixelR_buffer[i]+=random(0,random(0,fadespeedmax+1)+1); //use buffer red channel for color wheel strip.setPixelColor(i,wheel(pixelR_buffer[i])); } strip.show(); } void set_randomBuffer() { for (int i=0; i < strip.numPixels(); i++) { pixelR_buffer[i]=random(0,256); pixelG_buffer[i]=random(0,256); pixelB_buffer[i]=random(0,256); } } uint32_t parseColor(String value){ if (value.charAt(0)=='#'){ //solid fill String color=value.substring(1); int number = (int) strtol( &color[0], NULL, 16); // Split them up into r, g, b values int r = number >> 16; int g = number >> 8 & 0xFF; int b = number & 0xFF; Homie.getLogger() << "r=" << r << " g=" << g << " b=" << b << endl; //Serial.print("r=");Serial.print(r); //Serial.print(" g=");Serial.print(g); //Serial.print(" b=");Serial.println(b); return strip.Color(r, g, b); } return 0; } bool effectHandler(const HomieRange& range, const String& value) { Homie.getLogger() << "-> " << value << endl; int sep = value.indexOf("|"); String command=value.substring(0,sep); String parameters=value.substring(sep+1); 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")){ //example: set|37#ff003a 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")){ //example: smooth|[wheelspeed]|[smoothing]|[strength] wheelspeed=1-255, smoothing=0-100, strength=1-255 int sepparam = parameters.indexOf("|"); int p1=parameters.substring(0,sepparam).toInt(); String parameters_part2=parameters.substring(sepparam+1); sepparam = parameters_part2.indexOf("|"); int p2=parameters_part2.substring(0,sepparam).toInt(); int p3=parameters_part2.substring(sepparam+1).toInt(); wheelSpeed=16; //default, speed=+1 /frame if (p1>0){ wheelSpeed=p1; } smoothing=80; if (p2>0){ smoothing=p2; } strength=50; if (p3>0){ strength=p3; } Homie.getLogger() << "-- p1=" << p1 << " p2=" << p2 << " p3=" << p3 << endl; effect=EFFECT_SMOOTH; bufferClear(); showBuffer(); strip.show(); }else if (command.equals("spiral")){ effect=EFFECT_SPIRAL; bufferClear(); showBuffer(); strip.show(); }else if (command.equals("clearbuffer")){ bufferClear(); showBuffer(); strip.show(); }else if (command.equals("randomfade")){ //example: randomfade|5 int sepparam = parameters.indexOf("|"); int p1=parameters.substring(0,sepparam).toInt(); fadespeedmax=5; if (p1>0){ fadespeedmax=p1; } effect=EFFECT_RANDOMFADE; set_randomBuffer(); //initialize random }else if (command.equals("randombuffer")){ set_randomBuffer(); //set random showBuffer(); } return true; } 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; uint32_t currentcolor=parseColor(current); strip.setPixelColor(i, currentcolor); i++; remaining=remaining.substring(7); }while(remaining.length()>2 && (i