From 3f6c00966e377e371d52c11923ba042fd4787275 Mon Sep 17 00:00:00 2001 From: tociek Date: Tue, 13 Oct 2015 23:35:27 +0200 Subject: [PATCH] Final adjustments for APA102 via Adalight Former-commit-id: ba786d5c4165c992ce4671e487294547c8dae8c6 --- libsrc/leddevice/LedDeviceAdalightApa102.cpp | 53 ++++++++++++++++++++ libsrc/leddevice/LedDeviceAdalightApa102.h | 12 ++++- 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 libsrc/leddevice/LedDeviceAdalightApa102.cpp diff --git a/libsrc/leddevice/LedDeviceAdalightApa102.cpp b/libsrc/leddevice/LedDeviceAdalightApa102.cpp new file mode 100644 index 00000000..172e76de --- /dev/null +++ b/libsrc/leddevice/LedDeviceAdalightApa102.cpp @@ -0,0 +1,53 @@ + +// STL includes +#include +#include +#include + +// Linux includes +#include +#include + +// hyperion local includes +#include "LedDeviceAdalightApa102.h" + +LedDeviceAdalightApa102::LedDeviceAdalightApa102(const std::string& outputDevice, const unsigned baudrate, int delayAfterConnect_ms) : + LedDeviceAdalight(outputDevice, baudrate, delayAfterConnect_ms), + _ledBuffer(0), + _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 +int LedDeviceAdalightApa102::write(const std::vector & ledValues) +{ + const unsigned int startFrameSize = 4; + const unsigned int endFrameSize = (ledValues.size() + 63) / 64 * 4; + const unsigned int mLedCount = (ledValues.size() * 4) + startFrameSize + endFrameSize; + if(_ledBuffer.size() != mLedCount){ + _ledBuffer.resize(mLedCount, 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[5] = _ledBuffer[3] ^ _ledBuffer[4] ^ 0x55; // Checksum + } + + for (unsigned iLed=1; iLed<=ledValues.size(); iLed++) { + const ColorRgb& rgb = ledValues[iLed]; + _ledBuffer[iLed*4+6] = 0xFF; + _ledBuffer[iLed*4+1+6] = rgb.red; + _ledBuffer[iLed*4+2+6] = rgb.green; + _ledBuffer[iLed*4+3+6] = rgb.blue; + } + + // restart the timer + _timer.start(); + + // write data + return writeBytes(_ledBuffer.size(), _ledBuffer.data()); +} + + diff --git a/libsrc/leddevice/LedDeviceAdalightApa102.h b/libsrc/leddevice/LedDeviceAdalightApa102.h index 63e39c59..a0a7c89c 100644 --- a/libsrc/leddevice/LedDeviceAdalightApa102.h +++ b/libsrc/leddevice/LedDeviceAdalightApa102.h @@ -10,7 +10,7 @@ #include "LedDeviceAdalight.h" /// -/// Implementation of the LedDevice interface for writing to an Adalight led device for APA102 led strips. +/// Implementation of the LedDevice interface for writing to an Adalight led device for APA102. /// class LedDeviceAdalightApa102 : public LedDeviceAdalight { @@ -33,4 +33,14 @@ public: /// virtual int write(const std::vector & ledValues); + + +private: + /// The buffer containing the packed RGB values + std::vector _ledBuffer; + + /// 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 + QTimer _timer; };