diff --git a/CyanBusInjector-FW/CMakeLists.txt b/CyanBusInjector-FW/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d737352a1814723b55fa7dd1953ee16ac8af7998
--- /dev/null
+++ b/CyanBusInjector-FW/CMakeLists.txt
@@ -0,0 +1,13 @@
+idf_component_register(
+  SRC_DIRS
+  "."
+
+  INCLUDE_DIRS
+  "."
+
+  REQUIRES
+  main
+)
+
+component_compile_options(-std=c++17)
+component_compile_options(-Wno-reorder)
diff --git a/CyanBusInjector-FW/CyanBusInjector.cpp b/CyanBusInjector-FW/CyanBusInjector.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..936901d5ea4efd1691d0de19dabbd3783779e456
--- /dev/null
+++ b/CyanBusInjector-FW/CyanBusInjector.cpp
@@ -0,0 +1,37 @@
+#include "CyanBusInjector.hpp"
+
+// C++ system level
+#include <cinttypes>
+// #include <functional>
+
+// ESP32 specific
+// #include "esp_err.h"
+// #include "esp_log.h"
+// #include "driver/gpio.h"
+// #include "driver/uart.h"
+// #include "freertos/FreeRTOS.h"
+// #include "freertos/queue.h"
+
+// project specific
+#include "CyanBusTX.hpp"
+
+// qthing stuff
+// #include ""
+
+
+// TODO: Needed…?
+const char* const TAG = "CyanBusInjector";
+
+
+namespace SiliconTorch {
+
+  namespace CyanBusInjector {
+
+    CyanBusInjector::CyanBusInjector(uint8_t tx, uint8_t rx, uint8_t de, uint8_t re, uint32_t baudRate, uint8_t uartChannel) : cbTX(tx, rx, de, re, baudRate, uartChannel) {
+
+    }
+
+
+
+  }
+}
diff --git a/CyanBusInjector-FW/CyanBusInjector.hpp b/CyanBusInjector-FW/CyanBusInjector.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..de708d53026437e1371891d6983b8c51005984cb
--- /dev/null
+++ b/CyanBusInjector-FW/CyanBusInjector.hpp
@@ -0,0 +1,40 @@
+// C++ system level
+#include <cinttypes>
+
+// ESP32 specific
+// #include "esp_log.h"
+
+// project specific
+#include "CyanBusTX.hpp"
+
+// qthing stuff
+// #include ""
+
+
+namespace SiliconTorch {
+
+  namespace CyanBusInjector {
+
+
+    class CyanBusInjector {
+      public:
+        CyanBusInjector(uint8_t tx, uint8_t rx, uint8_t de, uint8_t re, uint32_t baudRate = 115200, uint8_t uartChannel = 1);
+
+
+      private:
+
+        CyanBusTX::CyanBusTX cbTX;
+
+
+    };
+
+
+
+    // Pinout proto board:
+    // TX -> 23
+    // RX -> 34
+    // DE -> 32
+    // RE -> 33
+
+  }
+}
diff --git a/CyanBusInjector-FW/CyanBusTX.cpp b/CyanBusInjector-FW/CyanBusTX.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6f7dc620572de80a8663793eb0c3fb94e664bbe2
--- /dev/null
+++ b/CyanBusInjector-FW/CyanBusTX.cpp
@@ -0,0 +1,131 @@
+#include "CyanBusTX.hpp"
+
+// C++ system level
+#include <cstring>     // memset, strncmp
+// #include <cstdlib>     // TODO: is this for memcpy?
+#include <cinttypes>
+// #include <functional>
+
+// ESP32 specific
+#include "esp_err.h"
+#include "esp_log.h"
+#include "driver/gpio.h"
+#include "driver/uart.h"
+
+// project specific
+// #include ""
+
+// qthing stuff
+// #include <qthing>
+
+
+
+static const char* TAG = "CyanBusTX";
+
+
+namespace SiliconTorch {
+
+  namespace CyanBusTX {
+
+
+    CyanBusTX::CyanBusTX(uint8_t tx, uint8_t rx, uint8_t de, uint8_t re, uint32_t baudRate, uint8_t uartChannel) : tx(tx), rx(rx), de(de), re(re), uartChannel(uartChannel) {
+
+      uint64_t bitMask = 0;
+
+      bitMask |= 1 << tx;
+      bitMask |= 1 << de;
+      bitMask |= 1 << re;
+
+      gpio_config_t gpio = {
+        .pin_bit_mask = bitMask,
+        .mode         = GPIO_MODE_OUTPUT,
+        .pull_up_en   = GPIO_PULLUP_DISABLE,
+        .pull_down_en = GPIO_PULLDOWN_DISABLE,
+        .intr_type    = GPIO_INTR_DISABLE,        
+      };
+
+      // configure outputs
+      gpio_config(&gpio);
+      txrxEN(false);
+
+      gpio.pin_bit_mask = 1 << rx;
+      gpio.mode = GPIO_MODE_INPUT;
+
+      // configure inputs
+      gpio_config(&gpio);
+
+
+      uart_config_t uartConfig = {
+        .baud_rate           = (int)baudRate,
+        .data_bits           = UART_DATA_8_BITS,
+        .parity              = UART_PARITY_DISABLE,
+        .stop_bits           = UART_STOP_BITS_1,
+        .flow_ctrl           = UART_HW_FLOWCTRL_DISABLE,
+        .rx_flow_ctrl_thresh = 0,
+        .use_ref_tick        = false,
+        // .source_clk = UART_SCLK_APB,
+      };
+
+
+      uart_port_t _ch = (uart_port_t)uartChannel;
+
+      ESP_ERROR_CHECK(uart_param_config(_ch, &uartConfig));
+      ESP_ERROR_CHECK(uart_set_pin(_ch, tx, rx, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
+      // uart_intr_config(_ch);
+
+      ESP_ERROR_CHECK(uart_driver_install(_ch, 0, MTU * 2, 256, NULL, 0));  // rxBuf = 256; (hopefully greater than FIFO size also in the future)
+
+      ESP_ERROR_CHECK(uart_set_mode(_ch, UART_MODE_UART));
+
+      // WARNING: RX timeout MUST be > 0 !!
+      // It determines after how much symbols pause an event is raised (event queue uses TOUT-feature internally)
+      // uart_set_rx_timeout(_ch, 5);
+      // TODO: We will only send… so just delete this completely??
+
+
+      // transmit only ATM!
+      txEN(true);
+      rxEN(false);
+    }
+
+
+    void CyanBusTX::write(std::string& data) {
+      write((uint8_t*)(data.c_str()), data.length());
+    }
+
+    void CyanBusTX::write(const uint8_t* data, uint32_t length) {
+      uint32_t bytes = uart_write_bytes((uart_port_t)uartChannel, (char*)data, length);
+
+      // TODO: Set level to DEBUG after dev
+      ESP_LOGI(TAG, "Send |bytes|[ %d ]", bytes);
+
+      if (bytes != length) ESP_LOGW(TAG, "Send only |bytes|[ %d ] from a |buffer|[ %d ]", bytes, length);
+    }
+
+
+    void CyanBusTX::setBaudRate(uint32_t baudRate) {
+      uart_set_baudrate((uart_port_t)uartChannel, baudRate);
+    }
+
+    uint32_t CyanBusTX::getBaudRate() {
+      uint32_t baudRate = 0;
+      uart_get_baudrate((uart_port_t)uartChannel, &baudRate);
+      return baudRate;
+    }
+
+
+    void CyanBusTX::txEN(bool state) {
+      gpio_set_level((gpio_num_t)de, state);
+    }
+
+    void CyanBusTX::rxEN(bool state) {
+      gpio_set_level((gpio_num_t)re, state ^ 1);
+    }
+    
+    void CyanBusTX::txrxEN(bool state) {
+      txEN(state);
+      rxEN(state);
+    }
+
+  }
+}
diff --git a/CyanBusInjector-FW/CyanBusTX.hpp b/CyanBusInjector-FW/CyanBusTX.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..cca44e505dd66081e6ca265977eddb8f0fe1dfb8
--- /dev/null
+++ b/CyanBusInjector-FW/CyanBusTX.hpp
@@ -0,0 +1,47 @@
+#pragma once
+
+// C++ system level
+#include <string>
+#include <cinttypes>
+
+// ESP32 specific
+// #include ""
+
+// project specific
+// #include ""
+
+// qthing stuff
+// #include <qthing>
+
+
+namespace SiliconTorch {
+
+  namespace CyanBusTX {
+
+    // CyanBus payload MTU
+    // This leads to ~54 P/s @ 2 MBaud at 100% load
+    constexpr uint32_t MTU = 4096;
+
+
+    class CyanBusTX {
+      public:
+        CyanBusTX(uint8_t tx, uint8_t rx, uint8_t de, uint8_t re, uint32_t baudRate = 115200, uint8_t uartChannel = 1);
+
+        uint32_t getBaudRate();
+        void setBaudRate(uint32_t baudRate);
+
+        void write(std::string& data);
+        void write(const uint8_t* data, uint32_t length);
+
+      private:
+
+        uint8_t uartChannel;
+        uint8_t tx, rx, de, re;
+
+        void txEN(bool state);
+        void rxEN(bool state);
+        void txrxEN(bool state);
+
+    };
+  }
+}
diff --git a/CyanBusInjector-FW/device_config.h b/CyanBusInjector-FW/device_config.h
new file mode 100644
index 0000000000000000000000000000000000000000..a11280c0b5122bbe78f79199e8edfd8734de8e77
--- /dev/null
+++ b/CyanBusInjector-FW/device_config.h
@@ -0,0 +1,9 @@
+// hostname and device namespace
+#define DEVICE_NAME "CyanBusInjector"
+
+#define NTP_SERVER "pool.ntp.org"
+
+
+#define DEVICE_IP          "192.168.0.254"
+#define DEVICE_GW          "192.168.0.1"
+#define DEVICE_NETMASK     "255.255.255.0"
diff --git a/CyanBusInjector-FW/device_main.cpp b/CyanBusInjector-FW/device_main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f916f71598eb939ab9b2f8cc74d62dcad679f031
--- /dev/null
+++ b/CyanBusInjector-FW/device_main.cpp
@@ -0,0 +1,26 @@
+#include <qthing>
+
+// #include "esp_log.h"
+// #include "driver/gpio.h"
+
+
+#include "CyanBusInjector.hpp"
+
+
+SiliconTorch::CyanBusInjector::CyanBusInjector* injector;
+
+void device_main() {
+
+  qthing::Config cfg;
+  cfg.apply();
+
+  // TODO: Needed…?
+  // qthing::power_managment_max_power();
+
+  qthing::enable_ethernet_lan8720();
+
+
+  injector = new SiliconTorch::CyanBusInjector::CyanBusInjector(23, 34, 32, 33);
+
+
+}