Improve Skydimo SK0L32 serial device support

This commit is contained in:
Zoin Zoin
2026-08-27 18:15:00 -05:00
committed by Adam Honse
parent ee8d24bac6
commit 6315c79afa
3 changed files with 57 additions and 3 deletions
@@ -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++)
{