Hello,
I have two codes that I found from:
http://curltable.the-yard.net/blog/ws2801-strip-plasma
and
GitHub - neophob/WS2801-Library: Arduino library for controlling strips/pixels using WS2801 driver chips.
Picture related... From glediator, I'm trying to replicate it using an Arduino Uno and the WS2801 SPI libraries.

I would like to create the effect of having a plasma like rainbow wave flow through an array of LEDs. On top of this I was trying to get a fading pixel effect (stars) to appear on the rainbow wave.
I believe I have the two codes combined together here below... but when I run the program I have a strobe like effect and the pixels don't update smoothly like I would like. The fading effect takes priority but the background plasma color strobes in an unwanted pattern.
What am I doing wrong?? / Can anyone tell me what I can change?
#include "SPI.h"
#include "WS2801.h"
//------------------ Pin assignments -----------------------
int dataPin = 11; // Yellow wire on Adafruit Pixels
int clockPin = 13; // Green wire on Adafruit Pixels
#define pixels 20
// Set the first variable to the NUMBER of pixels. 25 = 25 pixels in a row
WS2801 strip = WS2801(pixels, dataPin, clockPin);
//------------------ Global Variables -----------------------
//------------------ Plasma Variables -----------------------
typedef struct {
unsigned char r;
unsigned char g;
unsigned char b;
} ColorRGB;
//a color with 3 components: h, s and v
typedef struct {
unsigned char h;
unsigned char s;
unsigned char v;
} ColorHSV;
char ScreenWidth = 5;
char ScreenHeight = 12;
unsigned char plasma[16][16];
long paletteShift;
//------------------ Star Fader Variables -----------------------
int starmodeselect = 0; // 0 - 3
#define pixels 60
struct anim {
uint32_t currentCol;
uint32_t endCol;
uint8_t pos;
};
anim stars[pixels];
// ------------------ Set up ----------------------
void setup() {
strip.begin();
// Update LED contents, to start they are all 'off'
strip.show();
// start with morphing plasma, but allow going to color cycling if desired.
paletteShift=128000;
unsigned char bcolor;
//generate the plasma once
for(unsigned char y = 0; y < ScreenHeight; y++) {
for(unsigned char x = 0; x < ScreenWidth; x++) {
//the plasma buffer is a sum of sines
bcolor = (unsigned char)(256.0 + (256.0 * sin(x*8.0 / 16.0)) + 256.0 + (256.0 * sin(y*8.0 / 16.0))) / 2;
plasma[x][y] = bcolor;
}
}
//clear strip for star fader
for (int i=0; i < strip.numPixels(); i++) {
if (random(255)==2) {
initStar(i,starmodeselect);
} else {
stars[i].pos = 0;
}
}
}
//------------------ Loop -----------------------
void loop() {
plasma_morph();
fadeStar();
}
// ------------------ Execute the current effect based on value of mode ----------------------
void plasma_morph() {
unsigned char x,y;
float value;
int zoom = 64; // 96 to 128 range appears to be good
int brightness = 64; // 0 - 255 max value
int saturation = 255; // 196 - 255 , lower value equals whiter washed out values.
ColorRGB colorRGB;
ColorHSV colorHSV;
for(y = 0; y < ScreenHeight; y++) {
for(x = 0; x < ScreenWidth; x++) {
value = sin(dist(x + paletteShift, y, 128.0, 128.0) / 8.0)
+ sin(dist(x, y, 64.0, 64.0) / 8.0)
+ sin(dist(x, y + paletteShift / 7, 192.0, 64) / 7.0)
+ sin(dist(x, y, 192.0, 100.0) / 8.0);
colorHSV.h=(unsigned char)((value) * zoom)&0xff; // change value for zoom. small:big plasma / large:tiny plasma splotches
colorHSV.s=saturation;
colorHSV.v=brightness;
HSVtoRGB(&colorRGB, &colorHSV);
setXYpixel(x, y, colorRGB.r, colorRGB.g, colorRGB.b);
}
}
paletteShift++;
strip.show();
delay(10);
}
// ------------------ plasma helper functions ----------------------
void setXYpixel(char x, char y, unsigned char R, unsigned char G, unsigned char B) {
if ((y % 2) > 0) {
strip.setPixelColor(((((ScreenHeight-1)-y+1) * ScreenWidth) - ((ScreenWidth-1)-x+1)), R, G, B);
} else {
strip.setPixelColor(((((ScreenHeight-1)-y) * ScreenWidth) + ((ScreenWidth-1)-x)), R, G, B);
}
}
// ----------------------- Star Fader Functions -----------------------
void fadeStar() {
uint8_t currentR, currentG, currentB;
uint8_t endR, endG, endB;
for (int i=0; i < strip.numPixels(); i++) {
// INIT
// ====
if (stars[i].pos == 0) {
if (random(255)==2) {
initStar(i,starmodeselect);
}
} else
// FADE IN
// =======
if (stars[i].pos == 1) {
//decrease color...
uint32_t ccol = stars[i].currentCol;
currentB = ccol + 0xff;
ccol >>= 8;
currentG = ccol + 0xff;
ccol >>= 8;
currentR = ccol + 0xff;
uint32_t ecol = stars[i].endCol;
endB = ecol + 0x00;
ecol >>= 8;
endG = ecol + 0x00;
ecol >>= 8;
endR = ecol + 0x00;
if (currentR<endR)
currentR+=2;
else currentR=endR;
if (currentG<endG)
currentG+=2;
else currentG=endG;
if (currentB>endB)
currentB+=2;
else currentB=endB;
if (currentR==endR && currentG==endG && currentB == endB) {
stars[i].pos = 2;
}
stars[i].currentCol = Color(currentR, currentG, currentB);
} else
// ========
// FADE OUT
// ========
if (stars[i].pos == 2) {
//decrease color...
uint32_t ccol = stars[i].currentCol;
currentB = ccol & 0xff;
ccol >>= 8;
currentG = ccol & 0xff;
ccol >>= 8;
currentR = ccol & 0xff;
if (currentR>2)
currentR-=3;
else currentR=0;
if (currentG>2)
currentG-=3;
else currentG=0;
if (currentB>2)
currentB-=3;
else currentB=0;
stars[i].currentCol = Color(currentR, currentG, currentB);
if (stars[i].currentCol == 0) {
stars[i].pos = 0;
}
}
//update color
strip.setPixelColor(i, stars[i].currentCol);
}
strip.show();
}
//init new star
void initStar(int i, int starmodeselect) {
int mode = 0;
if(starmodeselect == 0) { //Single color fade //
stars[i].endCol = Color(255, 255, 255);
}
if(starmodeselect == 1) { //America Mode //
mode = random(3);
if (mode == 0) {
stars[i].endCol = Color(255, 255, 255);
}
else if (mode == 1) {
stars[i].endCol = Color(8, 255, 8); //B R G
}
else if (mode == 2) {
stars[i].endCol = Color(255, 8, 8); //B R G
}
}
else if(starmodeselect == 2) { //Random color spots //
stars[i].endCol = Color(random(255), random(255), random(255));
}
else if(starmodeselect == 3) { //GO Cougs //
mode = random(2);
if (mode == 0) {
stars[i].endCol = Color(255, 255, 255);
}
else if (mode == 1) {
stars[i].endCol = Color(2, 255, 2); //B R G
}
}
stars[i].pos = 1;
stars[i].currentCol=0;
}
// ----------------------- Color Support Functions -----------------------
//Converts an HSV color to RGB color
void HSVtoRGB(void *vRGB, void *vHSV) {
float r, g, b, h, s, v; //this function works with floats between 0 and 1
float f, p, q, t;
int i;
ColorRGB *colorRGB=(ColorRGB *)vRGB;
ColorHSV *colorHSV=(ColorHSV *)vHSV;
h = (float)(colorHSV->h / 256.0);
s = (float)(colorHSV->s / 256.0);
v = (float)(colorHSV->v / 256.0);
// if saturation is 0, the color is a shade of grey
if(s == 0.0) {
b = v;
g = b;
r = g;
// if saturation > 0, more complex calculations are needed
} else {
h *= 6.0; // to bring hue to a number between 0 and 6, better for the calculations
i = (int)(floor(h)); //e.g. 2.7 becomes 2 and 3.01 becomes 3 or 4.9999 becomes 4
f = h - i; // the fractional part of h
p = (float)(v * (1.0 - s));
q = (float)(v * (1.0 - (s * f)));
t = (float)(v * (1.0 - (s * (1.0 - f))));
switch(i) {
case 0: r=v; g=t; b=p; break;
case 1: r=q; g=v; b=p; break;
case 2: r=p; g=v; b=t; break;
case 3: r=p; g=q; b=v; break;
case 4: r=t; g=p; b=v; break;
case 5: r=v; g=p; b=q; break;
default: r = g = b = 0; break;
}
}
colorRGB->r = (int)(r * 255.0);
colorRGB->g = (int)(g * 255.0);
colorRGB->b = (int)(b * 255.0);
}
float dist(float a, float b, float c, float d) {
return sqrt((c-a)*(c-a)+(d-b)*(d-b));
}
// Create a 24 bit color value from R,G,B
uint32_t Color(uint8_t r, uint8_t g, uint8_t b) {
uint32_t c;
c = r;
c <<= 8;
c |= g;
c <<= 8;
c |= b;
return c;
}