hideakitai / ArtNet

Art-Net Sender/Receiver for Arduino (Ethernet, WiFi)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ArtNet

Art-Net Sender/Receiver for Arduino (Ethernet, WiFi)

Warning

Breaking API changes from v0.4.0 and above

Warning

Dependent libraries removed from v0.3.0

If you have already installed this library before v0.3.0, please follow:

  • Cloned from GitHub (manually): Please install dependent libraries manually
  • Installed from library manager: re-install this library from library manager
    • Dependent libraries will be installed automatically

Feature

  • Supports following protocols:
    • ArtDmx
    • ArtPoll/ArtPollReply
    • ArtTrigger
    • ArtSync
  • Supports multiple WiFi/Ethernet libraries
    • WiFi
    • WiFiNINA
    • WiFiS3 (Arduino Uno R4 WiFi)
    • Ethernet
    • EthernetENC
    • ETH (ESP32)
  • Supports a lot of boards which can use Ethernet or WiFi
  • Multiple receiver callbacks depending on universe
  • Mutilple destination streaming with sender
  • One-line send to desired destination
  • Flexible net/subnet/universe setting
  • Easy data forwarding to FastLED

Supported Platforms

WiFi

  • ESP32
  • ESP8266
  • Raspberry Pi Pico W
  • Arduino Uno WiFi Rev2
  • Arduino Uno R4 WiFi
  • Arduino MKR VIDOR 4000
  • Arduino MKR WiFi 1010
  • Arduino MKR WiFi 1000
  • Arduino Nano 33 IoT

Ethernet

  • ESP32 (Ethernet and ETH)
  • ESP8266
  • Almost all platforms without WiFi
  • Any platform supported by ENC28J60 (please read following section)
Notes for ENC28J60 ethernet controller (click to expand)

When using the ENC28J60 controller

  • make sure to clone the EthernetENC library (version =< 2.0.4 doesn't support MAC address)
  • simply replace #include <Artnet.h> with #include <ArtnetEtherENC.h>

Usage

This library has following Art-Net controller options. Please use them depending on the situation.

  • ArtnetReveiver
  • ArtnetSender
  • Artnet (Integrated Sender/Receiver)

Include Artnet

Please include #include "Artnet.h first.

If you use the board which has both WiFi and Ethernet, you can't use #include <Artnet.h>. Please replace it with #include <ArtnetWiFi.h> or #include <ArtnetEther.h> depending on the interface you want to use.

// For the boards which can use ether WiFi or Ethernet
#include <Artnet.h>
// OR use WiFi on the board which can use both WiFi and Ethernet
#include <ArtnetWiFi.h>
// OR use Ethenet on the board which can use both WiFi and Ethernet
#include <ArtnetEther.h>

ArtnetReceiver

#include <Artnet.h>
ArtnetReceiver artnet;

void callback(const uint8_t *data, uint16_t size, const ArtDmxMetadata &metadata, const ArtNetRemoteInfo &remote) {
    // you can also use pre-defined callbacks
}

void setup() {
    // setup Ethernet/WiFi...

    artnet.begin(); // waiting for Art-Net in default port

    artnet.subscribeArtDmxUniverse(universe15bit, [&](const uint8_t *data, uint16_t size, const ArtDmxMetadata &metadata, const ArtNetRemoteInfo &remote) {
        // if Artnet packet comes to this universe(0-15), this function is called
    });

    // you can also use pre-defined callbacks
    artnet.subscribeArtDmxUniverse(net, subnet, universe, callback);
}

void loop() {
    artnet.parse(); // check if artnet packet has come and execute callback
}

ArtnetSender

#include <Artnet.h>
ArtnetSender artnet;

void setup() {
    // setup Ethernet/WiFi...

    artnet.begin();
}

void loop() {
    // change send data as you want

    // one-line send
    artnet.sendArtDmx("127.0.0.1", universe15bit, data_ptr, size);
    // or you can set net and subnet
    // artnet.sendArtDmx("127.0.0.1", net, subnet, universe, data_ptr, size);

    // To use streamArtDmxTo(), you need to setArtDmxData() before streamArtDmxTo()
    artnet.setArtDmxData(data_ptr, size);
    // automatically send set data in 40fps
    artnet.streamArtDmxTo("127.0.0.1", universe15bit);
    // or you can set net and subnet here
    // artnet.streamArtDmxTo("127.0.0.1", net, subnet, universe);
}

Artnet (Integrated Sender/Receiver)

ArtNet class has ArtNetReceiver and ArtNetSender features.

#include <Artnet.h>
Artnet artnet;

void setup()
{
    // setup Ethernet/WiFi...

    artnet.begin(); // send to localhost and listen to default port

    artnet.subscribeArtDmxUniverse(universe, [&](const uint8_t *data, uint16_t size, const ArtDmxMetadata &metadata, const ArtNetRemoteInfo &remote) {
        // if Artnet packet comes to this universe, this function is called
    });
    artnet.subscribeArtDmx([&](const uint8_t *data, uint16_t size, const ArtDmxMetadata& metadata, const ArtNetRemoteInfo& remote) {
        // if Artnet packet comes, this function is called for every universe
    });
}

void loop() {
    artnet.parse(); // check if artnet packet has come and execute callback

    // change send data as you want

    artnet.send("127.0.0.1", universe, data_ptr, size); // one-line send

    artnet.streaming_data(data_ptr, size);
    artnet.streaming("127.0.0.1", universe); // stream in 40 fps
}

Artnet Receiver + FastLED

#include <Artnet.h>
ArtnetReceiver artnet;

// FastLED
#define NUM_LEDS 1
CRGB leds[NUM_LEDS];
const uint8_t PIN_LED_DATA = 3;

void setup() {
    // setup Ethernet/WiFi...

    // setup FastLED
    FastLED.addLeds<NEOPIXEL, PIN_LED>(&leds, NUM_LEDS);

    artnet.begin();
    // if Artnet packet comes to this universe, forward them to fastled directly
    artnet.forwardArtDmxDataToFastLED(universe, leds, NUM_LEDS);

    // this can be achieved manually as follows
    // artnet.subscribeArtDmxUniverse(universe, [](const uint8_t *data, uint16_t size, const ArtDmxMetadata& metadata, const ArtNetRemoteInfo& remote)
    // {
    //     // artnet data size per packet is 512 max
    //     // so there is max 170 pixel per packet (per universe)
    //     for (size_t pixel = 0; pixel < NUM_LEDS; ++pixel)
    //     {
    //         size_t idx = pixel * 3;
    //         leds[pixel].r = data[idx + 0];
    //         leds[pixel].g = data[idx + 1];
    //         leds[pixel].b = data[idx + 2];
    //     }
    // });
}

void loop() {
    artnet.parse(); // check if artnet packet has come and execute callback
    FastLED.show();
}

Other Configurations

Subscribing Callbacks with Net, Sub-Net and Universe as you like

  • The relationship of Net (0-127), Sub-Net (0-15), 4-bit Universe (0-15) and 15-bit Universe (0-32767) is universe15bit = (net << 8) | (subnet << 4) | universe4bit
  • You can subscribe ArtDmx data for Net (0-127), Sub-Net (0-15), and 4-bit Universe (0-15) like artnet.subscribeArtDmxUniverse(net, subnet, universe, callback)
  • Or you can use 15-bit Universe (0-32767) can be set lnke artnet.subscribeArtDmxUniverse(universe, callback)
  • Subscribed universes (targets of the callbacks) are automatically reflected to net_sw sub_sw sw_in in ArtPollreply

ArtPollReply Configuration

  • This library supports ArtPoll and ArtPollReply
  • ArtPoll is automatically parsed and sends ArtPollReply
  • You can configure the following information of by setArtPollReplyConfig()
  • Other settings are set automatically based on registerd callbacks
  • Please refer here for more information
struct ArtPollReplyMetadata
{
    uint16_t oem {0x00FF};      // OemUnknown https://github.com/tobiasebsen/ArtNode/blob/master/src/Art-NetOemCodes.h
    uint16_t esta_man {0x0000}; // ESTA manufacturer code
    uint8_t status1 {0x00};     // Unknown / Normal
    uint8_t status2 {0x08};     // sACN capable
    String short_name {"Arduino ArtNet"};
    String long_name {"Ardino ArtNet Protocol by hideakitai/ArtNet"};
    String node_report {""};
};

ArtTrigger

You can send/subscribe ArtTrigger using the follwing APIs. Please refer here for more information.

void sendArtTrigger(const String& ip, uint16_t oem = 0, uint8_t key = 0, uint8_t subkey = 0, const uint8_t *payload = nullptr, uint16_t size = 512);
void subscribeArtTrigger(const ArtTriggerCallback &func);
using ArtTriggerCallback = std::function<void(const ArtTriggerMetadata &metadata, const ArtNetRemoteInfo &remote)>;

ArtSync

You can send/subscribe ArtSync using the follwing APIs. Please refer here for more information.

void sendArtSync(const String& ip);
void subscribeArtSync(const ArtSyncCallback &func);
using ArtSyncCallback = std::function<void(const ArtNetRemoteInfo &remote)>;

APIs

ArtnetSender

// streaming artdmx packet
void setArtDmxData(const uint8_t* const data, uint16_t size);
void setArtDmxData(uint16_t ch, uint8_t data);
void streamArtDmxTo(const String& ip, uint16_t universe15bit);
void streamArtDmxTo(const String& ip, uint8_t net, uint8_t subnet, uint8_t universe);
void streamArtDmxTo(const String& ip, uint8_t net, uint8_t subnet, uint8_t universe, uint8_t physical);
// one-line artdmx sender
void sendArtDmx(const String& ip, uint16_t universe15bit, const uint8_t* const data, uint16_t size);
void sendArtDmx(const String& ip, uint8_t net, uint8_t subnet, uint8_t universe, const uint8_t* const data, uint16_t size);
void sendArtDmx(const String& ip, uint8_t net, uint8_t subnet, uint8_t universe, uint8_t physical, const uint8_t *data, uint16_t size);
// send other packets
void sendArtTrigger(const String& ip, uint16_t oem = 0, uint8_t key = 0, uint8_t subkey = 0, const uint8_t *payload = nullptr, uint16_t size = 512);
void sendArtSync(const String& ip);

ArtnetReceiver

using ArtDmxCallback = std::function<void(const uint8_t *data, uint16_t size, const ArtDmxMetadata &metadata, const ArtNetRemoteInfo &remote)>;
using ArtSyncCallback = std::function<void(const ArtNetRemoteInfo &remote)>;
using ArtTriggerCallback = std::function<void(const ArtTriggerMetadata &metadata, const RemoteInfo &remote)>;
struct ArtNetRemoteInfo
{
    IPAddress ip;
    uint16_t port;
};

struct ArtDmxMetadata
{
    uint8_t sequence;
    uint8_t physical;
    uint8_t net;
    uint8_t subnet;
    uint8_t universe;
};
OpCode parse()
// subscribe artdmx packet for specified net, subnet, and universe
void subscribeArtDmxUniverse(uint8_t net, uint8_t subnet, uint8_t universe, const ArtDmxCallback &func);
// subscribe artdmx packet for specified universe (15 bit)
void subscribeArtDmxUniverse(uint16_t universe, const ArtDmxCallback &func);
// subscribe artdmx packet for all universes
void subscribeArtDmx(const ArtDmxCallback &func);
// subscribe other packets
void subscribeArtSync(const ArtSyncCallback &func);
void subscribeArtTrigger(const ArtTriggerCallback &func);
// unsubscribe callbacks
void unsubscribeArtDmxUniverse(uint8_t net, uint8_t subnet, uint8_t universe);
void unsubscribeArtDmxUniverse(uint16_t universe);
void unsubscribeArtDmxUniverses();
void unsubscribeArtDmx();
void unsubscribeArtSync();
void unsubscribeArtTrigger();
// set artdmx data to CRGB (FastLED) directly
void forwardArtDmxDataToFastLED(uint8_t net, uint8_t subnet, uint8_t universe, CRGB* leds, uint16_t num);
void forwardArtDmxDataToFastLED(uint16_t universe, CRGB* leds, uint16_t num);
// set information for artpollreply
// https://art-net.org.uk/how-it-works/discovery-packets/artpollreply/
void setArtPollReplyConfig(uint16_t oem, uint16_t esta_man, uint8_t status1, uint8_t status2, const String &short_name, const String &long_name, const String &node_report);
// others
void verbose(bool b);

Note

Some boards without enough memory (e.g. Uno, Nano, etc.) may not be able to use integrated sender/receiver because of the lack of enough memory. Please consider to use more powerful board or to use only sender OR receiver.

Reference

Dependent Libraries

Embedded Libraries

License

MIT

About

Art-Net Sender/Receiver for Arduino (Ethernet, WiFi)

License:MIT License


Languages

Language:C++ 89.0%Language:C 11.0%