From ce70f346e63429ecd4cdf672f1a824e164b186dc Mon Sep 17 00:00:00 2001 From: starcalc Date: Wed, 1 Mar 2017 17:37:20 +0100 Subject: [PATCH] Fill-Effect working --- pixelprojektor/NeoPatterns.cpp | 44 ++- pixelprojektor/NeoPatterns.h | 8 +- pixelprojektor/pixelprojektor.ino | 447 +----------------------------- 3 files changed, 54 insertions(+), 445 deletions(-) diff --git a/pixelprojektor/NeoPatterns.cpp b/pixelprojektor/NeoPatterns.cpp index 4a66080..c68d487 100644 --- a/pixelprojektor/NeoPatterns.cpp +++ b/pixelprojektor/NeoPatterns.cpp @@ -4,14 +4,13 @@ NeoPatterns::NeoPatterns(uint16_t pixels, uint8_t pin, uint8_t type, void (*call Adafruit_NeoPixel(pixels, pin, type) { OnComplete = callback; - // TODO: Arrays hier initialisieren mit konkreten Werten? Und in der NeoPatterns.h nur der Platzhalter? //Allocate a zero initialized block of memory big enough to hold "pixels" uint8_t. - pixelR = ( uint8_t* ) calloc( pixels, sizeof( uint8_t ) ); - pixelG = ( uint8_t* ) calloc( pixels, sizeof( uint8_t ) ); - pixelB = ( uint8_t* ) calloc( pixels, sizeof( uint8_t ) ); - pixelR_buffer = ( uint8_t* ) calloc( pixels, sizeof( uint8_t ) ); - pixelG_buffer = ( uint8_t* ) calloc( pixels, sizeof( uint8_t ) ); - pixelB_buffer = ( uint8_t* ) calloc( pixels, sizeof( uint8_t ) ); + pixelR = ( uint8_t* ) calloc( pixels, sizeof( uint8_t ) ); + pixelG = ( uint8_t* ) calloc( pixels, sizeof( uint8_t ) ); + pixelB = ( uint8_t* ) calloc( pixels, sizeof( uint8_t ) ); + pixelR_buffer = ( uint8_t* ) calloc( pixels, sizeof( uint8_t ) ); + pixelG_buffer = ( uint8_t* ) calloc( pixels, sizeof( uint8_t ) ); + pixelB_buffer = ( uint8_t* ) calloc( pixels, sizeof( uint8_t ) ); } void NeoPatterns::Update() { @@ -253,7 +252,7 @@ void NeoPatterns::RandomFadeUpdate() { void NeoPatterns::Smooth(uint8_t wheelSpeed, uint8_t smoothing, uint8_t strength, uint8_t interval) { ActivePattern = SMOOTH; Interval = interval; - TotalSteps = 1000; // Beim Smooth nicht sinnvoll? + // TotalSteps = 1; // TODO: Beim Smooth nicht sinnvoll? Index = 0; WheelSpeed = wheelSpeed; Smoothing = smoothing; @@ -354,7 +353,7 @@ void NeoPatterns::SmoothUpdate() { } show(); - Increment(); + // Increment(); } @@ -385,6 +384,12 @@ void NeoPatterns::ColorSet(uint32_t color) show(); } +void NeoPatterns::ColorSetParameters(String parameters) +{ + None(); + ColorSet(parseColor(parameters)); +} + // Returns the Red component of a 32-bit color uint8_t NeoPatterns::Red(uint32_t color) { @@ -433,6 +438,13 @@ uint8_t NeoPatterns::xyToPos(int x, int y) { } } +//convert pixel number to actual 8x8 matrix position +uint8_t NeoPatterns::numToPos(int num) { + int x = num % 8; + int y = num / 8; + return xyToPos(x, y); +} + // Convert pixel number to actual 8x8 matrix position in a spiral uint8_t NeoPatterns::numToSpiralPos(int num) { int edge = (int)sqrt(numPixels()); @@ -481,6 +493,7 @@ uint8_t NeoPatterns::numToSpiralPos(int num) { uint8_t NeoPatterns::getAverage(uint8_t array[], uint8_t i, int x, int y) { + // TODO: This currently works only with 8x8 (64 pixel)! uint16_t sum = 0; uint8_t count = 0; if (i >= 8) { //up @@ -501,3 +514,16 @@ uint8_t NeoPatterns::getAverage(uint8_t array[], uint8_t i, int x, int y) } return sum / count; } + +uint32_t NeoPatterns::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; + return Color(r, g, b); + } + return 0; +} diff --git a/pixelprojektor/NeoPatterns.h b/pixelprojektor/NeoPatterns.h index a546cc4..d175364 100644 --- a/pixelprojektor/NeoPatterns.h +++ b/pixelprojektor/NeoPatterns.h @@ -26,21 +26,24 @@ class NeoPatterns : public Adafruit_NeoPixel void FadeUpdate(); void RandomFade(uint8_t interval = 100); void RandomFadeUpdate(); - void Smooth(uint8_t wheelSpeed, uint8_t smoothing, uint8_t strength, uint8_t interval); + void Smooth(uint8_t wheelSpeed = 16, uint8_t smoothing = 80, uint8_t strength = 50, uint8_t interval = 40); void SmoothUpdate(); void SetColor1(uint32_t color); void SetColor2(uint32_t color); //Utilities void ColorSet(uint32_t color); + void ColorSetParameters(String parameters); uint8_t Red(uint32_t color); uint8_t Green(uint32_t color); uint8_t Blue(uint32_t color); uint32_t Wheel(byte WheelPos); uint8_t numToSpiralPos(int num); uint8_t xyToPos(int x, int y); + uint8_t numToPos(int num); uint8_t getAverage(uint8_t array[], uint8_t i, int x, int y); - private: + uint32_t parseColor(String value); + private: // Member Variables: pattern ActivePattern; // which pattern is running @@ -52,6 +55,7 @@ class NeoPatterns : public Adafruit_NeoPixel uint32_t Color1, Color2; // What colors are in use uint16_t TotalSteps; // total number of steps in the pattern uint16_t Index; // current step within the pattern + uint8_t Every; // Turn every "Every" pixel in Color1/Color2 byte wPos; bool colorful; diff --git a/pixelprojektor/pixelprojektor.ino b/pixelprojektor/pixelprojektor.ino index 79d8c92..c9724cd 100644 --- a/pixelprojektor/pixelprojektor.ino +++ b/pixelprojektor/pixelprojektor.ino @@ -88,7 +88,16 @@ bool onSetEffect(const HomieRange& range, const String& value) { strip.Smooth(16, 80, 50, 40); } else { - strip.None(); + // Test whether command with parameters was sent + int sep = value.indexOf("|"); + String command = value.substring(0, sep); + String parameters = value.substring(sep + 1); + if (command.equals("fill")) + { + strip.ColorSetParameters(parameters); + } else { + strip.None(); + } } homieNode.setProperty("effect").send(value); } @@ -129,12 +138,14 @@ void setup() { homieNode.advertise("clear").settable(onSetClear); homieNode.advertise("length").settable(onSetLength); + + Homie.setup(); + strip.begin(); strip.clear(); strip.setBrightness(64); strip.show(); - Homie.setup(); ArduinoOTA.setHostname("pixelprojektor"); ArduinoOTA.onStart([]() { @@ -157,10 +168,6 @@ void loop() { // Diese Effekte müssen nach dem Umbau wieder vorhanden sein: /* - case EFFECT_SMOOTH: - led_movingPoint(); - led_smooth(); - break; case EFFECT_SPIRAL: led_spiral(); break; @@ -170,115 +177,22 @@ void loop() { case EFFECT_CHASE: led_chase(); break; - case EFFECT_RADAR: - led_radar(); - break; - case EFFECT_LARSON: - led_larson(); - break; */ /************ Old stuff ************/ /* - #define FPS 15 - uint8_t effect = 0; - 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_NONE 0 - #define EFFECT_SMOOTH 1 - #define EFFECT_SPIRAL 2 - #define EFFECT_RANDOMFADE 3 - #define EFFECT_CHASE 4 - #define EFFECT_RADAR 5 - #define EFFECT_LARSON 6 int fadespeedmax = 5; //1 to 255 int iconCountStart = 0; //for percentage calculation int iconCountdown = 0; //0=off uint8_t iconchar = 0; //last displayed char int32_t iconcolor = 0; //last icon color - uint16_t Index; // current step within the pattern - // int Index = 0; // Step for Effect (e.g. chase) - // int state = 0; // Direction for Larson Scanner (spiral) - direction Direction; // direction to run the pattern - 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); - } - - int numToSpiralPos(int num) { // convert pixel number to actual 8x8 matrix position in a spiral - int edge = (int)sqrt(NUMPIXELS); - int findx = edge-1; // 7 - int findy = 0; - int stepsize = edge-1; // initial value (0..7) - int stepnumber = 0; // each "step" should be used twice - int count = -1; - int dir = 1; // direction: 0 = incX, 1=incY, 2=decX, 3=decY - if (num < edge) { - return num; // trivial - } - for (int i = edge; i <= num; i++) - { - count++; - if (count == stepsize) { - count = 0; - // Change direction - dir++; - stepnumber++; - if (stepnumber == 2) { - stepsize -= 1; - stepnumber = 0; - } - if (dir == 4) { - dir = 0; - } - } - switch (dir) { - case 0: - findx++; - break; - case 1: - findy++; - break; - case 2: - findx--; - break; - case 3: - findy--; - break; - } - } - return xyToPos(findx, findy); - } - uint32_t wheel(byte WheelPos) { WheelPos = 255 - WheelPos; if (WheelPos < 85) { @@ -293,13 +207,6 @@ void loop() { } - void led_fill(uint32_t c) - { - for (int i = 0; i < strip.numPixels(); i++) { - strip.setPixelColor(i, c); - } - strip.show(); - } void led_random() { @@ -309,219 +216,12 @@ void loop() { 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++; - } - 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 < strength; 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)]++; - } else 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)]++; - } else 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)]++; - } else 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_chase() - { - Index += 1; - if (Index > 255) { - Index = 1; - } - // for (int j=0; j < 256; j++) { // cycle all 256 colors in the wheel - for (int q = 0; q < 3; q++) { - for (uint16_t i = 0; i < strip.numPixels(); i = i + 3) { - strip.setPixelColor(i + q, wheel( (i + Index) % 255)); //turn every third pixel on - } - strip.show(); - - delay(49); - - for (uint16_t i = 0; i < strip.numPixels(); i = i + 3) { - strip.setPixelColor(i + q, 0); //turn every third pixel off - } - } - } - - - void led_radar() { // "Sweep" in cirles... // line(0,0,950*cos(radians(iAngle)),-950*sin(radians(iAngle))); } - // Calculate 50% dimmed version of a color (used by led_larson()) - uint32_t DimColor(uint32_t color) - { - // Shift R, G and B components one bit to the right - uint32_t Dimcolor = strip.Color(Red(color) >> 1, Green(color) >> 1, Blue(color) >> 1); - return Dimcolor; - } - - // Returns the Red component of a 32-bit color - uint8_t Red(uint32_t color) - { - return (color >> 16) & 0xFF; - } - - // Returns the Green component of a 32-bit color - uint8_t Green(uint32_t color) - { - return (color >> 8) & 0xFF; - } - - // Returns the Blue component of a 32-bit color - uint8_t Blue(uint32_t color) - { - return color & 0xFF; - } - - void Increment() - { - if (Direction == FORWARD) - { - Index++; - if (Index >= (strip.numPixels() - 1) * 2) - { - Index = 0; - } - } - else // Direction == REVERSE - { - --Index; - if (Index <= 0) - { - Index = (strip.numPixels() - 1) * 2 - 1; - } - } - } - - void led_larson() { int EyeSize = 5; @@ -614,25 +314,6 @@ void loop() { } - 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) { @@ -774,107 +455,5 @@ void loop() { return true; } - void setup() { - Serial.begin(115200); - Serial << endl << endl; - - Serial << "Begin strip" << endl; - strip.begin(); - strip.show(); // Initialize all pixels to 'off' - - - led_fill(strip.Color(100, 0, 0)); - //delay(500); - - - - Serial << "Homie_setFirmware" << endl; - Homie_setFirmware("pixelprojektor", "1.0.0"); - - Serial << "Homie node advertise" << endl; - homieNode.advertise("effect").settable(effectHandler); - homieNode.advertise("pixels").settable(pixelsHandler); - homieNode.advertise("icon").settable(iconHandler); - - - - led_fill(strip.Color(0, 0, 0)); - strip.setPixelColor(0, strip.Color(100, 0, 0)); - strip.show(); - - Serial << "homie setup" << endl; - Homie.setup(); - - // Hostname defaults to esp8266-[ChipID] - ArduinoOTA.setHostname("pixelprojektor"); - - // No authentication by default - // ArduinoOTA.setPassword((const char *)"ctdo2342"); - - ArduinoOTA.onStart([]() { - Serial.println("Start"); - led_fill(strip.Color(0, 0, 0)); // Clear - }); - ArduinoOTA.onEnd([]() { - Serial.println("\nEnd"); - }); - ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { - strip.setPixelColor(numToPos((progress / (total / strip.numPixels()))), strip.Color(100, 0, 0)); - strip.show(); - Serial.printf("Progress: %u%%\r", (progress / (total / 100))); - }); - ArduinoOTA.onError([](ota_error_t error) { - Serial.printf("Error[%u]: ", error); - if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); - else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); - else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); - else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); - else if (error == OTA_END_ERROR) Serial.println("End Failed"); - }); - ArduinoOTA.begin(); - - effect = EFFECT_LARSON; - - Serial << "Setup finished" << endl; - } - - void loop() { - Homie.loop(); - ArduinoOTA.handle(); - - long currentMillis = millis(); - - - if (lastMillis + fpsdelay < currentMillis) { - if (iconCountdown > 0) { //icon effect active - iconCountdown--; - led_icon(iconchar, iconcolor); - } else { - switch (effect) { - case EFFECT_SMOOTH: - led_movingPoint(); - led_smooth(); - break; - case EFFECT_SPIRAL: - led_spiral(); - break; - case EFFECT_RANDOMFADE: - led_randomfade(); - break; - case EFFECT_CHASE: - led_chase(); - break; - case EFFECT_RADAR: - led_radar(); - break; - case EFFECT_LARSON: - led_larson(); - break; - } - } - lastMillis = currentMillis; - } - - } */