Code: Select all
#include <SPI.h>
#include <Cube.h>
/*
* A mega demo for the Freetronics Cube4.
*
* Shows a variety of effects in random sequence:
*
* - Sparkling.
* - Shifting wall of colour.
* - Coloured rain.
* - Slow pulse.
* - Fast flash.
* - Three different rainbow faders.
* - Diagonal pulser.
* - Random fill.
*
* (C)2013 bb@buxtronix.net, licenced under the GPLv2. (except as noted)
*/
rgb_t colours[3] = {RED, GREEN, BLUE};
byte xPos, yPos, zPos;
// Constants to define the ranges.
const int hueRedLow = 0;
const int hueRedHigh = 255;
const int hueBlue = 170;
// The size of the angle of one sector (1/6 of a colour wheel), and of a complete
// cycle of the colour wheel.
const int angleMin = 0;
const int angleSector = 60;
const int angleMax = 360;
const int brightMin = 0;
const int brightMax = 255;
int hueValue;
Cube cube;
void setup(void) {
// Serial port options for control of the Cube using serial commands are:
// 0: Control via the USB connector (most common).
// 1: Control via the RXD and TXD pins on the main board.
// -1: Don't attach any serial port to interact with the Cube.
cube.begin(0, 115200); // Start on serial port 0 (USB) at 115200 baud
pinMode(A0, INPUT);
randomSeed(analogRead(A0));
}
// Generate a random colour with maximum saturation.
rgb_t RandomColour() {
return HSBToRGB(random(255), 255, 255);
}
// Whole cube cycles a rainbow.
void rainbow1() {
for (hueValue = 0 ; hueValue < 255 ; hueValue+=4) {
cube.all(HSBToRGB(hueValue, 255, 255));
delay(20);
}
}
// Cycle colours in rainbow fashion across a random plane.
void rainbow() {
byte plane = random(3);
byte dir = random(2);
byte hue = 0;
for (byte i = 0 ; i < 150 ; i++) {
for (byte z = 0 ; z < 4 ; z++) {
byte h = hue + (z*32);
cube.setplane(plane, z, HSBToRGB(h, 255, 255));
}
delay(20);
hue += (dir ? 4 : -4);
}
}
// A diagonal rainbow from 0,0,0
void rainbow2() {
byte hueref = random(255);
byte dir = random(16);
byte hue;
byte fx, fy, fz;
for (byte i = 0 ; i < 255 ; i++) {
for (byte x = 0 ; x < 4 ; x++) {
for (byte y = 0 ; y < 4 ; y++) {
for (byte z = 0 ; z < 4 ; z++) {
// Goes from a random corner diagonally.
fx = x; fy = y; fz = z;
if (dir & 0x1 == 1) {
fx = 4-x;
} else if (dir & 0x2 == 2) {
fy = 4-y;
} else if (dir & 0x4 == 4){
fz = 4-z;
}
hue = hueref + (fx+fy+fz)*14;
cube.set(x, y, z, HSBToRGB(hue, 255, 255));
}
}
}
delay(20);
hueref += (dir & 0x8 == 0x8 ? 4 : -4);
}
}
// Sparkle the cube, white flickering LEDs.
void sparkle() {
byte x, y, z;
byte count = random(20, 30);
for (byte i = 0 ; i < count ; i++) {
x = random(0, 4);
y = random(0, 4);
z = random(0, 4);
delay(20);
cube.set(x, y, z, WHITE);
delay(50);
cube.set(x, y, z, BLACK);
}
}
// Set LEDs to the supplied colour in a random sequence.
void fill(rgb_t colour) {
for (byte filled = 0 ; filled < 64 ;) {
char x = random(4);
char y = random(4);
char z = random(4);
rgb_t ledvalue = led[x][y][z];
if (ledvalue.color[0] != colour.color[0] ||
ledvalue.color[1] != colour.color[1] ||
ledvalue.color[2] != colour.color[2]) {
cube.set(x, y, z, colour);
filled++;
delay(20);
}
}
}
// Moving walls of colour.
void colourwall() {
byte plane = random(0, 3);
rgb_t colour = RandomColour();
cube.setplane(plane, 3, colour);
delay(100);
for (zPos = 3 ; zPos > 0 ; zPos--) {
cube.moveplane(plane, zPos, zPos-1, BLACK);
delay(100);
}
for (zPos = 0 ; zPos < 3 ; zPos++) {
cube.moveplane(plane, zPos, zPos+1, BLACK);
delay(100);
}
}
// Pulse LEDs a random colour.
void pulse (void) {
byte hue = random(0, 255);
for (int value = 0 ; value < 255 ; value+=8) {
cube.all(HSBToRGB(hue, 255, value));
delay(10);
}
for (int value = 255 ; value > 0 ; value-=8) {
cube.all(HSBToRGB(hue, 255, value));
delay(10);
}
delay(50);
}
// A diagonal pulse.
void pulse2() {
unsigned int brightref = 0;
byte dir = random(16);
byte hue = random(255);
unsigned int bright;
byte fx, fy, fz;
for (byte i = 0 ; i < 128 ; i++) {
for (byte x = 0 ; x < 4 ; x++) {
for (byte y = 0 ; y < 4 ; y++) {
for (byte z = 0 ; z < 4 ; z++) {
// Goes from a random corner diagonally.
fx = x; fy = y; fz = z;
if (dir & 0x1 == 1) {
fx = 4-x;
} else if (dir & 0x2 == 2) {
fy = 4-y;
} else if (dir & 0x4 == 4){
fz = 4-z;
}
bright = brightref + (fx+fy+fz)*48;
if (bright > 255 && bright < 511) {
bright = 510 - bright;
} else if (bright > 510) {
bright = 0;
}
cube.set(x, y, z, HSBToRGB(hue, 255, bright));
}
}
}
delay(10);
brightref += 8;
if (brightref > 510) brightref = 0;
}
}
// Flash the LEDs quickly, between 1 and 3 times.
void flash(void) {
rgb_t colour = colours[random(0, 3)];
delay(100);
for (byte i = 0 ; i < random(0, 4) ; i++) {
cube.all(colour);
delay(50);
cube.all(BLACK);
delay(random(0, 255));
}
}
// Drops of coloured rain falling.
void colourrain() {
byte count = random(25, 50);
for (byte i = 0 ; i < count ; i++) {
for (byte z = 1 ; z < 4 ; z++) {
cube.moveplane(Z, z, z-1, BLACK);
}
if (random(2) == 1)
cube.set(random(4), random(4), 3, RandomColour());
delay(100);
}
}
// This function taken from here:
// http://eduardofv.com/read_post/179-Arduino-RGB-LED-HSV-Color-Wheel-
rgb_t HSBToRGB(
unsigned int inHue, unsigned int inSaturation, unsigned int inBrightness)
{
rgb_t retcol;
if (inSaturation == 0) {
// achromatic (grey)
retcol = RGB(inBrightness, inBrightness, inBrightness);
} else {
unsigned int scaledHue = (inHue * 6);
unsigned int sector = scaledHue >> 8; // sector 0 to 5 around the color wheel
unsigned int offsetInSector = scaledHue - (sector << 8); // position within the sector
unsigned int p = (inBrightness * ( 255 - inSaturation )) >> 8;
unsigned int q = (inBrightness * ( 255 - ((inSaturation * offsetInSector) >> 8) )) >> 8;
unsigned int t = (inBrightness * ( 255 - ((inSaturation * ( 255 - offsetInSector )) >> 8) )) >> 8;
switch(sector) {
case 0:
retcol = RGB(inBrightness, t, p);
break;
case 1:
retcol = RGB(q, inBrightness, p);
break;
case 2:
retcol = RGB(p, inBrightness, t);
break;
case 3:
retcol = RGB(p, q, inBrightness);
break;
case 4:
retcol = RGB(t, p, inBrightness);
break;
default: // case 5:
retcol = RGB(inBrightness, p, q);
break;
}
}
return retcol;
}
void loop() {
cube.all(BLACK);
delay(200);
switch(random(10)) {
case 0:
pulse();
break;
case 1:
flash();
break;
case 2:
sparkle();
break;
case 3:
colourrain();
break;
case 4:
rainbow();
break;
case 5:
rainbow2();
break;
case 6:
fill(RandomColour());
delay(200);
fill(BLACK);
break;
case 7:
rainbow1();
break;
case 8:
pulse2();
break;
default:
colourwall();
}
}