Improve Skydimo SK0L32 serial device support
This commit is contained in:
@@ -11,6 +11,11 @@
|
||||
|
||||
#include "RGBController_SkydimoSerial.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
#define SKYDIMO_SERIAL_SLEEP_THRESHOLD 100ms
|
||||
#define SKYDIMO_SERIAL_KEEPALIVE_PERIOD 1500ms
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Skydimo Serial
|
||||
@category LEDStrip
|
||||
@@ -41,12 +46,19 @@ RGBController_SkydimoSerial::RGBController_SkydimoSerial(SkydimoSerialController
|
||||
modes.push_back(direct_mode);
|
||||
|
||||
SetupZones();
|
||||
|
||||
last_update_time = std::chrono::steady_clock::now();
|
||||
keepalive_thread_run = true;
|
||||
keepalive_thread = std::thread(&RGBController_SkydimoSerial::KeepaliveThreadFunction, this);
|
||||
}
|
||||
|
||||
RGBController_SkydimoSerial::~RGBController_SkydimoSerial()
|
||||
{
|
||||
Shutdown();
|
||||
|
||||
keepalive_thread_run = false;
|
||||
keepalive_thread.join();
|
||||
|
||||
controller->SetBlack();
|
||||
delete controller;
|
||||
}
|
||||
@@ -129,6 +141,8 @@ void RGBController_SkydimoSerial::DeviceConfigureZone(int zone_idx)
|
||||
|
||||
void RGBController_SkydimoSerial::DeviceUpdateLEDs()
|
||||
{
|
||||
last_update_time = std::chrono::steady_clock::now();
|
||||
|
||||
controller->SetLEDs(colors);
|
||||
}
|
||||
|
||||
@@ -145,3 +159,29 @@ void RGBController_SkydimoSerial::DeviceUpdateSingleLED(int)
|
||||
void RGBController_SkydimoSerial::DeviceUpdateMode()
|
||||
{
|
||||
}
|
||||
|
||||
void RGBController_SkydimoSerial::KeepaliveThreadFunction()
|
||||
{
|
||||
std::chrono::nanoseconds sleep_time;
|
||||
|
||||
while(keepalive_thread_run.load())
|
||||
{
|
||||
sleep_time = SKYDIMO_SERIAL_KEEPALIVE_PERIOD
|
||||
- (std::chrono::steady_clock::now() - last_update_time);
|
||||
|
||||
if(sleep_time <= SKYDIMO_SERIAL_SLEEP_THRESHOLD)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| SK0L32 turns its output off when it does not receive |
|
||||
| a frame for a short period. Repeat the current frame |
|
||||
| while the device is connected, like the vendor app. |
|
||||
\*-----------------------------------------------------*/
|
||||
UpdateLEDsInternal(); // Already protected through the device update thread
|
||||
std::this_thread::sleep_for(SKYDIMO_SERIAL_KEEPALIVE_PERIOD);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::this_thread::sleep_for(sleep_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include "RGBController.h"
|
||||
#include "SkydimoSerialController.h"
|
||||
|
||||
@@ -28,6 +30,11 @@ public:
|
||||
void DeviceUpdateSingleLED(int led);
|
||||
void DeviceUpdateMode();
|
||||
|
||||
void KeepaliveThreadFunction();
|
||||
|
||||
private:
|
||||
SkydimoSerialController* controller;
|
||||
SkydimoSerialController* controller;
|
||||
std::chrono::time_point<std::chrono::steady_clock> last_update_time;
|
||||
std::atomic<bool> keepalive_thread_run;
|
||||
std::thread keepalive_thread;
|
||||
};
|
||||
|
||||
@@ -436,8 +436,15 @@ bool SkydimoSerialController::WriteFrame(const std::vector<RGBColor>& colors, un
|
||||
packet.push_back(skydimo_serial_frame_header[header_idx]);
|
||||
}
|
||||
|
||||
packet.push_back((unsigned char)((count >> 8) & 0xFF));
|
||||
packet.push_back((unsigned char)(count & 0xFF));
|
||||
/*-----------------------------------------------------*\
|
||||
| Skydimo uses the Adalight length convention: the |
|
||||
| 16-bit field contains the last LED index, not the |
|
||||
| number of LEDs. |
|
||||
\*-----------------------------------------------------*/
|
||||
unsigned int frame_length = count > 0 ? count - 1 : 0;
|
||||
|
||||
packet.push_back((unsigned char)((frame_length >> 8) & 0xFF));
|
||||
packet.push_back((unsigned char)(frame_length & 0xFF));
|
||||
|
||||
for(unsigned int led_idx = 0; led_idx < count; led_idx++)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user