diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7acdf24..1ece935 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -240,3 +240,81 @@ jobs: - name: ArxTypeTraits - name: FastLED verbose: true + + build-etherenc: + name: "Build Test (EtherENC): ${{matrix.board.arch}}:${{matrix.board.name}}" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + board: + # temporarily disabled due to memory shortage in `sender` example + # - vendor: arduino + # arch: avr + # name: uno + - vendor: arduino + arch: megaavr + name: uno2018 + # temporarily disabled due to FastLED not supporting mkrvidor4000 + # - vendor: arduino + # arch: samd + # name: mkrvidor4000 + - vendor: arduino + arch: samd + name: mkrwifi1010 + - vendor: arduino + arch: samd + name: mkr1000 + - vendor: arduino + arch: samd + name: nano_33_iot + - vendor: esp8266 + arch: esp8266 + name: generic + - vendor: esp32 + arch: esp32 + name: esp32 + - vendor: esp32 + arch: esp32 + name: esp32s3 + - vendor: esp32 + arch: esp32 + name: esp32c3 + - vendor: rp2040 + arch: rp2040 + name: rpipicow + include: + - index: https://downloads.arduino.cc/packages/package_index.json + board: + vendor: arduino + - index: https://arduino.esp8266.com/stable/package_esp8266com_index.json + board: + vendor: esp8266 + - index: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json + board: + vendor: esp32 + - index: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json + board: + vendor: rp2040 + steps: + - uses: actions/checkout@v4 + - name: compile example sketchs + uses: arduino/compile-sketches@v1 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + fqbn: ${{matrix.board.vendor}}:${{matrix.board.arch}}:${{matrix.board.name}} + platforms: | + - name: ${{matrix.board.vendor}}:${{matrix.board.arch}} + source-url: ${{matrix.index}} + sketch-paths: | + - examples/EthernetENC/receive_fastled + - examples/EthernetENC/receiver + - examples/EthernetENC/send_receive + - examples/EthernetENC/sender + libraries: | + - source-path: ./ + - name: ArxContainer + - name: ArxTypeTraits + - name: FastLED + - source-url: https://github.com/JAndrassy/EthernetENC.git + verbose: true diff --git a/Artnet/Receiver.h b/Artnet/Receiver.h index 3b89372..77f88a8 100644 --- a/Artnet/Receiver.h +++ b/Artnet/Receiver.h @@ -319,9 +319,7 @@ class Receiver_ { } template auto macAddress(uint8_t* mac) -> std::enable_if_t::value> { -#ifndef ESP8266 Ethernet.MACAddress(mac); -#endif } #endif // ARTNET_ENABLE_ETHER diff --git a/ArtnetEtherENC.h b/ArtnetEtherENC.h new file mode 100644 index 0000000..8de9e82 --- /dev/null +++ b/ArtnetEtherENC.h @@ -0,0 +1,19 @@ +#pragma once +#ifndef ARTNET_ETHER_H +#define ARTNET_ETHER_H + +#define ARTNET_ENABLE_ETHER + +#include +#include +#include +#include +#include +#include "Artnet/util/TeensyDirtySTLErrorSolution/TeensyDirtySTLErrorSolution.h" +#include "Artnet/Manager.h" + +using Artnet = art_net::Manager; +using ArtnetSender = art_net::Sender; +using ArtnetReceiver = art_net::Receiver; + +#endif // ARTNET_ETHER_H diff --git a/README.md b/README.md index d20bfb2..ca0cab0 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,16 @@ If you have already installed this library, please follow: - 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](https://github.com/JAndrassy/EthernetENC) library (version =< 2.0.4 doesn't support MAC address) +- simply replace `#include ` with `#include ` +
## Usage @@ -201,12 +211,13 @@ void loop() { - You can set Net (0-127) and Sub-Net (0-15) like `artnet.begin(net, subnet)` - Universe (0-15) can be set in `artnet.subscribe(universe, callback)`, -- Callbacks are limited to 4 universes (depending on the spec of Art-Net) - These universes (targets of the callbacks) are reflected to `net_sw` `sub_sw` `sw_in` in `ArtPollreply` automatically +PortTypes, GoodInput/Output, SwIn, etc., are limited to 4 ports. Only the first four ports are reflected if you subscribe to more than four callbacks. + ```C++ artnet.begin(net, subnet); // net and subnet can be set only once -artnet.subscribe(univ1, callback1); // 4 callbacks can be set +artnet.subscribe(univ1, callback1); // callbacks can be set artnet.subscribe(univ2, callback2); // these universes are reported to artnet.subscribe(univ3, callback3); // Art-Net controller if it polls artnet.subscribe(univ4, callback4); // Art-Net devices @@ -215,7 +226,7 @@ artnet.subscribe(univ4, callback4); // Art-Net devices Or you can register callbacks based on 15 bit universe. But these universes are not reflected to `ArtPollReply` automatically. ```C++ -artnet.subscribe15bit(univ15bit1, callback1); // 4 callbacks can be set +artnet.subscribe15bit(univ15bit1, callback1); // callbacks can be set artnet.subscribe15bit(univ15bit2, callback2); // these universes are NOT reported to artnet.subscribe15bit(univ15bit3, callback3); // Art-Net controller if it polls artnet.subscribe15bit(univ15bit4, callback4); // Art-Net devices diff --git a/examples/EthernetENC/receive_fastled/receive_fastled.ino b/examples/EthernetENC/receive_fastled/receive_fastled.ino new file mode 100644 index 0000000..978754e --- /dev/null +++ b/examples/EthernetENC/receive_fastled/receive_fastled.ino @@ -0,0 +1,50 @@ +#include // include FastLED *before* Artnet +#include + + +// Ethernet stuff +const IPAddress ip(192, 168, 0, 201); +uint8_t mac[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB}; + +ArtnetReceiver artnet; +uint8_t universe = 1; // 0 - 15 + +// FastLED +#define NUM_LEDS 1 +CRGB leds[NUM_LEDS]; +const uint8_t PIN_LED_DATA = 3; + +void setup() { + Serial.begin(115200); + delay(2000); + + FastLED.addLeds(leds, NUM_LEDS); + + Ethernet.begin(mac, ip); + artnet.begin(); + // artnet.subscribe_net(0); // optionally you can change + // artnet.subscribe_subnet(0); // optionally you can change + + // if Artnet packet comes to this universe, forward them to fastled directly + artnet.forward(universe, leds, NUM_LEDS); + + // this can be achieved manually as follows + // if Artnet packet comes to this universe, this function is called + // artnet.subscribe(universe, [&](const uint8_t* data, const uint16_t size) + // { + // // set led + // // 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) { + // const 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(); +} diff --git a/examples/EthernetENC/receiver/receiver.ino b/examples/EthernetENC/receiver/receiver.ino new file mode 100644 index 0000000..784d9a7 --- /dev/null +++ b/examples/EthernetENC/receiver/receiver.ino @@ -0,0 +1,44 @@ +#include + + +// Ethernet stuff +const IPAddress ip(192, 168, 0, 201); +uint8_t mac[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB}; + +ArtnetReceiver artnet; +uint32_t universe1 = 1; // 0 - 15 +uint32_t universe2 = 2; // 0 - 15 + +void callback(const uint8_t* data, const uint16_t size) { + // you can also use pre-defined callbacks +} + +void setup() { + Serial.begin(115200); + + Ethernet.begin(mac, ip); + artnet.begin(); + // artnet.subscribe_net(0); // optionally you can change + // artnet.subscribe_subnet(0); // optionally you can change + + // if Artnet packet comes to this universe, this function is called + artnet.subscribe(universe1, [&](const uint8_t* data, const uint16_t size) { + Serial.print("artnet data (universe : "); + Serial.print(universe1); + Serial.print(", size = "); + Serial.print(size); + Serial.print(") :"); + for (size_t i = 0; i < size; ++i) { + Serial.print(data[i]); + Serial.print(","); + } + Serial.println(); + }); + + // you can also use pre-defined callbacks + artnet.subscribe(universe2, callback); +} + +void loop() { + artnet.parse(); // check if artnet packet has come and execute callback +} diff --git a/examples/EthernetENC/send_receive/send_receive.ino b/examples/EthernetENC/send_receive/send_receive.ino new file mode 100644 index 0000000..259e68b --- /dev/null +++ b/examples/EthernetENC/send_receive/send_receive.ino @@ -0,0 +1,62 @@ +#ifdef __AVR__ +#warning THIS EXAMPLE MAY USE TOO MUCH MEMORY FOR AVR. WE RECOMMEND TO USE SENDER OR RECEIVER ONLY. +#endif + +#include + + +// Ethernet stuff +const IPAddress ip(192, 168, 0, 201); +uint8_t mac[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB}; + +Artnet artnet; +const String target_ip = "192.168.0.200"; +uint8_t universe = 1; // 0 - 15 + +const uint16_t size = 512; +uint8_t data[size]; +uint8_t value = 0; + +void setup() { + Serial.begin(115200); + delay(2000); + + Ethernet.begin(mac, ip); + artnet.begin(); + // artnet.begin(net, subnet); // optionally you can change + + Serial.println("set subscriber"); + + // if Artnet packet comes to this universe, this function is called + artnet.subscribe(universe, [](const uint8_t* data, const uint16_t size) { + Serial.print("artnet data (universe : "); + Serial.print(universe); + Serial.print(", size = "); + Serial.print(size); + Serial.print(") :"); + for (size_t i = 0; i < size; ++i) { + Serial.print(data[i]); + Serial.print(","); + } + Serial.println(); + }); + + // if Artnet packet comes, this function is called to every universe + artnet.subscribe([&](const uint32_t univ, const uint8_t* data, const uint16_t size) { + Serial.print("ArtNet data has come to universe: "); + Serial.println(univ); + }); + + Serial.println("start"); +} + +void loop() { + artnet.parse(); // check if artnet packet has come and execute callback + + value = (millis() / 4) % 256; + memset(data, value, size); + + artnet.streaming_data(data, size); + artnet.streaming(target_ip, universe); // automatically send set data in 40fps + // artnet.streaming(target_ip, net, subnet, univ); // or you can set net, subnet, and universe +} diff --git a/examples/EthernetENC/sender/sender.ino b/examples/EthernetENC/sender/sender.ino new file mode 100644 index 0000000..77781a1 --- /dev/null +++ b/examples/EthernetENC/sender/sender.ino @@ -0,0 +1,37 @@ +#include + + +// Ethernet stuff +const IPAddress ip(192, 168, 0, 201); +uint8_t mac[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB}; + +ArtnetSender artnet; +const String target_ip = "192.168.0.200"; +uint32_t universe = 1; + +const uint16_t size = 512; +uint8_t data[size]; +uint8_t value = 0; + +void setup() { + Serial.begin(115200); + delay(2000); + + Ethernet.begin(mac, ip); + artnet.begin(); + // artnet.begin(net, subnet); // optionally you can change + + Serial.println("start"); +#ifdef UDP_TX_PACKET_MAX_SIZE + Serial.println(UDP_TX_PACKET_MAX_SIZE); +#endif +} + +void loop() { + value = (millis() / 4) % 256; + memset(data, value, size); + + artnet.streaming_data(data, size); + artnet.streaming(target_ip, universe); // automatically send set data in 40fps + // artnet.streaming(target_ip, net, subnet, univ); // or you can set net, subnet, and universe +}