diff --git a/Arduino/LEDstream/LEDstream.ino b/Arduino/LEDstream/LEDstream.ino
deleted file mode 100644
index 629ad9e..0000000
--- a/Arduino/LEDstream/LEDstream.ino
+++ /dev/null
@@ -1,246 +0,0 @@
-// Arduino "bridge" code between host computer and WS2801-based digital
-// RGB LED pixels (e.g. Adafruit product ID #322). Intended for use
-// with USB-native boards such as Teensy or Adafruit 32u4 Breakout;
-// works on normal serial Arduinos, but throughput is severely limited.
-// LED data is streamed, not buffered, making this suitable for larger
-// installations (e.g. video wall, etc.) than could otherwise be held
-// in the Arduino's limited RAM.
-
-// Some effort is put into avoiding buffer underruns (where the output
-// side becomes starved of data). The WS2801 latch protocol, being
-// delay-based, could be inadvertently triggered if the USB bus or CPU
-// is swamped with other tasks. This code buffers incoming serial data
-// and introduces intentional pauses if there's a threat of the buffer
-// draining prematurely. The cost of this complexity is somewhat
-// reduced throughput, the gain is that most visual glitches are
-// avoided (though ultimately a function of the load on the USB bus and
-// host CPU, and out of our control).
-
-// LED data and clock lines are connected to the Arduino's SPI output.
-// On traditional Arduino boards, SPI data out is digital pin 11 and
-// clock is digital pin 13. On both Teensy and the 32u4 Breakout,
-// data out is pin B2, clock is B1. LEDs should be externally
-// powered -- trying to run any more than just a few off the Arduino's
-// 5V line is generally a Bad Idea. LED ground should also be
-// connected to Arduino ground.
-
-// --------------------------------------------------------------------
-// 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
-// .
-// --------------------------------------------------------------------
-
-#include
-
-// LED pin for Adafruit 32u4 Breakout Board:
-//#define LED_DDR DDRE
-//#define LED_PORT PORTE
-//#define LED_PIN _BV(PORTE6)
-// LED pin for Teensy:
-//#define LED_DDR DDRD
-//#define LED_PORT PORTD
-//#define LED_PIN _BV(PORTD6)
-// LED pin for Arduino:
-#define LED_DDR DDRB
-#define LED_PORT PORTB
-#define LED_PIN _BV(PORTB5)
-
-// A 'magic word' (along with LED count & checksum) precedes each block
-// of LED data; this assists the microcontroller in syncing up with the
-// host-side software and properly issuing the latch (host I/O is
-// likely buffered, making usleep() unreliable for latch). You may see
-// an initial glitchy frame or two until the two come into alignment.
-// The magic word can be whatever sequence you like, but each character
-// should be unique, and frequent pixel values like 0 and 255 are
-// avoided -- fewer false positives. The host software will need to
-// generate a compatible header: immediately following the magic word
-// are three bytes: a 16-bit count of the number of LEDs (high byte
-// first) followed by a simple checksum value (high byte XOR low byte
-// XOR 0x55). LED data follows, 3 bytes per LED, in order R, G, B,
-// where 0 = off and 255 = max brightness.
-
-static const uint8_t magic[] = {'A','d','a'};
-#define MAGICSIZE sizeof(magic)
-#define HEADERSIZE (MAGICSIZE + 3)
-
-#define MODE_HEADER 0
-#define MODE_HOLD 1
-#define MODE_DATA 2
-
-// If no serial data is received for a while, the LEDs are shut off
-// automatically. This avoids the annoying "stuck pixel" look when
-// quitting LED display programs on the host computer.
-static const unsigned long serialTimeout = 15000; // 15 seconds
-
-void setup()
-{
- // Dirty trick: the circular buffer for serial data is 256 bytes,
- // and the "in" and "out" indices are unsigned 8-bit types -- this
- // much simplifies the cases where in/out need to "wrap around" the
- // beginning/end of the buffer. Otherwise there'd be a ton of bit-
- // masking and/or conditional code every time one of these indices
- // needs to change, slowing things down tremendously.
- uint8_t
- buffer[256],
- indexIn = 0,
- indexOut = 0,
- mode = MODE_HEADER,
- hi, lo, chk, i, spiFlag;
- int16_t
- bytesBuffered = 0,
- hold = 0,
- c;
- int32_t
- bytesRemaining;
- unsigned long
- startTime,
- lastByteTime,
- lastAckTime,
- t;
-
- LED_DDR |= LED_PIN; // Enable output for LED
- LED_PORT &= ~LED_PIN; // LED off
-
- Serial.begin(115200); // Teensy/32u4 disregards baud rate; is OK!
-
- SPI.begin();
- SPI.setBitOrder(MSBFIRST);
- SPI.setDataMode(SPI_MODE0);
- SPI.setClockDivider(SPI_CLOCK_DIV16); // 1 MHz max, else flicker
-
- // Issue test pattern to LEDs on startup. This helps verify that
- // wiring between the Arduino and LEDs is correct. Not knowing the
- // actual number of LEDs connected, this sets all of them (well, up
- // to the first 25,000, so as not to be TOO time consuming) to red,
- // green, blue, then off. Once you're confident everything is working
- // end-to-end, it's OK to comment this out and reprogram the Arduino.
- uint8_t testcolor[] = { 0, 0, 0, 255, 0, 0 };
- for(char n=3; n>=0; n--) {
- for(c=0; c<25000; c++) {
- for(i=0; i<3; i++) {
- for(SPDR = testcolor[n + i]; !(SPSR & _BV(SPIF)); );
- }
- }
- delay(1); // One millisecond pause = latch
- }
-
- Serial.print("Ada\n"); // Send ACK string to host
-
- startTime = micros();
- lastByteTime = lastAckTime = millis();
-
- // loop() is avoided as even that small bit of function overhead
- // has a measurable impact on this code's overall throughput.
-
- for(;;) {
-
- // Implementation is a simple finite-state machine.
- // Regardless of mode, check for serial input each time:
- t = millis();
- if((bytesBuffered < 256) && ((c = Serial.read()) >= 0)) {
- buffer[indexIn++] = c;
- bytesBuffered++;
- lastByteTime = lastAckTime = t; // Reset timeout counters
- } else {
- // No data received. If this persists, send an ACK packet
- // to host once every second to alert it to our presence.
- if((t - lastAckTime) > 1000) {
- Serial.print("Ada\n"); // Send ACK string to host
- lastAckTime = t; // Reset counter
- }
- // If no data received for an extended time, turn off all LEDs.
- if((t - lastByteTime) > serialTimeout) {
- for(c=0; c<32767; c++) {
- for(SPDR=0; !(SPSR & _BV(SPIF)); );
- }
- delay(1); // One millisecond pause = latch
- lastByteTime = t; // Reset counter
- }
- }
-
- switch(mode) {
-
- case MODE_HEADER:
-
- // In header-seeking mode. Is there enough data to check?
- if(bytesBuffered >= HEADERSIZE) {
- // Indeed. Check for a 'magic word' match.
- for(i=0; (i 0) and multiply by 3 for R,G,B.
- bytesRemaining = 3L * (256L * (long)hi + (long)lo + 1L);
- bytesBuffered -= 3;
- spiFlag = 0; // No data out yet
- mode = MODE_HOLD; // Proceed to latch wait mode
- } else {
- // Checksum didn't match; search resumes after magic word.
- indexOut -= 3; // Rewind
- }
- } // else no header match. Resume at first mismatched byte.
- bytesBuffered -= i;
- }
- break;
-
- case MODE_HOLD:
-
- // Ostensibly "waiting for the latch from the prior frame
- // to complete" mode, but may also revert to this mode when
- // underrun prevention necessitates a delay.
-
- if((micros() - startTime) < hold) break; // Still holding; keep buffering
-
- // Latch/delay complete. Advance to data-issuing mode...
- LED_PORT &= ~LED_PIN; // LED off
- mode = MODE_DATA; // ...and fall through (no break):
-
- case MODE_DATA:
-
- while(spiFlag && !(SPSR & _BV(SPIF))); // Wait for prior byte
- if(bytesRemaining > 0) {
- if(bytesBuffered > 0) {
- SPDR = buffer[indexOut++]; // Issue next byte
- bytesBuffered--;
- bytesRemaining--;
- spiFlag = 1;
- }
- // If serial buffer is threatening to underrun, start
- // introducing progressively longer pauses to allow more
- // data to arrive (up to a point).
- if((bytesBuffered < 32) && (bytesRemaining > bytesBuffered)) {
- startTime = micros();
- hold = 100 + (32 - bytesBuffered) * 10;
- mode = MODE_HOLD;
- }
- } else {
- // End of data -- issue latch:
- startTime = micros();
- hold = 1000; // Latch duration = 1000 uS
- LED_PORT |= LED_PIN; // LED on
- mode = MODE_HEADER; // Begin next header search
- }
- } // end switch
- } // end for(;;)
-}
-
-void loop()
-{
- // Not used. See note in setup() function.
-}
diff --git a/Arduino/LEDstream_CircuitPlayground/LEDstream_CircuitPlayground.ino b/Arduino/LEDstream_CircuitPlayground/LEDstream_CircuitPlayground.ino
deleted file mode 100644
index 6aa3a8c..0000000
--- a/Arduino/LEDstream_CircuitPlayground/LEDstream_CircuitPlayground.ino
+++ /dev/null
@@ -1,134 +0,0 @@
-// This is a pared-down version of the LEDstream sketch specifically
-// for Circuit Playground. It is NOT a generic solution to NeoPixel
-// support with Adalight! The NeoPixel library disables interrupts
-// while issuing data...but Serial transfers depend on interrupts.
-// This code works (or appears to work, it hasn't been extensively
-// battle-tested) only because of the finite number of pixels (10)
-// on the Circuit Playground board. With 10 NeoPixels, interrupts are
-// off for about 300 microseconds...but if the incoming data rate is
-// sufficiently limited (<= 60 FPS or so with the given number of
-// pixels), things seem OK, no data is missed. Balancing act!
-
-// --------------------------------------------------------------------
-// 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
-// .
-// --------------------------------------------------------------------
-
-#include "Adafruit_CircuitPlayground.h"
-
-static const uint8_t magic[] = { 'A','d','a' };
-#define MAGICSIZE sizeof(magic)
-#define HEADERSIZE (MAGICSIZE + 3)
-static uint8_t
- buffer[HEADERSIZE], // Serial input buffer
- bytesBuffered = 0; // Amount of data in buffer
-
-static const unsigned long serialTimeout = 15000; // 15 seconds
-static unsigned long lastByteTime;
-
-void setup() {
- CircuitPlayground.begin();
- CircuitPlayground.setBrightness(255); // LEDs full blast!
- CircuitPlayground.strip.clear();
- CircuitPlayground.strip.show();
-
- Serial.begin(38400);
-
- lastByteTime = millis(); // Initialize timers
-}
-
-// Function is called when no pending serial data is available.
-static boolean timeout(
- unsigned long t, // Current time, milliseconds
- int nLEDs) { // Number of LEDs
-
- // If no data received for an extended time, turn off all LEDs.
- if((t - lastByteTime) > serialTimeout) {
- CircuitPlayground.strip.clear();
- CircuitPlayground.strip.show();
- lastByteTime = t; // Reset counter
- bytesBuffered = 0; // Clear serial buffer
- return true;
- }
-
- return false; // No timeout
-}
-
-void loop() {
- uint8_t i, hi, lo, byteNum;
- int c;
- long nLEDs, pixelNum;
- unsigned long t;
-
- // HEADER-SEEKING BLOCK: locate 'magic word' at start of frame.
-
- // If any data in serial buffer, shift it down to starting position.
- for(i=0; i= 0) { // Data received?
- buffer[bytesBuffered++] = c; // Store in buffer
- lastByteTime = t; // Reset timeout counter
- } else { // No data, check for timeout...
- if(timeout(t, 10000) == true) return; // Start over
- }
- }
-
- // Have a header's worth of data. Check for 'magic word' match.
- for(i=0; i 0)
- nLEDs = 256L * (long)hi + (long)lo + 1L;
- bytesBuffered = 0; // Clear serial buffer
- byteNum = 0;
-
- // DATA-FORWARDING BLOCK: move bytes from serial input to NeoPixels.
-
- for(pixelNum = 0; pixelNum < nLEDs; ) { // While more LED data is expected...
- t = millis();
- if((c = Serial.read()) >= 0) { // Successful read?
- lastByteTime = t; // Reset timeout counters
- buffer[byteNum++] = c; // Store in data buffer
- if(byteNum == 3) { // Have a full LED's worth?
- CircuitPlayground.strip.setPixelColor(pixelNum++,
- buffer[0], buffer[1], buffer[2]);
- byteNum = 0;
- }
- } else { // No data, check for timeout...
- if(timeout(t, nLEDs) == true) return; // Start over
- }
- }
-
- CircuitPlayground.strip.show();
-}
-
diff --git a/Arduino/LEDstream_LPD8806/LEDstream_LPD8806.ino b/Arduino/LEDstream_LPD8806/LEDstream_LPD8806.ino
deleted file mode 100644
index 1c2950c..0000000
--- a/Arduino/LEDstream_LPD8806/LEDstream_LPD8806.ino
+++ /dev/null
@@ -1,250 +0,0 @@
-// Arduino bridge code between host computer and LPD8806-based digital
-// addressable RGB LEDs (e.g. Adafruit product ID #306). LED data is
-// streamed, not buffered, making this suitable for larger installations
-// (e.g. video wall, etc.) than could otherwise be contained within the
-// Arduino's limited RAM. Intended for use with USB-native boards such
-// as Teensy or Adafruit 32u4 Breakout; also works on normal serial
-// Arduinos (Uno, etc.), but speed will be limited by the serial port.
-
-// LED data and clock lines are connected to the Arduino's SPI output.
-// On traditional Arduino boards (e.g. Uno), SPI data out is digital pin
-// 11 and clock is digital pin 13. On both Teensy and the 32u4 Breakout,
-// data out is pin B2, clock is B1. On Arduino Mega, 51=data, 52=clock.
-// LEDs should be externally powered -- trying to run any more than just
-// a few off the Arduino's 5V line is generally a Bad Idea. LED ground
-// should also be connected to Arduino ground.
-
-// Elsewhere, the WS2801 version of this code was specifically designed
-// to avoid buffer underrun conditions...the WS2801 pixels automatically
-// latch when the data stream stops for 500 microseconds or more, whether
-// intentional or not. The LPD8806 pixels are fundamentally different --
-// the latch condition is indicated within the data stream, not by pausing
-// the clock -- and buffer underruns are therefore a non-issue. In theory
-// it would seem this could allow the code to be much simpler and faster
-// (there's no need to sync up with a start-of-frame header), but in
-// practice the difference was not as pronounced as expected -- such code
-// soon ran up against a USB throughput limit anyway. So, rather than
-// break compatibility in the quest for speed that will never materialize,
-// this code instead follows the same header format as the WS2801 version.
-// This allows the same host-side code (e.g. Adalight, Adavision, etc.)
-// to run with either type of LED pixels. Huzzah!
-
-// --------------------------------------------------------------------
-// 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
-// .
-// --------------------------------------------------------------------
-
-#include
-
-// A 'magic word' precedes each block of LED data; this assists the
-// microcontroller in syncing up with the host-side software and latching
-// frames at the correct time. You may see an initial glitchy frame or
-// two until the two come into alignment. Immediately following the
-// magic word are three bytes: a 16-bit count of the number of LEDs (high
-// byte first) followed by a simple checksum value (high byte XOR low byte
-// XOR 0x55). LED data follows, 3 bytes per LED, in order R, G, B, where
-// 0 = off and 255 = max brightness. LPD8806 pixels only have 7-bit
-// brightness control, so each value is divided by two; the 8-bit format
-// is used to maintain compatibility with the protocol set forth by the
-// WS2801 streaming code (those LEDs use 8-bit values).
-static const uint8_t magic[] = { 'A','d','a' };
-#define MAGICSIZE sizeof(magic)
-#define HEADERSIZE (MAGICSIZE + 3)
-static uint8_t
- buffer[HEADERSIZE], // Serial input buffer
- bytesBuffered = 0; // Amount of data in buffer
-
-// If no serial data is received for a while, the LEDs are shut off
-// automatically. This avoids the annoying "stuck pixel" look when
-// quitting LED display programs on the host computer.
-static const unsigned long serialTimeout = 15000; // 15 seconds
-static unsigned long lastByteTime, lastAckTime;
-
-void setup() {
- byte c;
- int i, p;
-
- Serial.begin(115200); // 32u4 will ignore BPS and run full speed
-
- // SPI is run at 2 MHz. LPD8806 can run much faster,
- // but unshielded wiring is susceptible to interference.
- // Feel free to experiment with other divider ratios.
- SPI.begin();
- SPI.setBitOrder(MSBFIRST);
- SPI.setDataMode(SPI_MODE0);
- SPI.setClockDivider(SPI_CLOCK_DIV8); // 2 MHz
-
- // Issue dummy byte to "prime" the SPI bus. This later simplifies
- // the task of doing useful work during SPI transfers. Rather than
- // the usual issue-and-wait-loop, code can instead wait-and-issue --
- // with other operations occurring between transfers, the wait is
- // then shortened or eliminated. The SPSR register is read-only,
- // so this flag can't be forced -- SOMETHING must be issued.
- SPDR = 0;
-
- // Issue initial latch to LEDs. This flushes any undefined data that
- // may exist on powerup, and prepares the LEDs to receive the first
- // frame of data. Actual number of LEDs isn't known yet (this arrives
- // later in frame header packets), so just latch a large number:
- latch(10000);
-
- // Issue test pattern to LEDs on startup. This helps verify that
- // wiring between the Arduino and LEDs is correct. Again not knowing
- // the actual number of LEDs, this writes data for an arbitrarily
- // large number (10K). If wiring is correct, LEDs will all light
- // red, green, blue on startup, then off. Once you're confident
- // everything is working end-to-end, it's OK to comment this out and
- // re-upload the sketch to the Arduino.
- const uint8_t testColor[] = { 0x80, 0x80, 0xff, 0x80, 0x80, 0x80 },
- testOffset[] = { 1, 2, 0, 3 };
- for(c=0; c<4; c++) { // for each test sequence color...
- for(p=0; p<10000; p++) { // for each pixel...
- for(i=0; i<3; i++) { // for each R,G,B...
- while(!(SPSR & _BV(SPIF))); // Wait for prior byte out
- SPDR = testColor[testOffset[c] + i]; // Issue next byte
- }
- }
- latch(10000);
- if(c < 3) delay(250);
- }
-
- Serial.print("Ada\n"); // Send ACK string to host
- lastByteTime = lastAckTime = millis(); // Initialize timers
-}
-
-// Program flow is simpler than the WS2801 code. No need for a state
-// machine...instead, software just alternates between two conditions:
-// a header-seeking mode (looking for the 'magic word' at the start
-// of each frame of data), and a data-forwarding mode (moving bytes
-// from serial input to SPI output). A proper data stream will
-// consist only of alternating valid headers and valid data, so the
-// loop() function is simply divided into these two parts, and repeats
-// forever.
-
-// LPD8806 pixels expect colors in G,R,B order vs. WS2801's R,G,B.
-// This is used to shuffle things around later.
-static const uint8_t byteOrder[] = { 2, 0, 1 };
-
-void loop() {
- uint8_t i, hi, lo, byteNum;
- int c;
- long nLEDs, remaining;
- unsigned long t;
-
- // HEADER-SEEKING BLOCK: locate 'magic word' at start of frame.
-
- // If any data in serial buffer, shift it down to starting position.
- for(i=0; i= 0) { // Data received?
- buffer[bytesBuffered++] = c; // Store in buffer
- lastByteTime = lastAckTime = t; // Reset timeout counters
- } else { // No data, check for timeout...
- if(timeout(t, 10000) == true) return; // Start over
- }
- }
-
- // Have a header's worth of data. Check for 'magic word' match.
- for(i=0; i 0)
- nLEDs = remaining = 256L * (long)hi + (long)lo + 1L;
- bytesBuffered = 0; // Clear serial buffer
- byteNum = 0;
-
- // DATA-FORWARDING BLOCK: move bytes from serial input to SPI output.
-
- // Unfortunately can't just forward bytes directly. The data order is
- // different on LPD8806 (G,R,B), so bytes are buffered in groups of 3
- // and issued in the revised order.
-
- while(remaining > 0) { // While more LED data is expected...
- t = millis();
- if((c = Serial.read()) >= 0) { // Successful read?
- lastByteTime = lastAckTime = t; // Reset timeout counters
- buffer[byteNum++] = c; // Store in data buffer
- if(byteNum == 3) { // Have a full LED's worth?
- while(byteNum > 0) { // Issue data in LPD8806 order...
- i = 0x80 | (buffer[byteOrder[--byteNum]] >> 1);
- while(!(SPSR & _BV(SPIF))); // Wait for prior byte out
- SPDR = i; // Issue new byte
- }
- remaining--;
- }
- } else { // No data, check for timeout...
- if(timeout(t, nLEDs) == true) return; // Start over
- }
- }
-
- // Normal end of data. Issue latch, return to header-seeking mode.
- latch(nLEDs);
-}
-
-static void latch(int n) { // Pass # of LEDs
- n = ((n + 63) / 64) * 3; // Convert to latch length (bytes)
- while(n--) { // For each latch byte...
- while(!(SPSR & _BV(SPIF))); // Wait for prior byte out
- SPDR = 0; // Issue next byte
- }
-}
-
-// Function is called when no pending serial data is available.
-static boolean timeout(
- unsigned long t, // Current time, milliseconds
- int nLEDs) { // Number of LEDs
-
- // If condition persists, send an ACK packet to host once every
- // second to alert it to our presence.
- if((t - lastAckTime) > 1000) {
- Serial.print("Ada\n"); // Send ACK string to host
- lastAckTime = t; // Reset counter
- }
-
- // If no data received for an extended time, turn off all LEDs.
- if((t - lastByteTime) > serialTimeout) {
- long bytes = nLEDs * 3L;
- latch(nLEDs); // Latch any partial/incomplete data in strand
- while(bytes--) { // Issue all new data to turn off strand
- while(!(SPSR & _BV(SPIF))); // Wait for prior byte out
- SPDR = 0x80; // Issue next byte (0x80 = LED off)
- }
- latch(nLEDs); // Latch 'all off' data
- lastByteTime = t; // Reset counter
- bytesBuffered = 0; // Clear serial buffer
- return true;
- }
-
- return false; // No timeout
-}
-
diff --git a/C/Makefile b/C/Makefile
deleted file mode 100644
index 7d40df7..0000000
--- a/C/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-EXECS = colorswirl
-
-all: $(EXECS)
-
-colorswirl: colorswirl.c
- cc -O2 colorswirl.c -lm -o colorswirl
-
-clean:
- rm -f $(EXECS) *.o
diff --git a/C/colorswirl.c b/C/colorswirl.c
deleted file mode 100644
index 8bdb668..0000000
--- a/C/colorswirl.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
-"Colorswirl" LED demo. This is the host PC-side code written in C;
-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.
-
-This is a command-line program. It expects a single parameter, which is
-the serial port device name, e.g.:
-
- ./colorswirl /dev/tty.usbserial-A60049KO
-
-*/
-
-// --------------------------------------------------------------------
-// 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
-// .
-// --------------------------------------------------------------------
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#define N_LEDS 25 // Max of 65536
-
-int main(int argc,char *argv[])
-{
- int fd, i, bytesToGo, bytesSent, totalBytesSent = 0,
- frame = 0, hue1, hue2, brightness;
- unsigned char buffer[6 + (N_LEDS * 3)], // Header + 3 bytes per LED
- lo, r, g, b;
- double sine1, sine2;
- time_t t, start, prev;
- struct termios tty;
-
- if(argc < 2) {
- (void)printf("Usage: %s device\n", argv[0]);
- return 1;
- }
-
- if((fd = open(argv[1],O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0) {
- (void)printf("Can't open device '%s'.\n", argv[1]);
- return 1;
- }
-
- // Serial port config swiped from RXTX library (rxtx.qbang.org):
- tcgetattr(fd, &tty);
- tty.c_iflag = INPCK;
- tty.c_lflag = 0;
- tty.c_oflag = 0;
- tty.c_cflag = CREAD | CS8 | CLOCAL;
- tty.c_cc[ VMIN ] = 0;
- tty.c_cc[ VTIME ] = 0;
- cfsetispeed(&tty, B115200);
- cfsetospeed(&tty, B115200);
- tcsetattr(fd, TCSANOW, &tty);
-
- bzero(buffer, sizeof(buffer)); // Clear LED buffer
-
- // Header only needs to be initialized once, not
- // inside rendering loop -- number of LEDs is constant:
- buffer[0] = 'A'; // Magic word
- buffer[1] = 'd';
- buffer[2] = 'a';
- buffer[3] = (N_LEDS - 1) >> 8; // LED count high byte
- buffer[4] = (N_LEDS - 1) & 0xff; // LED count low byte
- buffer[5] = buffer[3] ^ buffer[4] ^ 0x55; // Checksum
-
- sine1 = 0.0;
- hue1 = 0;
- prev = start = time(NULL); // For bandwidth statistics
-
- for(;;) {
- sine2 = sine1;
- hue2 = hue1;
-
- // Start at position 6, after the LED header/magic word
- for(i = 6; i < sizeof(buffer); ) {
- // 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 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;
- case 5:
- 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.
- brightness = (int)(pow(0.5+sin(sine2)*0.5,3.0)*255.0);
- buffer[i++] = (r * brightness) / 255;
- buffer[i++] = (g * brightness) / 255;
- buffer[i++] = (b * brightness) / 255;
-
- // Each pixel is offset in both hue and brightness
- hue2 += 40;
- sine2 += 0.3;
- }
-
- // Slowly rotate hue and brightness in opposite directions
- hue1 = (hue1 + 5) % 1536;
- sine1 -= .03;
-
- // Issue color data to LEDs. Each OS is fussy in different
- // ways about serial output. This arrangement of drain-and-
- // write-loop seems to be the most relable across platforms:
- tcdrain(fd);
- for(bytesSent=0, bytesToGo=sizeof(buffer); bytesToGo > 0;) {
- if((i=write(fd,&buffer[bytesSent],bytesToGo)) > 0) {
- bytesToGo -= i;
- bytesSent += i;
- }
- }
- // Keep track of byte and frame counts for statistics
- totalBytesSent += sizeof(buffer);
- frame++;
-
- // Update statistics once per second
- if((t = time(NULL)) != prev) {
- (void)printf(
- "Average frames/sec: %d, bytes/sec: %d\n",
- (int)((float)frame / (float)(t - start)),
- (int)((float)totalBytesSent / (float)(t - start)));
- prev = t;
- }
- }
-
- close(fd);
- return 0;
-}
diff --git a/Processing/Adalight/Adalight.pde b/Processing/Adalight/Adalight.pde
deleted file mode 100644
index a8e0d89..0000000
--- a/Processing/Adalight/Adalight.pde
+++ /dev/null
@@ -1,430 +0,0 @@
-// "Adalight" is a do-it-yourself facsimile of the Philips Ambilight concept
-// for desktop computers and home theater PCs. 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
-// or more strands 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 display configuration.
-// Screen capture adapted from code by Cedrik Kiefer (processing.org forum)
-
-// --------------------------------------------------------------------
-// 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
-// .
-// --------------------------------------------------------------------
-
-import java.awt.*;
-import java.awt.image.*;
-import processing.serial.*;
-
-// CONFIGURABLE PROGRAM CONSTANTS --------------------------------------------
-
-// Minimum LED brightness; some users prefer a small amount of backlighting
-// at all times, regardless of screen content. Higher values are brighter,
-// or set to 0 to disable this feature.
-
-static final short minBrightness = 120;
-
-// LED transition speed; it's sometimes distracting if LEDs instantaneously
-// track screen contents (such as during bright flashing sequences), so this
-// feature enables a gradual fade to each new LED state. Higher numbers yield
-// slower transitions (max of 255), or set to 0 to disable this feature
-// (immediate transition of all LEDs).
-
-static final short fade = 75;
-
-// Pixel size for the live preview image.
-
-static final int pixelSize = 20;
-
-// Depending on many factors, it may be faster either to capture full
-// screens and process only the pixels needed, or to capture multiple
-// smaller sub-blocks bounding each region to be processed. Try both,
-// look at the reported frame rates in the Processing output console,
-// and run with whichever works best for you.
-
-static final boolean useFullScreenCaps = true;
-
-// Serial device timeout (in milliseconds), for locating Arduino device
-// running the corresponding LEDstream code. See notes later in the code...
-// in some situations you may want to entirely comment out that block.
-
-static final int timeout = 5000; // 5 seconds
-
-// PER-DISPLAY INFORMATION ---------------------------------------------------
-
-// This array contains details for each display that the software will
-// process. If you have screen(s) attached that are not among those being
-// "Adalighted," they should not be in this list. Each triplet in this
-// array represents one display. The first number is the system screen
-// number...typically the "primary" display on most systems is identified
-// as screen #1, but since arrays are indexed from zero, use 0 to indicate
-// the first screen, 1 to indicate the second screen, and so forth. This
-// is the ONLY place system screen numbers are used...ANY subsequent
-// references to displays are an index into this list, NOT necessarily the
-// same as the system screen number. For example, if you have a three-
-// screen setup and are illuminating only the third display, use '2' for
-// the screen number here...and then, in subsequent section, '0' will be
-// used to refer to the first/only display in this list.
-// The second and third numbers of each triplet represent the width and
-// height of a grid of LED pixels attached to the perimeter of this display.
-// For example, '9,6' = 9 LEDs across, 6 LEDs down.
-
-static final int displays[][] = new int[][] {
- {0,9,6} // Screen 0, 9 LEDs across, 6 LEDs down
-//,{1,9,6} // Screen 1, also 9 LEDs across and 6 LEDs down
-};
-
-// PER-LED INFORMATION -------------------------------------------------------
-
-// This array contains the 2D coordinates corresponding to each pixel in the
-// LED strand, in the order that they're connected (i.e. the first element
-// here belongs to the first LED in the strand, second element is the second
-// LED, and so forth). Each triplet in this array consists of a display
-// number (an index into the display array above, NOT necessarily the same as
-// the system screen number) and an X and Y coordinate specified in the grid
-// units given for that display. {0,0,0} is the top-left corner of the first
-// display in the array.
-// For our example purposes, the coordinate list below forms a ring around
-// the perimeter of a single screen, with a one pixel gap at the bottom to
-// accommodate a monitor stand. Modify this to match your own setup:
-
-static final int leds[][] = new int[][] {
- {0,3,5}, {0,2,5}, {0,1,5}, {0,0,5}, // Bottom edge, left half
- {0,0,4}, {0,0,3}, {0,0,2}, {0,0,1}, // Left edge
- {0,0,0}, {0,1,0}, {0,2,0}, {0,3,0}, {0,4,0}, // Top edge
- {0,5,0}, {0,6,0}, {0,7,0}, {0,8,0}, // More top edge
- {0,8,1}, {0,8,2}, {0,8,3}, {0,8,4}, // Right edge
- {0,8,5}, {0,7,5}, {0,6,5}, {0,5,5} // Bottom edge, right half
-
-/* Hypothetical second display has the same arrangement as the first.
- But you might not want both displays completely ringed with LEDs;
- the screens might be positioned where they share an edge in common.
- ,{1,3,5}, {1,2,5}, {1,1,5}, {1,0,5}, // Bottom edge, left half
- {1,0,4}, {1,0,3}, {1,0,2}, {1,0,1}, // Left edge
- {1,0,0}, {1,1,0}, {1,2,0}, {1,3,0}, {1,4,0}, // Top edge
- {1,5,0}, {1,6,0}, {1,7,0}, {1,8,0}, // More top edge
- {1,8,1}, {1,8,2}, {1,8,3}, {1,8,4}, // Right edge
- {1,8,5}, {1,7,5}, {1,6,5}, {1,5,5} // Bottom edge, right half
-*/
-};
-
-// GLOBAL VARIABLES ---- You probably won't need to modify any of this -------
-
-byte[] serialData = new byte[6 + leds.length * 3];
-short[][] ledColor = new short[leds.length][3],
- prevColor = new short[leds.length][3];
-byte[][] gamma = new byte[256][3];
-int nDisplays = displays.length;
-Robot[] bot = new Robot[displays.length];
-Rectangle[] dispBounds = new Rectangle[displays.length],
- ledBounds; // Alloc'd only if per-LED captures
-int[][] pixelOffset = new int[leds.length][256],
- screenData; // Alloc'd only if full-screen captures
-PImage[] preview = new PImage[displays.length];
-Serial port;
-DisposeHandler dh; // For disabling LEDs on exit
-
-// INITIALIZATION ------------------------------------------------------------
-
-void setup() {
- GraphicsEnvironment ge;
- GraphicsConfiguration[] gc;
- GraphicsDevice[] gd;
- int d, i, totalWidth, maxHeight, row, col, rowOffset;
- int[] x = new int[16], y = new int[16];
- float f, range, step, start;
-
- dh = new DisposeHandler(this); // Init DisposeHandler ASAP
-
- // Open serial port. As written here, this assumes the Arduino is the
- // first/only serial device on the system. If that's not the case,
- // change "Serial.list()[0]" to the name of the port to be used:
- port = new Serial(this, Serial.list()[0], 115200);
- // Alternately, in certain situations the following line can be used
- // to detect the Arduino automatically. But this works ONLY with SOME
- // Arduino boards and versions of Processing! This is so convoluted
- // to explain, it's easier just to test it yourself and see whether
- // it works...if not, leave it commented out and use the prior port-
- // opening technique.
- // port = openPort();
- // And finally, to test the software alone without an Arduino connected,
- // don't open a port...just comment out the serial lines above.
-
- // Initialize screen capture code for each display's dimensions.
- dispBounds = new Rectangle[displays.length];
- if(useFullScreenCaps == true) {
- screenData = new int[displays.length][];
- // ledBounds[] not used
- } else {
- ledBounds = new Rectangle[leds.length];
- // screenData[][] not used
- }
- ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
- gd = ge.getScreenDevices();
- if(nDisplays > gd.length) nDisplays = gd.length;
- totalWidth = maxHeight = 0;
- for(d=0; d 0) totalWidth++;
- if(displays[d][2] > maxHeight) maxHeight = displays[d][2];
- }
-
- // Precompute locations of every pixel to read when downsampling.
- // Saves a bunch of math on each frame, at the expense of a chunk
- // of RAM. Number of samples is now fixed at 256; this allows for
- // some crazy optimizations in the downsampling code.
- for(i=0; i> 8); // LED count high byte
- serialData[4] = (byte)((leds.length - 1) & 0xff); // LED count low byte
- serialData[5] = (byte)(serialData[3] ^ serialData[4] ^ 0x55); // Checksum
-
- // Pre-compute gamma correction table for LED brightness levels:
- for(i=0; i<256; i++) {
- f = pow((float)i / 255.0, 2.8);
- gamma[i][0] = (byte)(f * 255.0);
- gamma[i][1] = (byte)(f * 240.0);
- gamma[i][2] = (byte)(f * 220.0);
- }
-}
-
-// Open and return serial connection to Arduino running LEDstream code. This
-// attempts to open and read from each serial device on the system, until the
-// matching "Ada\n" acknowledgement string is found. Due to the serial
-// timeout, if you have multiple serial devices/ports and the Arduino is late
-// in the list, this can take seemingly forever...so if you KNOW the Arduino
-// will always be on a specific port (e.g. "COM6"), you might want to comment
-// out most of this to bypass the checks and instead just open that port
-// directly! (Modify last line in this method with the serial port name.)
-
-Serial openPort() {
- String[] ports;
- String ack;
- int i, start;
- Serial s;
-
- ports = Serial.list(); // List of all serial ports/devices on system.
-
- for(i=0; i= 4) &&
- ((ack = s.readString()) != null) &&
- ack.contains("Ada\n")) {
- return s; // Got it!
- }
- }
- // Connection timed out. Close port and move on to the next.
- s.stop();
- }
-
- // Didn't locate a device returning the acknowledgment string.
- // Maybe it's out there but running the old LEDstream code, which
- // didn't have the ACK. Can't say for sure, so we'll take our
- // changes with the first/only serial device out there...
- return new Serial(this, ports[0], 115200);
-}
-
-
-// PER_FRAME PROCESSING ------------------------------------------------------
-
-void draw () {
- BufferedImage img;
- int d, i, j, o, c, weight, rb, g, sum, deficit, s2;
- int[] pxls, offs;
-
- if(useFullScreenCaps == true ) {
- // Capture each screen in the displays array.
- for(d=0; d> 24) & 0xff) * weight +
- prevColor[i][0] * fade) >> 8);
- ledColor[i][1] = (short)(((( g >> 16) & 0xff) * weight +
- prevColor[i][1] * fade) >> 8);
- ledColor[i][2] = (short)((((rb >> 8) & 0xff) * weight +
- prevColor[i][2] * fade) >> 8);
-
- // Boost pixels that fall below the minimum brightness
- sum = ledColor[i][0] + ledColor[i][1] + ledColor[i][2];
- if(sum < minBrightness) {
- if(sum == 0) { // To avoid divide-by-zero
- deficit = minBrightness / 3; // Spread equally to R,G,B
- ledColor[i][0] += deficit;
- ledColor[i][1] += deficit;
- ledColor[i][2] += deficit;
- } else {
- deficit = minBrightness - sum;
- s2 = sum * 2;
- // Spread the "brightness deficit" back into R,G,B in proportion to
- // their individual contribition to that deficit. Rather than simply
- // boosting all pixels at the low end, this allows deep (but saturated)
- // colors to stay saturated...they don't "pink out."
- ledColor[i][0] += deficit * (sum - ledColor[i][0]) / s2;
- ledColor[i][1] += deficit * (sum - ledColor[i][1]) / s2;
- ledColor[i][2] += deficit * (sum - ledColor[i][2]) / s2;
- }
- }
-
- // Apply gamma curve and place in serial output buffer
- serialData[j++] = gamma[ledColor[i][0]][0];
- serialData[j++] = gamma[ledColor[i][1]][1];
- serialData[j++] = gamma[ledColor[i][2]][2];
- // Update pixels in preview image
- preview[d].pixels[leds[i][2] * displays[d][1] + leds[i][1]] =
- (ledColor[i][0] << 16) | (ledColor[i][1] << 8) | ledColor[i][2];
- }
-
- if(port != null) port.write(serialData); // Issue data to Arduino
-
- // Show live preview image(s)
- scale(pixelSize);
- for(i=d=0; d.
-// --------------------------------------------------------------------
-
-import java.awt.*;
-import java.awt.image.*;
-import processing.serial.*;
-
-// CONFIGURABLE PROGRAM CONSTANTS --------------------------------------------
-
-// This selects from the list of serial devices connected to the system.
-// Use print(Serial.list()); to get a list of ports. Then, counting from 0,
-// set this value to the index corresponding to the Circuit Playground port:
-
-static final byte serialPortIndex = 2;
-
-// For multi-screen systems, set this to the index (counting from 0) of the
-// display which will have ambient lighting:
-
-static final byte screenNumber = 0;
-
-// Minimum LED brightness; some users prefer a small amount of backlighting
-// at all times, regardless of screen content. Higher values are brighter,
-// or set to 0 to disable this feature.
-
-static final short minBrightness = 100;
-
-// LED transition speed; it's sometimes distracting if LEDs instantaneously
-// track screen contents (such as during bright flashing sequences), so this
-// feature enables a gradual fade to each new LED state. Higher numbers yield
-// slower transitions (max of 255), or set to 0 to disable this feature
-// (immediate transition of all LEDs).
-
-static final short fade = 60;
-
-// Depending on many factors, it may be faster either to capture full
-// screens and process only the pixels needed, or to capture multiple
-// smaller sub-blocks bounding each region to be processed. Try both,
-// look at the reported frame rates in the Processing output console,
-// and run with whichever works best for you.
-
-static final boolean useFullScreenCaps = true;
-
-// PER-LED INFORMATION -------------------------------------------------------
-
-// The Circuit Playground version of Adalight operates on a fixed 5x5 grid
-// encompassing the full display. 10 elements from this grid correspond to
-// the 10 NeoPixels on the Circuit Playground board. The following array
-// contains the 2D coordinates of each NeoPixel within that 5x5 grid (0,0 is
-// top left); board assumed facing away from display, with USB at bottom:
-// .4.5.
-// 3...6
-// 2...7
-// 1...8
-// .0.9.
-
-static final int leds[][] = new int[][] {
- {1,4}, {0,3}, {0,2}, {0,1}, {1,0},
- {3,0}, {4,1}, {4,2}, {4,3}, {3,4}
-};
-
-// GLOBAL VARIABLES ---- You probably won't need to modify any of this -------
-
-byte serialData[] = new byte[6 + leds.length * 3],
- gamma[][] = new byte[256][3];
-short[][] ledColor = new short[leds.length][3],
- prevColor = new short[leds.length][3];
-Robot bot;
-Rectangle dispBounds, ledBounds[];
-int pixelOffset[][] = new int[leds.length][256],
- screenData[];
-PImage preview;
-Serial port;
-
-// INITIALIZATION ------------------------------------------------------------
-
-void setup() {
- GraphicsEnvironment ge;
- GraphicsConfiguration[] gc;
- GraphicsDevice[] gd;
- int i, row, col;
- int[] x = new int[16], y = new int[16];
- float f, range, step, start;
-
- this.registerMethod("dispose", this);
- print(Serial.list()); // Show list of serial devices/ports
- // Open serial port. Change serialPortIndex in the globals to
- // select a different port:
- port = new Serial(this, Serial.list()[serialPortIndex], 38400);
-
- // Initialize screen capture code for the display's dimensions.
- if(useFullScreenCaps == false) ledBounds = new Rectangle[leds.length];
- ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
- gd = ge.getScreenDevices();
-
- try {
- bot = new Robot(gd[screenNumber]);
- }
- catch(AWTException e) {
- System.out.println("new Robot() failed");
- exit();
- }
- gc = gd[screenNumber].getConfigurations();
- dispBounds = gc[0].getBounds();
- dispBounds.x = dispBounds.y = 0;
- preview = createImage(5, 5, RGB);
- preview.loadPixels();
-
- // Precompute locations of every pixel to read when downsampling.
- // Saves a bunch of math on each frame, at the expense of a chunk
- // of RAM. Number of samples is now fixed at 256; this allows for
- // some crazy optimizations in the downsampling code.
- for(i=0; i> 8); // LED count high byte
- serialData[4] = (byte)((leds.length - 1) & 0xff); // LED count low byte
- serialData[5] = (byte)(serialData[3] ^ serialData[4] ^ 0x55); // Checksum
-
- // Pre-compute gamma correction table for LED brightness levels:
- for(i=0; i<256; i++) {
- f = pow((float)i / 255.0, 2.8);
- gamma[i][0] = (byte)(f * 255.0 + 0.5);
- gamma[i][1] = (byte)(f * 240.0 + 0.5);
- gamma[i][2] = (byte)(f * 220.0 + 0.5);
- }
-}
-
-// PER_FRAME PROCESSING ------------------------------------------------------
-
-void draw () {
- BufferedImage img;
- int i, j, o, c, weight, rb, g, sum, deficit, s2;
- int[] pxls, offs;
-
- if(useFullScreenCaps == true ) {
- img = bot.createScreenCapture(dispBounds);
- // Get location of source pixel data
- screenData =
- ((DataBufferInt)img.getRaster().getDataBuffer()).getData();
- }
-
- weight = 257 - fade; // 'Weighting factor' for new frame vs. old
- j = 6; // Serial led data follows header / magic word
-
- // This computes a single pixel value filtered down from a rectangular
- // section of the screen. While it would seem tempting to use the native
- // image scaling in Processing/Java, in practice this didn't look very
- // good -- either too pixelated or too blurry, no happy medium. So
- // instead, a "manual" downsampling is done here. In the interest of
- // speed, it doesn't actually sample every pixel within a block, just
- // a selection of 256 pixels spaced within the block...the results still
- // look reasonably smooth and are handled quickly enough for video.
-
- for(i=0; i> 24) & 0xff) * weight +
- prevColor[i][0] * fade) >> 8);
- ledColor[i][1] = (short)(((( g >> 16) & 0xff) * weight +
- prevColor[i][1] * fade) >> 8);
- ledColor[i][2] = (short)((((rb >> 8) & 0xff) * weight +
- prevColor[i][2] * fade) >> 8);
- // Boost pixels that fall below the minimum brightness
- sum = ledColor[i][0] + ledColor[i][1] + ledColor[i][2];
- if(sum < minBrightness) {
- if(sum == 0) { // To avoid divide-by-zero
- deficit = minBrightness / 3; // Spread equally to R,G,B
- ledColor[i][0] += deficit;
- ledColor[i][1] += deficit;
- ledColor[i][2] += deficit;
- } else {
- deficit = minBrightness - sum;
- s2 = sum * 2;
- // Spread the "brightness deficit" back into R,G,B in proportion to
- // their individual contribition to that deficit. Rather than simply
- // boosting all pixels at the low end, this allows deep (but saturated)
- // colors to stay saturated...they don't "pink out."
- ledColor[i][0] += deficit * (sum - ledColor[i][0]) / s2;
- ledColor[i][1] += deficit * (sum - ledColor[i][1]) / s2;
- ledColor[i][2] += deficit * (sum - ledColor[i][2]) / s2;
- }
- }
-
- // Apply gamma curve and place in serial output buffer
- serialData[j++] = gamma[ledColor[i][0]][0];
- serialData[j++] = gamma[ledColor[i][1]][1];
- serialData[j++] = gamma[ledColor[i][2]][2];
- // Update pixels in preview image
- preview.pixels[leds[i][1] * 5 + leds[i][0]] = 0xFF000000 |
- (ledColor[i][0] << 16) | (ledColor[i][1] << 8) | ledColor[i][2];
- }
-
- if(port != null) port.write(serialData); // Issue data to Arduino
-
- // Show live preview image
- preview.updatePixels();
- scale(40);
- image(preview, 0, 0);
-
- println(frameRate); // How are we doing?
-
- // Copy LED color data to prior frame array for next pass
- arraycopy(ledColor, 0, prevColor, 0, ledColor.length);
-}
-
-// CLEANUP -------------------------------------------------------------------
-
-// The DisposeHandler is called on program exit (but before the Serial library
-// is shutdown), in order to turn off the LEDs (reportedly more reliable than
-// stop()). Seems to work for the window close box and escape key exit, but
-// not the 'Quit' menu option. Thanks to phi.lho in the Processing forums.
-
-void dispose() {
- // Fill serialData (after header) with 0's, and issue to Arduino...
- java.util.Arrays.fill(serialData, 6, serialData.length, (byte)0);
- if(port != null) port.write(serialData);
-}
\ No newline at end of file
diff --git a/Processing/Colorswirl/Colorswirl.pde b/Processing/Colorswirl/Colorswirl.pde
deleted file mode 100644
index 752ee60..0000000
--- a/Processing/Colorswirl/Colorswirl.pde
+++ /dev/null
@@ -1,141 +0,0 @@
-// "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.
-
-// --------------------------------------------------------------------
-// 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
-// .
-// --------------------------------------------------------------------
-
-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()
-{
-}
-