diff --git a/CLC-qthing/CyanLight.cpp b/CLC-qthing/CyanLight.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..410da48c56a1eafc0332e9e73dbbb80202685a39
--- /dev/null
+++ b/CLC-qthing/CyanLight.cpp
@@ -0,0 +1,25 @@
+#include "CyanLight.hpp"
+
+#include <cstdlib>  // TODO: was this for std::min() ?
+
+
+uint8_t MAX_CHANNELS = 8;
+
+extern const uint8_t CyanLight::channelGPIOs[] = { 42 };  // !!!
+
+
+CyanLight::CyanLightControl::CyanLightControl(uint8_t channelsConfigured) {
+
+  if (channelsConfigured > MAX_CHANNELS)
+    ESP_LOGE("", "Cannot create channel#[ %i ]! Hardware limit is #[ %i ]", channelsConfigured, MAX_CHANNELS);
+
+  uint8_t channels = std::min(channelsConfigured, MAX_CHANNELS);
+
+  for (uint8_t i = 0; i < channels; i++)
+    this->addChannel(CyanLight::channelGPIOs[i]);
+}
+
+
+bool CyanLight::CyanLightControl::addChannel() {
+  // TODO: implement!
+}
diff --git a/CLC-qthing/CyanLight.hpp b/CLC-qthing/CyanLight.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..de3691c188c1a3af5a960d08d5461cb9f8aacd32
--- /dev/null
+++ b/CLC-qthing/CyanLight.hpp
@@ -0,0 +1,20 @@
+#pragma once
+
+// TODO: should we include <cinttypes> here or accepts its ingress via FxCyanF.hpp ???
+
+#include "SiliconTorch/FxCyanF.hpp"
+
+
+namespace CyanLight {
+
+  extern const uint8_t channelGPIOs[];
+
+  class CyanLightControl : SiliconTorch::FxCyanF {
+    public:
+      CyanLightControl(uint8_t channelsConfigured);
+
+      bool addChannel();
+
+  };
+
+}
diff --git a/CLC-qthing/SiliconTorch/FxCyanF.cpp b/CLC-qthing/SiliconTorch/FxCyanF.cpp
index 43a523034c508aa50895d515400b7a2b1fb46a98..0cf956cb0dde8ca470abe4ee7d0f1aa8247ac606 100644
--- a/CLC-qthing/SiliconTorch/FxCyanF.cpp
+++ b/CLC-qthing/SiliconTorch/FxCyanF.cpp
@@ -33,11 +33,10 @@ static float bytes2float(const char *bytes) {
 }
 
 
-SiliconTorch::FxCyanF::FxCyanF(uint16_t baseChannel, uint8_t channelsConfigured) : baseChannel{baseChannel} {
+SiliconTorch::FxCyanF::FxCyanF() {
 
-  this->channelsConfigured = std::min(channelsConfigured, CyanLight::MAX_CHANNELS);
-
-  this->channels = new SiliconTorch::Impl::PWMChannel*[this->channelsConfigured];
+  // TODO: make vector!
+  this->channels = new SiliconTorch::Impl::PWMChannel*[MAX_CHANNELS];
 
   this->timer_cfg.duty_resolution = (ledc_timer_bit_t)this->resolution;
   this->timer_cfg.freq_hz         = this->frequency;
@@ -55,18 +54,6 @@ SiliconTorch::FxCyanF::FxCyanF(uint16_t baseChannel, uint8_t channelsConfigured)
     else ESP_LOGE(TAG, "Invalid message format: Fragmentation is unsupported");
   });
 
-  for (uint8_t i = 0; i < this->channelsConfigured; i++) {
-    this->channels[i] = new SiliconTorch::Impl::PWMChannel(i, CyanLight::channelGPIOS[i]);
-
-    char topic[32];
-    snprintf(topic, sizeof(topic), "pwm/$%i", i);
-
-    add_message_callback(this->genDeviceTopic(topic), [&, i](std::string message) {
-      this->setPWM(i, strtof(message.c_str(), NULL));
-      this->callPacketCallback();
-    });
-  }
-
 
   std::string header("fxCyanF");
   uint8_t headerLength = header.length();
@@ -163,6 +150,30 @@ SiliconTorch::FxCyanF::FxCyanF(uint16_t baseChannel, uint8_t channelsConfigured)
 }
 
 
+bool SiliconTorch::FxCyanF::addChannel(uint8_t gpio) {
+  if (this->channelsConfigured >= MAX_CHANNELS) {
+    ESP_LOGE(TAG, "Maximum number of PWMChannels reached");
+    return false;
+  }
+
+  uint8_t channel = this->channelsConfigured;
+
+  // TODO: catch channel creation errors from IDF (e.g. on input-only GPIO)
+  this->channels[channel] = new SiliconTorch::Impl::PWMChannel(channel, gpio);
+
+  char topic[32];
+  snprintf(topic, sizeof(topic), "pwm/$%i", channel);
+
+  add_message_callback(this->genDeviceTopic(topic), [&, channel](std::string message) {
+    this->setPWM(channel, strtof(message.c_str(), NULL));
+    this->callPacketCallback();
+  });
+
+  this->channelsConfigured++;
+  return true;
+}
+
+
 bool SiliconTorch::FxCyanF::handleUnicast(const char *data, std::size_t length) {
   std::size_t size = this->getChannelCount() * sizeof(float);
 
diff --git a/CLC-qthing/SiliconTorch/FxCyanF.hpp b/CLC-qthing/SiliconTorch/FxCyanF.hpp
index a0fa5899394072d2359a4fbf4daa317abbca2b23..125fb28730bb93d7699072926918a7810cf33df7 100644
--- a/CLC-qthing/SiliconTorch/FxCyanF.hpp
+++ b/CLC-qthing/SiliconTorch/FxCyanF.hpp
@@ -15,15 +15,14 @@ namespace SiliconTorch {
 
   extern const char *TAG;
 
-  
-  const uint8_t channelGPIOS[MAX_CHANNELS] = { 27, 16, 17, 18, 19, 21 };
-
   typedef std::function<void()> PacketHandledCallback;
   typedef std::function<float(float)> GammaCorrector;
 
   class FxCyanF {
     public:
-      FxCyanF(uint16_t baseChannel, uint8_t channelsConfigured = 1);
+      FxCyanF(uint16_t baseChannel = 0);
+
+      bool addChannel(uint8_t gpio);
 
       void setPWM(uint8_t channel, float value);
 
@@ -61,7 +60,8 @@ namespace SiliconTorch {
       uint8_t resolution =   10;  // bits
 
       uint16_t baseChannel;
-      uint8_t channelsConfigured;
+      uint8_t channelsConfigured = 0;
+
       Impl::PWMChannel **channels;
 
       ledc_timer_config_t timer_cfg;
diff --git a/CLC-qthing/SiliconTorch/PWMChannel.cpp b/CLC-qthing/SiliconTorch/PWMChannel.cpp
index d5b16c68638f49791676c1bad1a91097957f2d14..411e55e3867c5cfce0d15b54645a155726d657a7 100644
--- a/CLC-qthing/SiliconTorch/PWMChannel.cpp
+++ b/CLC-qthing/SiliconTorch/PWMChannel.cpp
@@ -31,7 +31,7 @@ SiliconTorch::Impl::PWMChannel::PWMChannel(uint8_t channel, uint8_t gpio) : chan
 
   ledc_channel_config(&ledc_channel);
 
-  setPWM(0);
+  this->setPWM(0);
 }
 
 void SiliconTorch::Impl::PWMChannel::setPWM(uint32_t pwm) {
diff --git a/CLC-qthing/device_main.cpp b/CLC-qthing/device_main.cpp
index 04681872833be6092356cf822b16cbd97566c8fc..fc83f73132a67d39c7e875775c75f2e13926fc85 100644
--- a/CLC-qthing/device_main.cpp
+++ b/CLC-qthing/device_main.cpp
@@ -7,11 +7,11 @@
 #include "freertos/task.h"
 
 
-#include "CyanLightControl.hpp"
+#include "CyanLight.hpp"
 
 
 
-CyanLight::Controller ctrl(0, 1);
+CyanLight::CyanLightControl ctrl(1);
 
 
 void device_main() {