2011-10-04 17:09:09 +00:00
|
|
|
// "Colorswirl" LED demo. This is the host PC-side code written in
|
|
|
|
// Processing; intended for use with a USB-connected Arduino microcontroller
|
|
|
|
// running the accompanying LED streaming code. Requires one strand of
|
|
|
|
// Digital RGB LED Pixels (Adafruit product ID #322, specifically the newer
|
|
|
|
// WS2801-based type, strand of 25) and a 5 Volt power supply (such as
|
|
|
|
// Adafruit #276). You may need to adapt the code and the hardware
|
|
|
|
// arrangement for your specific configuration.
|
|
|
|
|
2012-12-05 20:02:32 +00:00
|
|
|
// --------------------------------------------------------------------
|
|
|
|
// This file is part of Adalight.
|
|
|
|
|
|
|
|
// Adalight is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU Lesser General Public License as
|
|
|
|
// published by the Free Software Foundation, either version 3 of
|
|
|
|
// the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
// Adalight is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU Lesser General Public License for more details.
|
|
|
|
|
|
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
|
|
// License along with Adalight. If not, see
|
|
|
|
// <http://www.gnu.org/licenses/>.
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
2011-10-04 17:09:09 +00:00
|
|
|
import processing.serial.*;
|
|
|
|
|
|
|
|
int N_LEDS = 25; // Max of 65536
|
|
|
|
|
|
|
|
void setup()
|
|
|
|
{
|
|
|
|
byte[] buffer = new byte[6 + N_LEDS * 3];
|
|
|
|
Serial myPort;
|
|
|
|
int i, hue1, hue2, bright, lo, r, g, b, t, prev, frame = 0;
|
|
|
|
long totalBytesSent = 0;
|
|
|
|
float sine1, sine2;
|
|
|
|
|
|
|
|
noLoop();
|
|
|
|
|
|
|
|
// Assumes the Arduino is the first/only serial device. If this is not the
|
|
|
|
// case, change the device index here. println(Serial.list()); can be used
|
|
|
|
// to get a list of available serial devices.
|
|
|
|
myPort = new Serial(this, Serial.list()[0], 115200);
|
|
|
|
|
|
|
|
// A special header / magic word is expected by the corresponding LED
|
|
|
|
// streaming code running on the Arduino. This only needs to be initialized
|
|
|
|
// once because the number of LEDs remains constant:
|
|
|
|
buffer[0] = 'A'; // Magic word
|
|
|
|
buffer[1] = 'd';
|
|
|
|
buffer[2] = 'a';
|
|
|
|
buffer[3] = byte((N_LEDS - 1) >> 8); // LED count high byte
|
|
|
|
buffer[4] = byte((N_LEDS - 1) & 0xff); // LED count low byte
|
|
|
|
buffer[5] = byte(buffer[3] ^ buffer[4] ^ 0x55); // Checksum
|
|
|
|
|
|
|
|
sine1 = 0.0;
|
|
|
|
hue1 = 0;
|
|
|
|
prev = second(); // For bandwidth statistics
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
sine2 = sine1;
|
|
|
|
hue2 = hue1;
|
|
|
|
|
|
|
|
// Start at position 6, after the LED header/magic word
|
|
|
|
for (i = 6; i < buffer.length; ) {
|
|
|
|
// Fixed-point hue-to-RGB conversion. 'hue2' is an integer in the
|
|
|
|
// range of 0 to 1535, where 0 = red, 256 = yellow, 512 = green, etc.
|
|
|
|
// The high byte (0-5) corresponds to the sextant within the color
|
|
|
|
// wheel, while the low byte (0-255) is the fractional part between
|
|
|
|
// the primary/secondary colors.
|
|
|
|
lo = hue2 & 255;
|
|
|
|
switch((hue2 >> 8) % 6) {
|
|
|
|
case 0:
|
|
|
|
r = 255;
|
|
|
|
g = lo;
|
|
|
|
b = 0;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
r = 255 - lo;
|
|
|
|
g = 255;
|
|
|
|
b = 0;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
r = 0;
|
|
|
|
g = 255;
|
|
|
|
b = lo;
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
r = 0;
|
|
|
|
g = 255 - lo;
|
|
|
|
b = 255;
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
r = lo;
|
|
|
|
g = 0;
|
|
|
|
b = 255;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
r = 255;
|
|
|
|
g = 0;
|
|
|
|
b = 255 - lo;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Resulting hue is multiplied by brightness in the range of 0 to 255
|
|
|
|
// (0 = off, 255 = brightest). Gamma corrrection (the 'pow' function
|
|
|
|
// here) adjusts the brightness to be more perceptually linear.
|
|
|
|
bright = int(pow(0.5 + sin(sine2) * 0.5, 2.8) * 255.0);
|
|
|
|
buffer[i++] = byte((r * bright) / 255);
|
|
|
|
buffer[i++] = byte((g * bright) / 255);
|
|
|
|
buffer[i++] = byte((b * bright) / 255);
|
|
|
|
|
|
|
|
// Each pixel is slightly offset in both hue and brightness
|
|
|
|
hue2 += 40;
|
|
|
|
sine2 += 0.3;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Slowly rotate hue and brightness in opposite directions
|
|
|
|
hue1 = (hue1 + 4) % 1536;
|
|
|
|
sine1 -= .03;
|
|
|
|
|
|
|
|
// Issue color data to LEDs and keep track of the byte and frame counts
|
|
|
|
myPort.write(buffer);
|
|
|
|
totalBytesSent += buffer.length;
|
|
|
|
frame++;
|
|
|
|
|
|
|
|
// Update statistics once per second
|
|
|
|
if ((t = second()) != prev) {
|
|
|
|
print("Average frames/sec: ");
|
|
|
|
print(int((float)frame / (float)millis() * 1000.0));
|
|
|
|
print(", bytes/sec: ");
|
|
|
|
println(int((float)totalBytesSent / (float)millis() * 1000.0));
|
|
|
|
prev = t;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void draw()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|