From c17e4894d9a8ac8328ad838f1feae155615e1531 Mon Sep 17 00:00:00 2001 From: penfold42 Date: Tue, 10 May 2016 20:16:19 +1000 Subject: [PATCH] Apa102 fix if the led strip has more physical LEDs than you want to configure with hyperion (#626) * Removed -HUP so the default -TERM signal is sent instead. - hyperiond only listens for TERM and INT. HUP is often used to get an exe to reread its config Changed pgrep to add '-x' so it wont partial match on the exe name. - I have multiple instances with multiple hyperiond-instance1 names - this ensures the service script only kills the right process * reversing errant change to hyperion.systemd.sh * started bug fixes for APA strips with more physical leds than configured * 1st cut of changes to APA102. now looks at config for "leds" which is the # of hardware leds in the strip. This enables us to write the correct trailer length in the packet. Also fixed a bug where switchoff was writing the wrong # of leds * removed commented out old code removed debug printf * included prebuild test binary for Pi2 * Second attempt at the fix. BEFORE: If you have more physcial LEDs than defined in the "leds" "index" section of the config there is random junk added to the end of the strip. WITH THIS FIX: In the "device" section specify the number of physical leds with: "leds" : 212, If this is greater than the number of led indexes, additional LEDs are set to black If this is smaller than the number of led indexes, it is ignored * included test binary * Clean exit if the device config is missing or a non-supported device type is specified Former-commit-id: 8ae96188fa74d91b13a921e7d5faf6d6ac1c42ee --- dependencies/external/rpi_ws281x | 2 +- hyperiond.test-binary.REMOVED.git-id | 1 + libsrc/leddevice/LedDeviceAPA102.cpp | 49 ++++++++++++++++++++------- libsrc/leddevice/LedDeviceAPA102.h | 5 ++- libsrc/leddevice/LedDeviceFactory.cpp | 4 ++- 5 files changed, 45 insertions(+), 16 deletions(-) create mode 100644 hyperiond.test-binary.REMOVED.git-id diff --git a/dependencies/external/rpi_ws281x b/dependencies/external/rpi_ws281x index e053bc9b..f82fa85f 160000 --- a/dependencies/external/rpi_ws281x +++ b/dependencies/external/rpi_ws281x @@ -1 +1 @@ -Subproject commit e053bc9be127d1f4f0cffd10e7892cd32657ecf7 +Subproject commit f82fa85f26c9ee10210469e61315d9c0182a2b81 diff --git a/hyperiond.test-binary.REMOVED.git-id b/hyperiond.test-binary.REMOVED.git-id new file mode 100644 index 00000000..dc9b6471 --- /dev/null +++ b/hyperiond.test-binary.REMOVED.git-id @@ -0,0 +1 @@ +5d75f380f2bd74d3cd6b574f0a7d05850786216b \ No newline at end of file diff --git a/libsrc/leddevice/LedDeviceAPA102.cpp b/libsrc/leddevice/LedDeviceAPA102.cpp index 26a21f72..e7dc7eb6 100644 --- a/libsrc/leddevice/LedDeviceAPA102.cpp +++ b/libsrc/leddevice/LedDeviceAPA102.cpp @@ -12,38 +12,61 @@ // hyperion local includes #include "LedDeviceAPA102.h" -LedDeviceAPA102::LedDeviceAPA102(const std::string& outputDevice, const unsigned baudrate) : +LedDeviceAPA102::LedDeviceAPA102(const std::string& outputDevice, const unsigned baudrate, const unsigned ledcount) : LedSpiDevice(outputDevice, baudrate, 500000), _ledBuffer(0) { - // empty + _HW_ledcount = ledcount; } int LedDeviceAPA102::write(const std::vector &ledValues) { + _mLedCount = ledValues.size(); + const unsigned int max_leds = std::max(_mLedCount, _HW_ledcount); 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); + const unsigned int endFrameSize = std::max(((max_leds + 15) / 16), 4); + const unsigned int APAbufferSize = (max_leds * 4) + startFrameSize + endFrameSize; + +//printf ("_mLedCount %d _HW_ledcount %d max_leds %d APAbufferSize %d\n", +// _mLedCount, _HW_ledcount, max_leds, APAbufferSize); + + if(_ledBuffer.size() != APAbufferSize){ + _ledBuffer.resize(APAbufferSize, 0xFF); _ledBuffer[0] = 0x00; _ledBuffer[1] = 0x00; _ledBuffer[2] = 0x00; _ledBuffer[3] = 0x00; } - for (unsigned iLed=1; iLed<=ledValues.size(); ++iLed) { - const ColorRgb& rgb = ledValues[iLed-1]; - _ledBuffer[iLed*4] = 0xFF; - _ledBuffer[iLed*4+1] = rgb.red; - _ledBuffer[iLed*4+2] = rgb.green; - _ledBuffer[iLed*4+3] = rgb.blue; + unsigned iLed=0; + for (iLed=0; iLed < _mLedCount; ++iLed) { + const ColorRgb& rgb = ledValues[iLed]; + _ledBuffer[4+iLed*4] = 0xFF; + _ledBuffer[4+iLed*4+1] = rgb.red; + _ledBuffer[4+iLed*4+2] = rgb.green; + _ledBuffer[4+iLed*4+3] = rgb.blue; } + for ( ; iLed < max_leds; ++iLed) { + _ledBuffer[4+iLed*4] = 0xFF; + _ledBuffer[4+iLed*4+1] = 0x00; + _ledBuffer[4+iLed*4+2] = 0x00; + _ledBuffer[4+iLed*4+3] = 0x00; + } + +/* +for (unsigned i=0; i< _ledBuffer.size(); i+=4) { + printf ("i %2d led %2d RGB 0x0%02x%02x%02x%02x\n",i, i/4-1, + _ledBuffer[i+0], + _ledBuffer[i+1], + _ledBuffer[i+2], + _ledBuffer[i+3]); +} +*/ return writeBytes(_ledBuffer.size(), _ledBuffer.data()); } int LedDeviceAPA102::switchOff() { - return write(std::vector(_ledBuffer.size(), ColorRgb{0,0,0})); + return write(std::vector(_mLedCount, ColorRgb{0,0,0})); } diff --git a/libsrc/leddevice/LedDeviceAPA102.h b/libsrc/leddevice/LedDeviceAPA102.h index 3cc4e518..405e54d8 100644 --- a/libsrc/leddevice/LedDeviceAPA102.h +++ b/libsrc/leddevice/LedDeviceAPA102.h @@ -21,7 +21,8 @@ public: /// @param baudrate The used baudrate for writing to the output device /// LedDeviceAPA102(const std::string& outputDevice, - const unsigned baudrate); + const unsigned baudrate, const unsigned ledcount ); + /// /// Writes the led color values to the led-device @@ -38,5 +39,7 @@ private: /// The buffer containing the packed RGB values std::vector _ledBuffer; + unsigned int _HW_ledcount; + unsigned int _mLedCount; }; diff --git a/libsrc/leddevice/LedDeviceFactory.cpp b/libsrc/leddevice/LedDeviceFactory.cpp index 6d737ec9..7cf2385b 100755 --- a/libsrc/leddevice/LedDeviceFactory.cpp +++ b/libsrc/leddevice/LedDeviceFactory.cpp @@ -124,8 +124,9 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig) { const std::string output = deviceConfig["output"].asString(); const unsigned rate = deviceConfig["rate"].asInt(); + const unsigned ledcount = deviceConfig.get("leds",0).asInt(); - LedDeviceAPA102* deviceAPA102 = new LedDeviceAPA102(output, rate); + LedDeviceAPA102* deviceAPA102 = new LedDeviceAPA102(output, rate, ledcount); deviceAPA102->open(); device = deviceAPA102; @@ -349,6 +350,7 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig) { std::cout << "LEDDEVICE ERROR: Unknown/Unimplemented device " << type << std::endl; // Unknown / Unimplemented device + exit(1); } return device; }