From 3bc2b4735170140bcd2acc200d39510e3ea114b3 Mon Sep 17 00:00:00 2001 From: David Madison Date: Tue, 20 Dec 2016 03:29:40 -0500 Subject: [PATCH 01/10] Rename from .pde to .ino Complies with modern Arduino IDE (post v1.0) --- Arduino/LEDstream/{LEDstream.pde => LEDstream.ino} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Arduino/LEDstream/{LEDstream.pde => LEDstream.ino} (100%) diff --git a/Arduino/LEDstream/LEDstream.pde b/Arduino/LEDstream/LEDstream.ino similarity index 100% rename from Arduino/LEDstream/LEDstream.pde rename to Arduino/LEDstream/LEDstream.ino From 33e98325dd30f8489163414de1c150a719fe5817 Mon Sep 17 00:00:00 2001 From: David Madison Date: Tue, 20 Dec 2016 03:30:38 -0500 Subject: [PATCH 02/10] Rename from .pde to .ino Complies with modern Arduino IDE (post v1.0) --- .../{LEDstream_LPD8806.pde => LEDstream_LPD8806.ino} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Arduino/LEDstream_LPD8806/{LEDstream_LPD8806.pde => LEDstream_LPD8806.ino} (100%) diff --git a/Arduino/LEDstream_LPD8806/LEDstream_LPD8806.pde b/Arduino/LEDstream_LPD8806/LEDstream_LPD8806.ino similarity index 100% rename from Arduino/LEDstream_LPD8806/LEDstream_LPD8806.pde rename to Arduino/LEDstream_LPD8806/LEDstream_LPD8806.ino From ab14c0a99609010237a50e7d04553f8a7895605a Mon Sep 17 00:00:00 2001 From: David Madison Date: Tue, 20 Dec 2016 03:56:50 -0500 Subject: [PATCH 03/10] Updated README to Github .md --- README.txt => README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename README.txt => README.md (98%) diff --git a/README.txt b/README.md similarity index 98% rename from README.txt rename to README.md index 31d45a9..95d9eb0 100644 --- a/README.txt +++ b/README.md @@ -9,4 +9,4 @@ 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 . +License along with Adalight. If not, see . \ No newline at end of file From 11b73f2e6d2c2a711d5a0a4a571c043b82b03e20 Mon Sep 17 00:00:00 2001 From: David Madison Date: Tue, 20 Dec 2016 03:58:53 -0500 Subject: [PATCH 04/10] Updated README --- README.md | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 95d9eb0..915ee70 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,31 @@ +## Synopsis + +This is the standard Adalight library, modified to work with 3-pin WS2812B LED strips (2016-era Adafruit NeoPixels). The Arduino code has been modified to use the FastLED library. + +In addition to ambilight setups, the protocol can be used to stream any color data from a computer to a WS2812B strip (data rate limited by serial throughput). + + +## Configuration + +Open the WS2812B file in the Arduino IDE and edit the definitions at the top for your setup. Specifically: + +- Number of LEDs +- LED data pin +- LED grounding pin (optional) +- Brightness +- Serial speed + +Upload to your Arduino and use a corresponding PC application to stream color data. The Processing files are included, though I would recommend using Patrick Siegler's (@psieg) fork of Lightpacks's Prismatik, which you can find [here](https://github.com/psieg/Lightpack). + +## Tutorial + +If you'd like you can follow Adafruit's tutorial, which is fairly comprehensive for the WS2801 they use but is otherwise out of date. You can find the tutorial here: + + + + +## License + 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 @@ -9,4 +37,4 @@ 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 . \ No newline at end of file +License along with Adalight. If not, see . From b541a2085a6a9303562d5f0ed302485463f3d74b Mon Sep 17 00:00:00 2001 From: David Madison Date: Tue, 20 Dec 2016 04:30:27 -0500 Subject: [PATCH 05/10] Added WS2812B Arduino code The initial modifications to the Adalight code to incorporate the FastLED library and work with WS2812B LEDs were done by James Bruce (@jamesabruce). I can't find a way to do a pull request on a Gist, so I'm copying his code in full here. Original Gist: https://gist.github.com/jamesabruce/09d79a56d270ed37870c --- .../LEDstream_WS2812B/LEDstream_WS2812B.ino | 166 ++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 Arduino/LEDstream_WS2812B/LEDstream_WS2812B.ino diff --git a/Arduino/LEDstream_WS2812B/LEDstream_WS2812B.ino b/Arduino/LEDstream_WS2812B/LEDstream_WS2812B.ino new file mode 100644 index 0000000..30e0d18 --- /dev/null +++ b/Arduino/LEDstream_WS2812B/LEDstream_WS2812B.ino @@ -0,0 +1,166 @@ +// Slightly modified Adalight protocol implementation that uses FastLED +// library (http://fastled.io) for driving WS2811/WS2812 led stripe +// Was tested only with Prismatik software from Lightpack project + +#include "FastLED.h" + +#define NUM_LEDS 114 // Max LED count +#define LED_PIN 6 // arduino output pin +#define GROUND_PIN 10 +#define BRIGHTNESS 255 // maximum brightness +#define SPEED 115200 // virtual serial port speed, must be the same in boblight_config + +CRGB leds[NUM_LEDS]; +uint8_t * ledsRaw = (uint8_t *)leds; + +// 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_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 = 150000; // 150 seconds + +void setup() +{ + pinMode(GROUND_PIN, OUTPUT); + digitalWrite(GROUND_PIN, LOW); + FastLED.addLeds(leds, NUM_LEDS); + + // 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; + int32_t outPos = 0; + + Serial.begin(SPEED); // Teensy/32u4 disregards baud rate; is OK! + + 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) { + memset(leds, 0, NUM_LEDS * sizeof(struct CRGB)); //filling Led array by zeroes + FastLED.show(); + 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; + outPos = 0; + memset(leds, 0, NUM_LEDS * sizeof(struct CRGB)); + mode = MODE_DATA; // 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_DATA: + + if(bytesRemaining > 0) { + if(bytesBuffered > 0) { + if (outPos < sizeof(leds)) + ledsRaw[outPos++] = buffer[indexOut++]; // Issue next byte + bytesBuffered--; + bytesRemaining--; + } + // If serial buffer is threatening to underrun, start + // introducing progressively longer pauses to allow more + // data to arrive (up to a point). + } + else { + // End of data -- issue latch: + startTime = micros(); + mode = MODE_HEADER; // Begin next header search + FastLED.show(); + } + } // end switch + } // end for(;;) +} + +void loop() +{ + // Not used. See note in setup() function. +} From 915ac148827d28acb9d9282293fadb054c0953ae Mon Sep 17 00:00:00 2001 From: David Madison Date: Tue, 20 Dec 2016 04:38:52 -0500 Subject: [PATCH 06/10] Updated definition comments and whitespace --- Arduino/LEDstream_WS2812B/LEDstream_WS2812B.ino | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Arduino/LEDstream_WS2812B/LEDstream_WS2812B.ino b/Arduino/LEDstream_WS2812B/LEDstream_WS2812B.ino index 30e0d18..0201779 100644 --- a/Arduino/LEDstream_WS2812B/LEDstream_WS2812B.ino +++ b/Arduino/LEDstream_WS2812B/LEDstream_WS2812B.ino @@ -1,14 +1,14 @@ // Slightly modified Adalight protocol implementation that uses FastLED -// library (http://fastled.io) for driving WS2811/WS2812 led stripe +// library (http://fastled.io) for driving WS2811/WS2812 led strip // Was tested only with Prismatik software from Lightpack project #include "FastLED.h" -#define NUM_LEDS 114 // Max LED count -#define LED_PIN 6 // arduino output pin -#define GROUND_PIN 10 -#define BRIGHTNESS 255 // maximum brightness -#define SPEED 115200 // virtual serial port speed, must be the same in boblight_config +#define NUM_LEDS 80 // strip length +#define LED_PIN 6 // Arduino data output pin +#define GROUND_PIN 10 // additional grounding pin (optional) +#define BRIGHTNESS 255 // maximum brightness +#define SPEED 115200 // serial port speed, max available CRGB leds[NUM_LEDS]; uint8_t * ledsRaw = (uint8_t *)leds; From 4fc9d02d9cc4c37662f96f2d38d679c3e740edcc Mon Sep 17 00:00:00 2001 From: David Madison Date: Tue, 20 Dec 2016 04:46:43 -0500 Subject: [PATCH 07/10] Removed Prismatik only comment --- Arduino/LEDstream_WS2812B/LEDstream_WS2812B.ino | 1 - 1 file changed, 1 deletion(-) diff --git a/Arduino/LEDstream_WS2812B/LEDstream_WS2812B.ino b/Arduino/LEDstream_WS2812B/LEDstream_WS2812B.ino index 0201779..55ddf55 100644 --- a/Arduino/LEDstream_WS2812B/LEDstream_WS2812B.ino +++ b/Arduino/LEDstream_WS2812B/LEDstream_WS2812B.ino @@ -1,6 +1,5 @@ // Slightly modified Adalight protocol implementation that uses FastLED // library (http://fastled.io) for driving WS2811/WS2812 led strip -// Was tested only with Prismatik software from Lightpack project #include "FastLED.h" From 025fecb99be5b2f77e0d929d5d07d849f02d85a9 Mon Sep 17 00:00:00 2001 From: David Madison Date: Tue, 20 Dec 2016 04:47:22 -0500 Subject: [PATCH 08/10] Moved serial timeout variable below definitions --- Arduino/LEDstream_WS2812B/LEDstream_WS2812B.ino | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Arduino/LEDstream_WS2812B/LEDstream_WS2812B.ino b/Arduino/LEDstream_WS2812B/LEDstream_WS2812B.ino index 55ddf55..f34fbe1 100644 --- a/Arduino/LEDstream_WS2812B/LEDstream_WS2812B.ino +++ b/Arduino/LEDstream_WS2812B/LEDstream_WS2812B.ino @@ -9,6 +9,10 @@ #define BRIGHTNESS 255 // maximum brightness #define SPEED 115200 // serial port speed, max available +// If no serial data is received for a while, the LEDs are shut off +// automatically. Value in milliseconds. +static const unsigned long serialTimeout = 150000; // 150 seconds + CRGB leds[NUM_LEDS]; uint8_t * ledsRaw = (uint8_t *)leds; @@ -34,11 +38,6 @@ static const uint8_t magic[] = { #define MODE_HEADER 0 #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 = 150000; // 150 seconds - void setup() { pinMode(GROUND_PIN, OUTPUT); From 9c8d8ebfa7779eb9ee72bcfca3feb1fbdbdaf0d7 Mon Sep 17 00:00:00 2001 From: David Madison Date: Tue, 20 Dec 2016 04:50:14 -0500 Subject: [PATCH 09/10] Added serial timeout line --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 915ee70..5ff28e1 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ Open the WS2812B file in the Arduino IDE and edit the definitions at the top for - LED grounding pin (optional) - Brightness - Serial speed +- Serial timeout length Upload to your Arduino and use a corresponding PC application to stream color data. The Processing files are included, though I would recommend using Patrick Siegler's (@psieg) fork of Lightpacks's Prismatik, which you can find [here](https://github.com/psieg/Lightpack). From 523daa7ea0ca2d93c15cab8f281ca802dd0db038 Mon Sep 17 00:00:00 2001 From: David Madison Date: Tue, 20 Dec 2016 05:07:16 -0500 Subject: [PATCH 10/10] Reworked line about FastLED --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5ff28e1..fcee265 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ## Synopsis -This is the standard Adalight library, modified to work with 3-pin WS2812B LED strips (2016-era Adafruit NeoPixels). The Arduino code has been modified to use the FastLED library. +This is the standard Adalight library, modified to work with the FastLED library (fastled.io) and 3-pin WS2812B LED strips (2016-era Adafruit NeoPixels). In addition to ambilight setups, the protocol can be used to stream any color data from a computer to a WS2812B strip (data rate limited by serial throughput).