Creating a Plasma effect for the Arduino and the Sparkfun LED tile
Posted in Programming, real-time video on December 26th, 2009 by admin – Be the first to commentAfter having discovered the Arduino and before attacking the network extension I wanted to create something fun with the board and the 8 by 8 LED tile.
So I came with the idea of using one old school plasma effect of ArKaos VJ and porting it to the Arduino.
Here is the result:
Basically there are 2 textures pre-computed at startup. They are moved on a circular motion.
The 2 textures are moved and summed and you obtain an height value for each pixel. To get a nice effect you then go through a color table that is also pre-computed at startup.
To have a nice rotation effect you shift the color table at each generation of a new image.
At the end of the video you have another simple loop I did to test my setup.
Here is the plasma code for the Arduino:
//
// Plasma generation for the Arduino and a RGB Serial Backpack Matrix from SparkFun Electronics
// Marco Hinic, built on top of the code of Ryan Owens
//
//Define the SPI Pin Numbers
#define DATAOUT 11//MOSI
#define DATAIN 12//MISO
#define SPICLOCK 13//sck
#define SLAVESELECT 10//ss
void LED_Setup() //Set the pin modes for the RGB matrix //Make sure the RGB matrix is deactivated // #define PLASMA_W 8 #define TABLE_W 16 unsigned char gPlasma[PLASMA_W*PLASMA_H]; void Plasma_CalcTable1 () void Plasma_CalcTable2 () void Plasma_SetColor (int index, unsigned char red, unsigned char green, unsigned char blue) double gRed, gGreen, gBlue; #define color(u,a) (cos((u)+(a))+1)*127 void BuildColorTable() gRed+=0.05; void Plasma_Setup () for (int i=0; i Plasma_CalcTable1 (); gRed=1.0/6.0*PI; BuildColorTable (); void setup() void ComputePlasma (int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4,int roll) for (i=0; i< PLASMA_H; i++) unsigned int new_height = gTable1[TABLE_W*(i+y1)+j+x1]; new_height = new_height & 0xFF; new_height = gColorTable[new_height]; gPlasma[index] = new_height; char SendOneChar (volatile char data) void SendToLEDs () void loop() float ratio = 2; gCircle1 = gCircle1 + (ratio * 0.085/6); x2=(PLASMA_W/2)+(PLASMA_W/2)*sin(gCircle1); x1=(PLASMA_W/2)+(PLASMA_W/2)*cos(gCircle3); x3=(PLASMA_W/2)+(PLASMA_W/2)*cos(gCircle5); x4=(PLASMA_W/2)+(PLASMA_W/2)*cos(gCircle7); ComputePlasma(x1,y1,x2,y2,x3,y3,x4,y4,gRoll); gRoll = gRoll + 1; SendToLEDs(); delay (20);
{
//SPI Bus setup
SPCR = (1<
pinMode(DATAOUT, OUTPUT);
pinMode(DATAIN, INPUT);
pinMode(SPICLOCK,OUTPUT);
pinMode(SLAVESELECT,OUTPUT);
digitalWrite(SLAVESELECT,HIGH);
}
// tables for plasma
//
// 8 by 8 -> 64 bytes
// 16 by 16 -> 256 bytes
// color table 256 bytes
//
#define PLASMA_H 8
#define TABLE_H 16
unsigned char gTable1[TABLE_W*TABLE_H];
unsigned char gTable2[TABLE_W*TABLE_H];
unsigned char gColorTable[256];
float gCircle1, gCircle2, gCircle3, gCircle4, gCircle5, gCircle6, gCircle7, gCircle8;
int gRoll;
{
for (int i=0; i< TABLE_H; i++)
{
for (int j=0; j< TABLE_W; j++)
{
int index = (i*TABLE_W)+j;
gTable1[index] = (unsigned char) ((sqrt(16.0+(PLASMA_H-i)*(PLASMA_H-i)+(PLASMA_W-j)*(PLASMA_W-j))-4) *5 );
}
}
}
{
for (int i=0; i< TABLE_H; i++)
{
for (int j=0; j< TABLE_W; j++)
{
int index = (i*TABLE_W)+j;
float temp = sqrt(16.0+(PLASMA_H-i)*(PLASMA_H-i)+(PLASMA_W-j)*(PLASMA_W-j))-4;
gTable2[index] = (sin(temp/9.5)+1)*90;
}
}
}
{
unsigned char new_color = (red & 0xE0) + ((green & 0xE0) >> 3) + ((blue & 0xC0) >> 6);
gColorTable [index] = new_color;
}
{
double u;
int i;
for (i=0; i<256; i++)
{
u=2*PI/256*i;
Plasma_SetColor(i,color(u,gRed),color(u,gGreen),color(u,gBlue));
}
gGreen-=0.05;
gBlue+=0.1;
}
{
gCircle1 = 0;
gCircle2 = 0;
gCircle3 = 0;
gCircle4 = 0;
gCircle5 = 0;
gCircle6 = 0;
gCircle7 = 0;
gCircle8 = 0;
gRoll = 0;
Plasma_CalcTable2 ();
gGreen=3.0/6.0*PI;
gBlue=5.0/6.0*PI;
}
{
LED_Setup ();
Plasma_Setup ();
}
{
int i, j;
{
for (j=0; j< PLASMA_W; j++)
{
int index = (i*PLASMA_W)+j;
new_height = new_height + roll;
new_height = new_height + gTable2[TABLE_W*(i+y2)+j+x2];
new_height = new_height + gTable2[TABLE_W*(i+y3)+j+x3]; // + gTable2[TABLE_W*(i+y4)+j+x4];
}
}
}
{
SPDR = data; // Start the transmission
while (!(SPSR & (1<
};
return SPDR; // return the received byte
}
{
int i;
//Activate the RGB Matrix
digitalWrite(SLAVESELECT, LOW);
//Send the color buffer to the RGB Matrix
for(i=0; i
SendOneChar((char)gPlasma[i]);
}
//Deactivate the RGB matrix.
digitalWrite(SLAVESELECT, HIGH);
}
{
int x1,y1,x2,y2,x3,y3,x4,y4;
gCircle2 = gCircle2 – (ratio * 0.1/6);
gCircle3 = gCircle3 + (ratio * 0.3/6);
gCircle4 = gCircle4 – (ratio * 0.2/6);
gCircle5 = gCircle5 + (ratio * 0.4/6);
gCircle6 = gCircle6 – (ratio * 0.15/6);
gCircle7 = gCircle7 + (ratio * 0.35/6);
gCircle8 = gCircle8 – (ratio * 0.05/6);
y2=(PLASMA_H/2)+(PLASMA_H/2)*cos(gCircle2);
y1=(PLASMA_H/2)+(PLASMA_H/2)*sin(gCircle4);
y3=(PLASMA_H/2)+(PLASMA_H/2)*sin(gCircle6);
y4=(PLASMA_H/2)+(PLASMA_H/2)*sin(gCircle8);
}









