From 33edcddb1b6af087164d5837d72668b184be1983 Mon Sep 17 00:00:00 2001 From: tociek Date: Tue, 13 Oct 2015 19:11:01 +0200 Subject: [PATCH 1/2] APA102 device for use with Adalight (nominaly for ws2801) Former-commit-id: 7fb9e8e84518be9387ea9feca11e93a8a5389e4f --- libsrc/leddevice/CMakeLists.txt | 2 ++ libsrc/leddevice/LedDeviceAdalight.h | 2 +- libsrc/leddevice/LedDeviceAdalightApa102.h | 36 ++++++++++++++++++++++ libsrc/leddevice/LedDeviceFactory.cpp | 12 ++++++++ 4 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 libsrc/leddevice/LedDeviceAdalightApa102.h diff --git a/libsrc/leddevice/CMakeLists.txt b/libsrc/leddevice/CMakeLists.txt index 06e13278..16463fb5 100755 --- a/libsrc/leddevice/CMakeLists.txt +++ b/libsrc/leddevice/CMakeLists.txt @@ -15,6 +15,7 @@ include_directories( SET(Leddevice_QT_HEADERS ${CURRENT_SOURCE_DIR}/LedRs232Device.h ${CURRENT_SOURCE_DIR}/LedDeviceAdalight.h + ${CURRENT_SOURCE_DIR}/LedDeviceAdalightApa102.h ${CURRENT_SOURCE_DIR}/LedDeviceAmbiLed.h ${CURRENT_SOURCE_DIR}/LedDevicePhilipsHue.h ) @@ -40,6 +41,7 @@ SET(Leddevice_SOURCES ${CURRENT_SOURCE_DIR}/LedRs232Device.cpp ${CURRENT_SOURCE_DIR}/LedDeviceAdalight.cpp + ${CURRENT_SOURCE_DIR}/LedDeviceAdalightApa102.cpp ${CURRENT_SOURCE_DIR}/LedDeviceAmbiLed.cpp ${CURRENT_SOURCE_DIR}/LedDeviceLightpack.cpp ${CURRENT_SOURCE_DIR}/LedDeviceMultiLightpack.cpp diff --git a/libsrc/leddevice/LedDeviceAdalight.h b/libsrc/leddevice/LedDeviceAdalight.h index bc08200b..66d299d1 100644 --- a/libsrc/leddevice/LedDeviceAdalight.h +++ b/libsrc/leddevice/LedDeviceAdalight.h @@ -40,7 +40,7 @@ private slots: /// Write the last data to the leds again void rewriteLeds(); -private: +protected: /// The buffer containing the packed RGB values std::vector _ledBuffer; diff --git a/libsrc/leddevice/LedDeviceAdalightApa102.h b/libsrc/leddevice/LedDeviceAdalightApa102.h new file mode 100644 index 00000000..63e39c59 --- /dev/null +++ b/libsrc/leddevice/LedDeviceAdalightApa102.h @@ -0,0 +1,36 @@ +#pragma once + +// STL includes +#include + +// Qt includes +#include + +// hyperion incluse +#include "LedDeviceAdalight.h" + +/// +/// Implementation of the LedDevice interface for writing to an Adalight led device for APA102 led strips. +/// +class LedDeviceAdalightApa102 : public LedDeviceAdalight +{ + Q_OBJECT + +public: + /// + /// Constructs the LedDevice for attached Adalight device + /// + /// @param outputDevice The name of the output device (eg '/dev/ttyS0') + /// @param baudrate The used baudrate for writing to the output device + /// + LedDeviceAdalightApa102(const std::string& outputDevice, const unsigned baudrate, int delayAfterConnect_ms); + + /// + /// Writes the led color values to the led-device + /// + /// @param ledValues The color-value per led + /// @return Zero on succes else negative + /// + virtual int write(const std::vector & ledValues); + +}; diff --git a/libsrc/leddevice/LedDeviceFactory.cpp b/libsrc/leddevice/LedDeviceFactory.cpp index 55028fde..ce8cb835 100755 --- a/libsrc/leddevice/LedDeviceFactory.cpp +++ b/libsrc/leddevice/LedDeviceFactory.cpp @@ -33,6 +33,7 @@ #include "LedDevicePhilipsHue.h" #include "LedDeviceTpm2.h" #include "LedDeviceAtmo.h" +#include "LedDeviceAdalightApa102.h" #ifdef ENABLE_WS2812BPWM #include "LedDeviceWS2812b.h" @@ -58,6 +59,17 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig) device = deviceAdalight; } + else if (type == "adalightapa102") + { + const std::string output = deviceConfig["output"].asString(); + const unsigned rate = deviceConfig["rate"].asInt(); + const int delay_ms = deviceConfig["delayAfterConnect"].asInt(); + + LedDeviceAdalightApa102* deviceAdalightApa102 = new LedDeviceAdalightApa102(output, rate, delay_ms); + deviceAdalightApa102->open(); + + device = deviceAdalightApa102; + } else if (type == "ambiled") { const std::string output = deviceConfig["output"].asString(); From 3f6c00966e377e371d52c11923ba042fd4787275 Mon Sep 17 00:00:00 2001 From: tociek Date: Tue, 13 Oct 2015 23:35:27 +0200 Subject: [PATCH 2/2] 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; };