including ArtNet feature from different Project
This commit is contained in:
+140
-10
@@ -35,6 +35,8 @@
|
||||
#include "cliWrapper.hpp"
|
||||
#include "udpSockets.hpp"
|
||||
#include "tcpSockets.hpp"
|
||||
#include "Queue.hpp"
|
||||
#include "Artnet.h"
|
||||
|
||||
static const char *TAG = "Watch";
|
||||
static esp_eth_handle_t s_eth_handle = NULL;
|
||||
@@ -44,6 +46,35 @@ extern "C" { // This switch allows the ROS C-implementation to find this main
|
||||
void app_main(void);
|
||||
}
|
||||
|
||||
struct Color {
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
};
|
||||
|
||||
struct DeviceState {
|
||||
int jumps;
|
||||
int pictogram;
|
||||
int profile;
|
||||
float speed = 1.0; // Rad/sec
|
||||
float accel = 1.0; // Rad/sec^2
|
||||
Color color{16, 16, 16};
|
||||
};
|
||||
|
||||
DeviceState activeState;
|
||||
enum class MoveType {
|
||||
Step,
|
||||
AllPictograms,
|
||||
Arbitrary,
|
||||
};
|
||||
struct MoveCommand {
|
||||
MoveType type;
|
||||
uint8_t deltaPic;
|
||||
uint8_t profile;
|
||||
Color color;
|
||||
};
|
||||
static fos::Queue<MoveCommand> commandQueue(8);
|
||||
|
||||
|
||||
std::unique_ptr<Cli> shellPtr;
|
||||
|
||||
@@ -117,24 +148,123 @@ static void telnetSocketTask(int addrFamily) {
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
|
||||
constexpr uint32_t DmxUniverse = 0;
|
||||
constexpr int DmxChannelCount = 9; //
|
||||
|
||||
uint8_t scaledRgbChannel(uint8_t value, float scale) {
|
||||
return static_cast<uint8_t>(value * scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Callback for ArtNet DMX-socket. Does not send data only updates the image
|
||||
*
|
||||
* @param data Pointer to dmx-values
|
||||
* @param size length of dmx-values
|
||||
*/
|
||||
static void UniverseCallback(const uint8_t *data, const uint16_t size) {
|
||||
int len = std::min(static_cast<int>(size), DmxChannelCount);
|
||||
ESP_LOGD(TAG, "Got DMX");
|
||||
ESP_LOG_BUFFER_HEXDUMP("DMX", data, len, ESP_LOG_DEBUG);
|
||||
Syslog::logv(Syslog::Severity::Debug, "Got DMX: r%0x g%0x b%0x i%0x trig%i j%i p%i a%i w%i",
|
||||
data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8]);
|
||||
|
||||
float intens = (float)data[3] / UINT8_MAX;
|
||||
// activeState.color = Color{
|
||||
// scaledRgbChannel(data[0], intens),
|
||||
// scaledRgbChannel(data[1], intens),
|
||||
// scaledRgbChannel(data[2], intens),
|
||||
// 0};
|
||||
|
||||
static uint8_t lastTrig = 0;
|
||||
uint8_t thisTrig = data[4];
|
||||
if (thisTrig == lastTrig) {
|
||||
return;
|
||||
}
|
||||
lastTrig = thisTrig;
|
||||
uint8_t jumps = data[5];
|
||||
activeState.jumps = jumps;
|
||||
uint8_t profile = data[6];
|
||||
uint8_t accel = data[7];
|
||||
uint8_t velo = data[8];
|
||||
activeState.accel = (float)accel / 100 + 0.5; // min .5 / max 3
|
||||
activeState.speed = (float)velo / 100 + 0.5; // min .5 / max 3
|
||||
activeState.profile = profile;
|
||||
|
||||
Syslog::logv(Syslog::Severity::Notice, "Command detected step=%i prof=%i accel=%.1f velo=%.1f", jumps, profile, activeState.accel, activeState.speed);
|
||||
commandQueue.enqueue(std::make_unique<MoveCommand>(MoveType::Step, jumps, profile, activeState.color));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMX-Socket for ArtNet TCP/IP
|
||||
*
|
||||
* @details Tested with [Q Light Controller+](https://www.qlcplus.org/)
|
||||
* @param args ignored task argument
|
||||
*/
|
||||
static void dmxSocketSenderTask(UdpSocket &socket) {
|
||||
try {
|
||||
ArtnetSender artnet(socket);
|
||||
std::array<uint8_t, 16> data;
|
||||
while (socket.isActive()) {
|
||||
data[0]++;
|
||||
artnet.send("", 0, data.data(), data.size());
|
||||
fos::Task::delayMs(500);
|
||||
}
|
||||
|
||||
} catch (const std::exception &e) {
|
||||
ESP_LOGE("UDP", "%s", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMX-Socket for ArtNet TCP/IP
|
||||
*
|
||||
* @details Tested with [Q Light Controller+](https://www.qlcplus.org/)
|
||||
* @param args ignored task argument
|
||||
*/
|
||||
static void dmxSocketTask(int addrFamily) {
|
||||
|
||||
ESP_LOGI(TAG, "Starting ArtNet task");
|
||||
constexpr uint16_t ArtNetPort = arx::artnet::DEFAULT_PORT;
|
||||
IpAdr address = addrFamily == AF_INET ? IpAdr(INADDR_ANY, ArtNetPort) : IpAdr(ArtNetPort);
|
||||
|
||||
try {
|
||||
while (true) {
|
||||
UdpSocket socket(address);
|
||||
socket.bindTo();
|
||||
|
||||
ArtnetReceiver artnet(socket);
|
||||
artnet.subscribe(DmxUniverse, UniverseCallback);
|
||||
artnet.parse();
|
||||
// auto msg = std::make_unique<Display::Message>(Display::Message::Type::UpdateInfo, "DMX-IP-Mode");
|
||||
// displayEvents.enqueue(std::move(msg));
|
||||
// deviceState.setNewState(DeviceState::Mode::Remote);
|
||||
// xTaskCreate(valueRefresherTask, "valueRefresher", 4096, nullptr, 5, NULL);
|
||||
// static TaskT<UdpSocket &> dmxSender(dmxSocketSenderTask, socket, "dmxSender", 4096);
|
||||
|
||||
// parse artnet as long socket is active, then restart socket
|
||||
while (socket.isActive()) {
|
||||
ESP_LOGD(TAG, "Waiting for data");
|
||||
artnet.parse();
|
||||
// socket.write(data);
|
||||
}
|
||||
// deviceState.fallbackToLast();
|
||||
}
|
||||
|
||||
} catch (const std::exception &e) {
|
||||
ESP_LOGE("UDP", "%s", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
void startServerTasks() {
|
||||
static int ipVersion = AF_INET;
|
||||
static fos::TaskT<int> telnetSocket(telnetSocketTask, ipVersion, "tcpServer", 4096);
|
||||
// static TaskT<int> dmxNode(dmxSocketTask, ipVersion, "dmxNode", 4096);
|
||||
static fos::TaskT<int> dmxNode(dmxSocketTask, ipVersion, "dmxNode", 4096);
|
||||
// static Task otaUpdate(SystemFunctions::OtaTaskEntry, "otaTask", 8192);
|
||||
|
||||
// initialise_mdns();
|
||||
// netbiosns_init();
|
||||
// netbiosns_set_name(CONFIG_EXAMPLE_MDNS_HOST_NAME);
|
||||
// WebServer::init(FileSystem::getInstance());
|
||||
// WebServer::getInstance(FileSystem::getInstance()).registerCallback(printSysState);
|
||||
|
||||
// auto &store = NvsApi::getInstance();
|
||||
// auto broker = store.getValue("mqttBroker");
|
||||
// if (broker != "") {
|
||||
// MqttClient::init(broker);
|
||||
// }
|
||||
|
||||
// auto logger = store.getValue("syslogDst");
|
||||
// if (logger != "") {
|
||||
// Syslog::setupTask(IpAdr{logger, 0});
|
||||
|
||||
Reference in New Issue
Block a user