Effect: Plasma added

This commit is contained in:
starcalc 2017-03-02 11:06:29 +01:00
parent 755abb3317
commit 535281750e
3 changed files with 87 additions and 4 deletions

View File

@ -46,6 +46,9 @@ void NeoPatterns::Update() {
case ICON: case ICON:
IconUpdate(); IconUpdate();
break; break;
case PLASMA:
PlasmaUpdate();
break;
case NONE: case NONE:
break; break;
default: default:
@ -449,6 +452,70 @@ void NeoPatterns::IconComplete()
Direction = SavedDirection; Direction = SavedDirection;
} }
// Based upon https://github.com/johncarl81/neopixelplasma
void NeoPatterns::Plasma(float phase, float phaseIncrement, float colorStretch, uint8_t interval)
{
ActivePattern = PLASMA;
Interval = interval;
PlasmaPhase = phase;
PlasmaPhaseIncrement = phaseIncrement;
PlasmaColorStretch = colorStretch;
}
void NeoPatterns::PlasmaUpdate()
{
PlasmaPhase += PlasmaPhaseIncrement;
int edge = (int)sqrt(numPixels());
// The two points move along Lissajious curves, see: http://en.wikipedia.org/wiki/Lissajous_curve
// The sin() function returns values in the range of -1.0..1.0, so scale these to our desired ranges.
// The phase value is multiplied by various constants; I chose these semi-randomly, to produce a nice motion.
Point p1 = { (sin(PlasmaPhase * 1.000) + 1.0) * (edge / 2), (sin(PlasmaPhase * 1.310) + 1.0) * (edge / 2) };
Point p2 = { (sin(PlasmaPhase * 1.770) + 1.0) * (edge / 2), (sin(PlasmaPhase * 2.865) + 1.0) * (edge / 2) };
Point p3 = { (sin(PlasmaPhase * 0.250) + 1.0) * (edge / 2), (sin(PlasmaPhase * 0.750) + 1.0) * (edge / 2)};
byte row, col;
// For each row...
for ( row = 0; row < edge; row++ ) {
float row_f = float(row); // Optimization: Keep a floating point value of the row number, instead of recasting it repeatedly.
// For each column...
for ( col = 0; col < edge; col++ ) {
float col_f = float(col); // Optimization.
// Calculate the distance between this LED, and p1.
Point dist1 = { col_f - p1.x, row_f - p1.y }; // The vector from p1 to this LED.
float distance1 = sqrt( dist1.x * dist1.x + dist1.y * dist1.y );
// Calculate the distance between this LED, and p2.
Point dist2 = { col_f - p2.x, row_f - p2.y }; // The vector from p2 to this LED.
float distance2 = sqrt( dist2.x * dist2.x + dist2.y * dist2.y );
// Calculate the distance between this LED, and p3.
Point dist3 = { col_f - p3.x, row_f - p3.y }; // The vector from p3 to this LED.
float distance3 = sqrt( dist3.x * dist3.x + dist3.y * dist3.y );
// Warp the distance with a sin() function. As the distance value increases, the LEDs will get light,dark,light,dark,etc...
// You can use a cos() for slightly different shading, or experiment with other functions. Go crazy!
float color_1 = distance1; // range: 0.0...1.0
float color_2 = distance2;
float color_3 = distance3;
float color_4 = (sin( distance1 * distance2 * PlasmaColorStretch )) + 2.0 * 0.5;
// Square the color_f value to weight it towards 0. The image will be darker and have higher contrast.
color_1 *= color_1 * color_4;
color_2 *= color_2 * color_4;
color_3 *= color_3 * color_4;
color_4 *= color_4;
// Scale the color up to 0..7 . Max brightness is 7.
//strip.setPixelColor(col + (edge * row), strip.Color(color_4, 0, 0) );
setPixelColor(col + (edge * row), Color(color_1, color_2, color_3));
}
}
show();
}
/****************** Helper functions ******************/ /****************** Helper functions ******************/
void NeoPatterns::SetColor1(uint32_t color) { void NeoPatterns::SetColor1(uint32_t color) {

View File

@ -2,7 +2,7 @@
#include "font.h" #include "font.h"
// Pattern types supported: // Pattern types supported:
enum pattern { NONE, RAINBOW_CYCLE, THEATER_CHASE, COLOR_WIPE, SCANNER, FADE, RANDOM_FADE, SMOOTH, ICON, RANDOM_FADE_SINGLE }; enum pattern { NONE, RAINBOW_CYCLE, THEATER_CHASE, COLOR_WIPE, SCANNER, FADE, RANDOM_FADE, SMOOTH, ICON, RANDOM_FADE_SINGLE, PLASMA };
// Patern directions supported: // Patern directions supported:
enum direction { FORWARD, REVERSE }; enum direction { FORWARD, REVERSE };
@ -36,6 +36,8 @@ class NeoPatterns : public Adafruit_NeoPixel
void Icon(uint8_t fontchar, String iconcolor = "#FFFFFF", uint8_t interval = 30); void Icon(uint8_t fontchar, String iconcolor = "#FFFFFF", uint8_t interval = 30);
void IconUpdate(); void IconUpdate();
void IconComplete(); void IconComplete();
void Plasma(float phase = 0, float phaseIncrement = 0.03, float colorStretch = 0.3, uint8_t interval = 60); // 0.08 and 0.11
void PlasmaUpdate();
void SetColor1(uint32_t color); void SetColor1(uint32_t color);
void SetColor2(uint32_t color); void SetColor2(uint32_t color);
@ -89,8 +91,19 @@ class NeoPatterns : public Adafruit_NeoPixel
uint8_t FontChar; uint8_t FontChar;
float PlasmaPhase;
float PlasmaPhaseIncrement;
float PlasmaColorStretch;
uint32_t DimColor(uint32_t color); uint32_t DimColor(uint32_t color);
void Increment(); void Increment();
void (*OnComplete)(); // Callback on completion of pattern void (*OnComplete)(); // Callback on completion of pattern
// Convenient 2D point structure
struct Point {
float x;
float y;
};
}; };

View File

@ -6,7 +6,7 @@
#include <avr/power.h> #include <avr/power.h>
#endif #endif
#define PIN 2 //data pin for ws2812 (pixelprojektor @ ctdo: PIN 2) #define PIN D1 //data pin for ws2812 (pixelprojektor @ ctdo: PIN 2)
#define NUMPIXELS 64 #define NUMPIXELS 64
NeoPatterns strip = NeoPatterns(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800, &StripComplete); NeoPatterns strip = NeoPatterns(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800, &StripComplete);
@ -92,10 +92,13 @@ bool onSetEffect(const HomieRange& range, const String& value) {
} }
else if (effect == "random") { else if (effect == "random") {
strip.Random(); strip.Random();
} else if (effect == "smooth") { //example: smooth|[wheelspeed]|[smoothing]|[strength] wheelspeed=1-255, smoothing=0-100, strength=1-255 }
else if (effect == "smooth") { //example: smooth|[wheelspeed]|[smoothing]|[strength] wheelspeed=1-255, smoothing=0-100, strength=1-255
strip.Smooth(16, 80, 50, 40); strip.Smooth(16, 80, 50, 40);
} }
else { else if (effect == "plasma") {
strip.Plasma();
} else {
// Test whether command with parameters was sent // Test whether command with parameters was sent
int sep = value.indexOf("|"); int sep = value.indexOf("|");
String command = value.substring(0, sep); String command = value.substring(0, sep);