From 7551a06cf4b800b51b284bbf42afbbc92d9015fd Mon Sep 17 00:00:00 2001 From: tociek Date: Thu, 12 Nov 2015 00:22:11 +0100 Subject: [PATCH 01/10] Corrected APA102 USB (adalight) led device I have removed the 'hack' that allowed to use APA102 with original version of adalight. I have modified adalight code and placed it into dependencies folder. This change is not backward compatible, so it won't work with original adalight code. The reason for the change is that last leds were not acting as they should (last led red). Additionally with this change and new arduino code, performance is lot better and lights change much smoother. I have also changed switchOff method that requires different data sent to apa102 to turn all leds off. Enjoy :) Jacek Former-commit-id: 624fe6c429aee896b150d23289f0be19e040474d --- dependencies/LightberryHDUSBAPA1021.1.zip | Bin 0 -> 4443 bytes libsrc/leddevice/LedDeviceAdalightApa102.cpp | 35 ++++++++++++++----- libsrc/leddevice/LedDeviceAdalightApa102.h | 8 +++-- 3 files changed, 32 insertions(+), 11 deletions(-) create mode 100644 dependencies/LightberryHDUSBAPA1021.1.zip diff --git a/dependencies/LightberryHDUSBAPA1021.1.zip b/dependencies/LightberryHDUSBAPA1021.1.zip new file mode 100644 index 0000000000000000000000000000000000000000..13c743a080b77d837e04beb6a62e7e210ae984bc GIT binary patch literal 4443 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 PdnNi~9{quczdrXr;VLB$ literal 0 HcmV?d00001 diff --git a/libsrc/leddevice/LedDeviceAdalightApa102.cpp b/libsrc/leddevice/LedDeviceAdalightApa102.cpp index 07732080..5f5cc42e 100644 --- a/libsrc/leddevice/LedDeviceAdalightApa102.cpp +++ b/libsrc/leddevice/LedDeviceAdalightApa102.cpp @@ -3,7 +3,6 @@ #include #include #include -#include // Linux includes #include @@ -18,24 +17,23 @@ LedDeviceAdalightApa102::LedDeviceAdalightApa102(const std::string& outputDevice _timer() { } -//comparing to ws2801 adalight, the following changes were needed: -// 1- differnt data frame (4 bytes instead of 3) -// 2 - in order to accomodate point 1 above, number of leds sent to adalight is increased by 1/3rd +// see dependencies folder for arduino sketch for APA102 int LedDeviceAdalightApa102::write(const std::vector & ledValues) { + ledCount = ledValues.size(); const unsigned int startFrameSize = 4; const unsigned int endFrameSize = std::max(((ledValues.size() + 15) / 16), 4); const unsigned int mLedCount = (ledValues.size() * 4) + startFrameSize + endFrameSize; - if(_ledBuffer.size() != mLedCount){ - _ledBuffer.resize(mLedCount, 0xFF); + if(_ledBuffer.size() != mLedCount+6){ + _ledBuffer.resize(mLedCount+6, 0x00); _ledBuffer[0] = 'A'; _ledBuffer[1] = 'd'; _ledBuffer[2] = 'a'; - _ledBuffer[3] = (((unsigned int)(ledValues.size() * 1.33) - 1) >> 8) & 0xFF; // LED count high byte - _ledBuffer[4] = ((unsigned int)(ledValues.size() * 1.33) - 1) & 0xFF; // LED count low byte + _ledBuffer[3] = (((unsigned int)(ledValues.size())) >> 8) & 0xFF; // LED count high byte + _ledBuffer[4] = ((unsigned int)(ledValues.size())) & 0xFF; // LED count low byte _ledBuffer[5] = _ledBuffer[3] ^ _ledBuffer[4] ^ 0x55; // Checksum } - + for (unsigned iLed=1; iLed<=ledValues.size(); iLed++) { const ColorRgb& rgb = ledValues[iLed-1]; _ledBuffer[iLed*4+6] = 0xFF; @@ -51,4 +49,23 @@ int LedDeviceAdalightApa102::write(const std::vector & ledValues) return writeBytes(_ledBuffer.size(), _ledBuffer.data()); } +int LedDeviceAdalightApa102::switchOff() +{ + for (unsigned iLed=1; iLed<=ledCount; iLed++) { + _ledBuffer[iLed*4+6] = 0xFF; + _ledBuffer[iLed*4+1+6] = 0x00; + _ledBuffer[iLed*4+2+6] = 0x00; + _ledBuffer[iLed*4+3+6] = 0x00; + } + // restart the timer + _timer.start(); + + // write data + return writeBytes(_ledBuffer.size(), _ledBuffer.data()); +} + +void LedDeviceAdalightApa102::rewriteLeds() +{ + writeBytes(_ledBuffer.size(), _ledBuffer.data()); +} diff --git a/libsrc/leddevice/LedDeviceAdalightApa102.h b/libsrc/leddevice/LedDeviceAdalightApa102.h index a0a7c89c..0c4b502a 100644 --- a/libsrc/leddevice/LedDeviceAdalightApa102.h +++ b/libsrc/leddevice/LedDeviceAdalightApa102.h @@ -32,13 +32,17 @@ public: /// @return Zero on succes else negative /// virtual int write(const std::vector & ledValues); + virtual int switchOff(); - +private slots: + /// Write the last data to the leds again + void rewriteLeds(); + private: /// The buffer containing the packed RGB values std::vector _ledBuffer; - + unsigned int ledCount; /// Timer object which makes sure that led data is written at a minimum rate /// The Adalight device will switch off when it does not receive data at least /// every 15 seconds From fa0b8db1314dd8edd5513d88cee9b5f4b928b5ec Mon Sep 17 00:00:00 2001 From: tociek Date: Mon, 23 Nov 2015 21:47:04 +0100 Subject: [PATCH 02/10] Fix to the adalightapa102 firmware Fix to the firmware when converter would require reconnect after 15 seconds of hyperion inactivity Former-commit-id: 1952eaad1ddbea3ce23252bb1d9c96ba29d72184 --- dependencies/LightberryHDUSBAPA1021.1.zip | Bin 4443 -> 4555 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/dependencies/LightberryHDUSBAPA1021.1.zip b/dependencies/LightberryHDUSBAPA1021.1.zip index 13c743a080b77d837e04beb6a62e7e210ae984bc..45d92c04034381b43ff720b959060fccd2bb4217 100644 GIT binary patch delta 4348 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 Date: Thu, 26 Nov 2015 18:04:43 +0100 Subject: [PATCH 03/10] added the LightberryHDUSBAPA102.1.ino as a source file Former-commit-id: 4923f654cefc5a08df5424e6a2553111e6914b10 --- .../LightberryHDUSBAPA1021.1.ino | 271 ++++++++++++++++++ 1 file changed, 271 insertions(+) create mode 100644 dependencies/LightberryHDUSBAPA1021.1/LightberryHDUSBAPA1021.1.ino diff --git a/dependencies/LightberryHDUSBAPA1021.1/LightberryHDUSBAPA1021.1.ino b/dependencies/LightberryHDUSBAPA1021.1/LightberryHDUSBAPA1021.1.ino new file mode 100644 index 00000000..e4eca0a4 --- /dev/null +++ b/dependencies/LightberryHDUSBAPA1021.1/LightberryHDUSBAPA1021.1.ino @@ -0,0 +1,271 @@ +// 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 + +#define DATA_LED A5 +#define SPI_LED A3 + +// 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; + bool + data_in_led = false, + spi_out_led = false; + + LED_DDR |= LED_PIN; // Enable output for LED + LED_PORT &= ~LED_PIN; // LED off + pinMode(DATA_LED, OUTPUT); //data in led + pinMode(SPI_LED, OUTPUT); //data out led + + 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(int i=0; i<5; i++){ + for(SPDR = 0x00; !(SPSR & _BV(SPIF)); ); + } + 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)); ); + } + for(i=0; i<1; i++) { + for(SPDR = 0xFF; !(SPSR & _BV(SPIF)); ); + } + } + for(int i=0; i<16; i++){ + for(SPDR = 0x00; !(SPSR & _BV(SPIF)); ); + } + delay(1); // One millisecond pause = latch + digitalWrite(SPI_LED, spi_out_led = !spi_out_led); + } + + 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(;;) { + digitalWrite(DATA_LED, LOW); + digitalWrite(SPI_LED, LOW); + // 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<25000; c++) { + for(i=0; i<3; i++) { + for(SPDR = 0x00; !(SPSR & _BV(SPIF)); ); + } + for(i=0; i<1; i++) { + for(SPDR = 0xFF; !(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 = 4L * (256L * (long)hi + (long)lo) +4L + (256L *(long)hi + (long)lo +15)/16; + bytesBuffered -= 3; + spiFlag = 0; // No data out yet + mode = MODE_HOLD; // Proceed to latch wait mode + digitalWrite(DATA_LED, data_in_led = !data_in_led); + } 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: + digitalWrite(SPI_LED, spi_out_led = !spi_out_led); + 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. +} From cf359e51821ecba664b7cf43e66b2b10288c9955 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sch=C3=B6ck=2C=20Florian?= Date: Thu, 26 Nov 2015 18:21:20 +0100 Subject: [PATCH 04/10] corrected the source to exactly match the protocol of the APA 102 LED's Former-commit-id: 10d097ff4bbcfa3c717c72138ea0cb1d9e629565 --- dependencies/LightberryHDUSBAPA1021.1.zip | Bin 4555 -> 4567 bytes .../LightberryHDUSBAPA1021.1.ino | 30 ++++++++++-------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/dependencies/LightberryHDUSBAPA1021.1.zip b/dependencies/LightberryHDUSBAPA1021.1.zip index 45d92c04034381b43ff720b959060fccd2bb4217..7a9e6cb1202ba4dc6c24628541a91c3284ab6cb6 100644 GIT binary patch delta 4368 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 n--) { for(c=0; c<25000; c++) { + for(SPDR = 0xFF; !(SPSR & _BV(SPIF)); ); //Brightness byte for(i=0; i<3; i++) { - for(SPDR = testcolor[n + i]; !(SPSR & _BV(SPIF)); ); - } - for(i=0; i<1; i++) { - for(SPDR = 0xFF; !(SPSR & _BV(SPIF)); ); + for(SPDR = testcolor[n + i]; !(SPSR & _BV(SPIF)); ); //BGR } } - for(int i=0; i<16; i++){ - for(SPDR = 0x00; !(SPSR & _BV(SPIF)); ); + for(int i=0; i<4; i++){ //Stop Frame + for(SPDR = 0xFF; !(SPSR & _BV(SPIF)); ); } delay(1); // One millisecond pause = latch digitalWrite(SPI_LED, spi_out_led = !spi_out_led); @@ -181,14 +179,18 @@ void setup() } // If no data received for an extended time, turn off all LEDs. if((t - lastByteTime) > serialTimeout) { - for(c=0; c<25000; c++) { - for(i=0; i<3; i++) { - for(SPDR = 0x00; !(SPSR & _BV(SPIF)); ); - } - for(i=0; i<1; i++) { - for(SPDR = 0xFF; !(SPSR & _BV(SPIF)); ); - } + for(i=0;i<4;i++) { //Start Frame + for(SPDR = 0x00; !(SPSR & _BV(SPIF)); ); + } + for(c=0; c<25000; c++) { + for(SPDR = 0xFF; !(SPSR & _BV(SPIF)); ); //Brightness Byte + for(i=0; i<3; i++) { + for(SPDR = 0x00; !(SPSR & _BV(SPIF)); ); //BGR } + } + for(i=0;i<4;i++) { //Stop Frame + for(SPDR = 0xFF; !(SPSR & _BV(SPIF)); ); + } delay(1); // One millisecond pause = latch lastByteTime = t; // Reset counter } From e7c9d9decd9b77a9e9ffdfc168ae9501814ff128 Mon Sep 17 00:00:00 2001 From: tociek Date: Sat, 28 Nov 2015 22:58:58 +0100 Subject: [PATCH 05/10] Performance fixes for adalightapa102 Adalightapa102 now inherits from RS232Device. Due to bad initialization, previous CPU usage on RPI1 could reach 60%. ON RPi2 20%. Now its about 3% with grabber in use. Former-commit-id: 7ebb72f503ad74a7768deedf648b9e84c0a7cf3c --- libsrc/leddevice/LedDeviceAdalightApa102.cpp | 21 +++++++++++++++----- libsrc/leddevice/LedDeviceAdalightApa102.h | 4 ++-- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/libsrc/leddevice/LedDeviceAdalightApa102.cpp b/libsrc/leddevice/LedDeviceAdalightApa102.cpp index 5f5cc42e..9cbd3603 100644 --- a/libsrc/leddevice/LedDeviceAdalightApa102.cpp +++ b/libsrc/leddevice/LedDeviceAdalightApa102.cpp @@ -12,18 +12,27 @@ #include "LedDeviceAdalightApa102.h" LedDeviceAdalightApa102::LedDeviceAdalightApa102(const std::string& outputDevice, const unsigned baudrate, int delayAfterConnect_ms) : - LedDeviceAdalight(outputDevice, baudrate, delayAfterConnect_ms), + LedRs232Device(outputDevice, baudrate, delayAfterConnect_ms), _ledBuffer(0), _timer() { + // setup the timer + _timer.setSingleShot(false); + _timer.setInterval(5000); + connect(&_timer, SIGNAL(timeout()), this, SLOT(rewriteLeds())); + + // start the timer + _timer.start(); } -// see dependencies folder for arduino sketch for APA102 +//comparing to ws2801 adalight, the following changes were needed: +// 1- differnt data frame (4 bytes instead of 3) +// 2 - in order to accomodate point 1 above, number of leds sent to adalight is increased by 1/3rd int LedDeviceAdalightApa102::write(const std::vector & ledValues) { ledCount = ledValues.size(); const unsigned int startFrameSize = 4; - const unsigned int endFrameSize = std::max(((ledValues.size() + 15) / 16), 4); - const unsigned int mLedCount = (ledValues.size() * 4) + startFrameSize + endFrameSize; + const unsigned int endFrameSize = std::max(((ledCount + 15) / 16), 4); + const unsigned int mLedCount = (ledCount * 4) + startFrameSize + endFrameSize; if(_ledBuffer.size() != mLedCount+6){ _ledBuffer.resize(mLedCount+6, 0x00); _ledBuffer[0] = 'A'; @@ -34,7 +43,7 @@ int LedDeviceAdalightApa102::write(const std::vector & ledValues) _ledBuffer[5] = _ledBuffer[3] ^ _ledBuffer[4] ^ 0x55; // Checksum } - for (unsigned iLed=1; iLed<=ledValues.size(); iLed++) { + for (unsigned iLed=1; iLed<=ledCount; iLed++) { const ColorRgb& rgb = ledValues[iLed-1]; _ledBuffer[iLed*4+6] = 0xFF; _ledBuffer[iLed*4+1+6] = rgb.red; @@ -57,11 +66,13 @@ int LedDeviceAdalightApa102::switchOff() _ledBuffer[iLed*4+2+6] = 0x00; _ledBuffer[iLed*4+3+6] = 0x00; } + // restart the timer _timer.start(); // write data return writeBytes(_ledBuffer.size(), _ledBuffer.data()); + } void LedDeviceAdalightApa102::rewriteLeds() diff --git a/libsrc/leddevice/LedDeviceAdalightApa102.h b/libsrc/leddevice/LedDeviceAdalightApa102.h index 0c4b502a..eef37662 100644 --- a/libsrc/leddevice/LedDeviceAdalightApa102.h +++ b/libsrc/leddevice/LedDeviceAdalightApa102.h @@ -7,12 +7,12 @@ #include // hyperion incluse -#include "LedDeviceAdalight.h" +#include "LedRs232Device.h" /// /// Implementation of the LedDevice interface for writing to an Adalight led device for APA102. /// -class LedDeviceAdalightApa102 : public LedDeviceAdalight +class LedDeviceAdalightApa102 : public LedRs232Device { Q_OBJECT From f910c717bbf022458049df92ec10da09429dc2c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sch=C3=B6ck=2C=20Florian?= Date: Sun, 29 Nov 2015 19:24:01 +0100 Subject: [PATCH 06/10] reformated code (Arduino IDE auto-reformat) Former-commit-id: 8f94b2bb865337ba7b0538617857432ea0376aea --- .../LightberryHDUSBAPA1021.1.ino | 208 +++++++++--------- 1 file changed, 104 insertions(+), 104 deletions(-) diff --git a/dependencies/LightberryHDUSBAPA1021.1/LightberryHDUSBAPA1021.1.ino b/dependencies/LightberryHDUSBAPA1021.1/LightberryHDUSBAPA1021.1.ino index 5d67cedf..7df0e0d9 100644 --- a/dependencies/LightberryHDUSBAPA1021.1/LightberryHDUSBAPA1021.1.ino +++ b/dependencies/LightberryHDUSBAPA1021.1/LightberryHDUSBAPA1021.1.ino @@ -71,7 +71,7 @@ // 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'}; +static const uint8_t magic[] = {'A', 'd', 'a'}; #define MAGICSIZE sizeof(magic) #define HEADERSIZE (MAGICSIZE + 3) @@ -96,31 +96,31 @@ void setup() // 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; + buffer[256], + indexIn = 0, + indexOut = 0, + mode = MODE_HEADER, + hi, lo, chk, i, spiFlag; int16_t - bytesBuffered = 0, - hold = 0, - c; + bytesBuffered = 0, + hold = 0, + c; int32_t - bytesRemaining; + bytesRemaining; unsigned long - startTime, - lastByteTime, - lastAckTime, - t; - bool - data_in_led = false, - spi_out_led = false; - + startTime, + lastByteTime, + lastAckTime, + t; + bool + data_in_led = false, + spi_out_led = false; + LED_DDR |= LED_PIN; // Enable output for LED LED_PORT &= ~LED_PIN; // LED off pinMode(DATA_LED, OUTPUT); //data in led pinMode(SPI_LED, OUTPUT); //data out led - + Serial.begin(115200); // Teensy/32u4 disregards baud rate; is OK! SPI.begin(); @@ -135,18 +135,18 @@ void setup() // 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(int i=0; i<4; i++){ //Start Frame - for(SPDR = 0x00; !(SPSR & _BV(SPIF)); ); + for (int i = 0; i < 4; i++) { //Start Frame + for (SPDR = 0x00; !(SPSR & _BV(SPIF)); ); } - for(char n=3; n>=0; n--) { - for(c=0; c<25000; c++) { - for(SPDR = 0xFF; !(SPSR & _BV(SPIF)); ); //Brightness byte - for(i=0; i<3; i++) { - for(SPDR = testcolor[n + i]; !(SPSR & _BV(SPIF)); ); //BGR + for (char n = 3; n >= 0; n--) { + for (c = 0; c < 25000; c++) { + for (SPDR = 0xFF; !(SPSR & _BV(SPIF)); ); //Brightness byte + for (i = 0; i < 3; i++) { + for (SPDR = testcolor[n + i]; !(SPSR & _BV(SPIF)); ); //BGR } } - for(int i=0; i<4; i++){ //Stop Frame - for(SPDR = 0xFF; !(SPSR & _BV(SPIF)); ); + for (int i = 0; i < 4; i++) { //Stop Frame + for (SPDR = 0xFF; !(SPSR & _BV(SPIF)); ); } delay(1); // One millisecond pause = latch digitalWrite(SPI_LED, spi_out_led = !spi_out_led); @@ -160,109 +160,109 @@ void setup() // loop() is avoided as even that small bit of function overhead // has a measurable impact on this code's overall throughput. - for(;;) { + for (;;) { digitalWrite(DATA_LED, LOW); digitalWrite(SPI_LED, LOW); // 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)) { + 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) { + 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(i=0;i<4;i++) { //Start Frame - for(SPDR = 0x00; !(SPSR & _BV(SPIF)); ); + if ((t - lastByteTime) > serialTimeout) { + for (i = 0; i < 4; i++) { //Start Frame + for (SPDR = 0x00; !(SPSR & _BV(SPIF)); ); } - for(c=0; c<25000; c++) { - for(SPDR = 0xFF; !(SPSR & _BV(SPIF)); ); //Brightness Byte - for(i=0; i<3; i++) { - for(SPDR = 0x00; !(SPSR & _BV(SPIF)); ); //BGR + for (c = 0; c < 25000; c++) { + for (SPDR = 0xFF; !(SPSR & _BV(SPIF)); ); //Brightness Byte + for (i = 0; i < 3; i++) { + for (SPDR = 0x00; !(SPSR & _BV(SPIF)); ); //BGR } } - for(i=0;i<4;i++) { //Stop Frame - for(SPDR = 0xFF; !(SPSR & _BV(SPIF)); ); + for (i = 0; i < 4; i++) { //Stop Frame + for (SPDR = 0xFF; !(SPSR & _BV(SPIF)); ); } delay(1); // One millisecond pause = latch lastByteTime = t; // Reset counter } } - switch(mode) { + switch (mode) { - case MODE_HEADER: + 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 = 4L * (256L * (long)hi + (long)lo) +4L + (256L *(long)hi + (long)lo +15)/16; - bytesBuffered -= 3; - spiFlag = 0; // No data out yet - mode = MODE_HOLD; // Proceed to latch wait mode - digitalWrite(DATA_LED, data_in_led = !data_in_led); - } 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: - digitalWrite(SPI_LED, spi_out_led = !spi_out_led); - 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; + // In header-seeking mode. Is there enough data to check? + if (bytesBuffered >= HEADERSIZE) { + // Indeed. Check for a 'magic word' match. + for (i = 0; (i < MAGICSIZE) && (buffer[indexOut++] == magic[i++]);); + if (i == MAGICSIZE) { + // Magic word matches. Now how about the checksum? + hi = buffer[indexOut++]; + lo = buffer[indexOut++]; + chk = buffer[indexOut++]; + if (chk == (hi ^ lo ^ 0x55)) { + // Checksum looks valid. Get 16-bit LED count, add 1 + // (# LEDs is always > 0) and multiply by 3 for R,G,B. + bytesRemaining = 4L * (256L * (long)hi + (long)lo) + 4L + (256L * (long)hi + (long)lo + 15) / 16; + bytesBuffered -= 3; + spiFlag = 0; // No data out yet + mode = MODE_HOLD; // Proceed to latch wait mode + digitalWrite(DATA_LED, data_in_led = !data_in_led); + } 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: + digitalWrite(SPI_LED, spi_out_led = !spi_out_led); + 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 } - // 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(;;) } From 4cdba8cdb689cf158074b179136c3f5a75d98f89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sch=C3=B6ck=2C=20Florian?= Date: Sun, 29 Nov 2015 19:31:51 +0100 Subject: [PATCH 07/10] fixed boot animation Former-commit-id: 418ed83a4bd4ddaae79bf41de7fd9fb0794f8239 --- .../LightberryHDUSBAPA1021.1.ino | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/dependencies/LightberryHDUSBAPA1021.1/LightberryHDUSBAPA1021.1.ino b/dependencies/LightberryHDUSBAPA1021.1/LightberryHDUSBAPA1021.1.ino index 7df0e0d9..e10c8c3b 100644 --- a/dependencies/LightberryHDUSBAPA1021.1/LightberryHDUSBAPA1021.1.ino +++ b/dependencies/LightberryHDUSBAPA1021.1/LightberryHDUSBAPA1021.1.ino @@ -135,10 +135,10 @@ void setup() // 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 (int i = 0; i < 4; i++) { //Start Frame - for (SPDR = 0x00; !(SPSR & _BV(SPIF)); ); - } for (char n = 3; n >= 0; n--) { + for (int i = 0; i < 4; i++) { //Start Frame + for (SPDR = 0x00; !(SPSR & _BV(SPIF)); ); + } for (c = 0; c < 25000; c++) { for (SPDR = 0xFF; !(SPSR & _BV(SPIF)); ); //Brightness byte for (i = 0; i < 3; i++) { @@ -148,9 +148,10 @@ void setup() for (int i = 0; i < 4; i++) { //Stop Frame for (SPDR = 0xFF; !(SPSR & _BV(SPIF)); ); } + delay(1); // One millisecond pause = latch - digitalWrite(SPI_LED, spi_out_led = !spi_out_led); } + digitalWrite(SPI_LED, spi_out_led = !spi_out_led); Serial.print("Ada\n"); // Send ACK string to host From f950ec7df6dbd5627bd6870616736f725a2dbb00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sch=C3=B6ck=2C=20Florian?= Date: Sun, 29 Nov 2015 19:35:26 +0100 Subject: [PATCH 08/10] changed the SPI frequency to 2 Mhz. APA102 can handle MUCH higher frequencies than WS2801, so 2Mhz is no big deal for them Former-commit-id: 814faa648e4f39d7105710ff872bde00aaeaada9 --- .../LightberryHDUSBAPA1021.1/LightberryHDUSBAPA1021.1.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/LightberryHDUSBAPA1021.1/LightberryHDUSBAPA1021.1.ino b/dependencies/LightberryHDUSBAPA1021.1/LightberryHDUSBAPA1021.1.ino index e10c8c3b..4a02d71a 100644 --- a/dependencies/LightberryHDUSBAPA1021.1/LightberryHDUSBAPA1021.1.ino +++ b/dependencies/LightberryHDUSBAPA1021.1/LightberryHDUSBAPA1021.1.ino @@ -126,7 +126,7 @@ void setup() SPI.begin(); SPI.setBitOrder(MSBFIRST); SPI.setDataMode(SPI_MODE0); - SPI.setClockDivider(SPI_CLOCK_DIV16); // 1 MHz max, else flicker + SPI.setClockDivider(SPI_CLOCK_DIV8); // 2Mhz // Issue test pattern to LEDs on startup. This helps verify that // wiring between the Arduino and LEDs is correct. Not knowing the From 8d52466acdaa180651db17eb818c77606075e3c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sch=C3=B6ck=2C=20Florian?= Date: Sun, 29 Nov 2015 19:38:40 +0100 Subject: [PATCH 09/10] re-added buffer underrun handling should not be necessary because the number of LED's in a usual Lightberry setup is to low, but it's nice to have implemented. Former-commit-id: def3c46687670439be572e6b9c2dd1de5be2f1b5 --- .../LightberryHDUSBAPA1021.1.ino | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dependencies/LightberryHDUSBAPA1021.1/LightberryHDUSBAPA1021.1.ino b/dependencies/LightberryHDUSBAPA1021.1/LightberryHDUSBAPA1021.1.ino index 4a02d71a..603599c9 100644 --- a/dependencies/LightberryHDUSBAPA1021.1/LightberryHDUSBAPA1021.1.ino +++ b/dependencies/LightberryHDUSBAPA1021.1/LightberryHDUSBAPA1021.1.ino @@ -252,11 +252,11 @@ void setup() // 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; - //} + if ((bytesBuffered < 32) && (bytesRemaining > bytesBuffered)) { + startTime = micros(); + hold = 100 + (32 - bytesBuffered) * 10; + mode = MODE_HOLD; + } } else { // End of data -- issue latch: startTime = micros(); From b898f25f980f804df4fff6aa555f3c386b456d3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sch=C3=B6ck=2C=20Florian?= Date: Sun, 29 Nov 2015 19:56:33 +0100 Subject: [PATCH 10/10] updated zip to match newest source Former-commit-id: 2e54f40d48a993a66f07f5b655965847a9bf7d14 --- dependencies/LightberryHDUSBAPA1021.1.zip | Bin 4567 -> 4548 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/dependencies/LightberryHDUSBAPA1021.1.zip b/dependencies/LightberryHDUSBAPA1021.1.zip index 7a9e6cb1202ba4dc6c24628541a91c3284ab6cb6..af1527aecae1ce355ffcfb87ef4cbd813a79f5fa 100644 GIT binary patch delta 4318 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 M0002I5C8xG06yM4nE(I) delta 4367 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 E3nIf=oB#j-