From 1a7d6a81d3f0e41a537cea14da81cd07c10f5a88 Mon Sep 17 00:00:00 2001 From: Hideaki Tai Date: Wed, 31 Jan 2024 09:02:12 +0900 Subject: [PATCH] feat: support send/receive art-sync --- Artnet/ArtSync.h | 36 ++++++++++++++++++++++++++++++++++++ Artnet/Common.h | 1 + Artnet/Receiver.h | 17 +++++++++++++++++ Artnet/Sender.h | 7 +++++++ README.md | 14 ++++++++++++++ 5 files changed, 75 insertions(+) create mode 100644 Artnet/ArtSync.h diff --git a/Artnet/ArtSync.h b/Artnet/ArtSync.h new file mode 100644 index 0000000..6374ca2 --- /dev/null +++ b/Artnet/ArtSync.h @@ -0,0 +1,36 @@ +#pragma once +#ifndef ARTNET_ART_SYNC_H +#define ARTNET_ART_SYNC_H + +#include "Common.h" +#include +#include + +namespace art_net { +namespace art_sync { + +enum Index : uint16_t { + ID = 0, + OP_CODE_L = 8, + OP_CODE_H = 9, + PROTOCOL_VER_H = 10, + PROTOCOL_VER_L = 11, + AUX1 = 12, + AUX2 = 13, +}; + +inline void set_header(uint8_t *packet) +{ + for (size_t i = 0; i < ID_LENGTH; i++) packet[i] = static_cast(ARTNET_ID[i]); + packet[OP_CODE_L] = (static_cast(OpCode::Sync) >> 0) & 0x00FF; + packet[OP_CODE_H] = (static_cast(OpCode::Sync) >> 8) & 0x00FF; + packet[PROTOCOL_VER_H] = (PROTOCOL_VER >> 8) & 0x00FF; + packet[PROTOCOL_VER_L] = (PROTOCOL_VER >> 0) & 0x00FF; + packet[AUX1] = 0; + packet[AUX2] = 0; +} + +} // namespace art_sync +} // namespace art_net + +#endif // ARTNET_ART_SYNC_H diff --git a/Artnet/Common.h b/Artnet/Common.h index 2e0dce9..7631638 100644 --- a/Artnet/Common.h +++ b/Artnet/Common.h @@ -64,6 +64,7 @@ constexpr uint16_t PACKET_SIZE {530}; using CallbackAllType = std::function; using CallbackType = std::function; +using CallbackArtSync = std::function; #if ARX_HAVE_LIBSTDCPLUSPLUS >= 201103L // Have libstdc++11 template diff --git a/Artnet/Receiver.h b/Artnet/Receiver.h index 77f88a8..ea2ca5e 100644 --- a/Artnet/Receiver.h +++ b/Artnet/Receiver.h @@ -17,6 +17,7 @@ class Receiver_ { uint8_t sub_switch; // subnet of universe CallbackMap callbacks; CallbackAllType callback_all; + CallbackArtSync callback_artsync; S* stream; bool b_verbose {false}; artpollreply::ArtPollReply artpollreply_ctx; @@ -71,6 +72,11 @@ class Receiver_ { op_code = OpCode::Poll; break; } + case OpCode::Sync: { + if (callback_artsync) callback_artsync(); + op_code = OpCode::Sync; + break; + } default: { if (b_verbose) { Serial.print(F("Unsupported OpCode: ")); @@ -178,6 +184,14 @@ class Receiver_ { inline auto subscribe(F* func) -> std::enable_if_t::value> { callback_all = arx::function_traits::cast(func); } + template + inline auto subscribeArtsync(F&& func) -> std::enable_if_t::value> { + callback_artsync = arx::function_traits::cast(func); + } + template + inline auto subscribeArtsync(F* func) -> std::enable_if_t::value> { + callback_artsync = arx::function_traits::cast(func); + } inline void unsubscribe(const uint8_t universe) { auto it = callbacks.find(universe); @@ -186,6 +200,9 @@ class Receiver_ { inline void unsubscribe() { callback_all = nullptr; } + inline void unsubscribeArtSync() { + callback_artsync = nullptr; + } inline void clear_subscribers() { unsubscribe(); diff --git a/Artnet/Sender.h b/Artnet/Sender.h index bb6f6e5..49b4a61 100644 --- a/Artnet/Sender.h +++ b/Artnet/Sender.h @@ -5,6 +5,7 @@ #include "Common.h" #include "ArtDmx.h" #include "ArtTrigger.h" +#include "ArtSync.h" namespace art_net { @@ -100,6 +101,12 @@ class Sender_ { send_raw(ip, DEFAULT_PORT, packet.data(), packet.size()); } + // ArtSync + void sync(const String& ip) { + art_sync::set_header(packet.data()); + send_raw(ip, DEFAULT_PORT, packet.data(), packet.size()); + } + protected: void attach(S& s) { stream = &s; diff --git a/README.md b/README.md index ca0cab0..08d9c94 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,11 @@ If you have already installed this library, please follow: - One-line send to desired destination - Flexible net/subnet/universe setting - Easy data forwarding to [FastLED](https://github.com/FastLED/FastLED) +- Supports following protocols: + - ArtDmx + - ArtPoll/ArtPollReply + - ArtTrigger + - ArtSync ## Supported Platforms @@ -284,6 +289,8 @@ void set_subkey(uint8_t subkey); void set_payload(const uint8_t* const payload, uint16_t size); // send ArtTrigger based on the config above void trigger(const String& ip); +// send ArtSync +void sync(const String& ip); ``` ### ArtnetReceiver @@ -295,12 +302,19 @@ template inline auto subscribe(const uint8_t universe, F&& func); template inline auto subscribe(const uint8_t universe, F* func); template inline auto subscribe(F&& func); template inline auto subscribe(F* func); +template inline auto subscribeArtsync(F&& func); +template inline auto subscribeArtsync(F* func); +// callback definitions for subscribers +using CallbackAllType = std::function; +using CallbackType = std::function; +using CallbackArtSync = std::function; // for FastLED inline void forward(const uint8_t universe, CRGB* leds, const uint16_t num); // unsubscribe inline void unsubscribe(const uint8_t universe); inline void unsubscribe(); inline void clear_subscribers(); +inline void unsubscribeArtSync(); // ArtPollReply information void shortname(const String& sn); void longname(const String& ln);