hideakitai / ArtNet

Art-Net Sender/Receiver for Arduino (Ethernet, WiFi)
MIT License
257 stars 52 forks source link

Long delay after large amount of packets (WiFi) #71

Closed marf41 closed 1 year ago

marf41 commented 1 year ago

Good day. I am trying to use this lib to convert from Art-Net to DMX and FastLED. I am using Chamsys MagicQ as Art-Net source, and WS32-ETH01 as node. If rate of changes is slow (few per second), all is working okay. But if I add an effect, which is updating multiple times per second, they delay from change in controller to change on ESP32 takes multiple seconds, sometimes even as long as 10 seconds. This problem exists on WiFi and Ethernet. I suspect the buffer is filling up, and the library can't parse them fast enough. Are there any tips, or workarounds? Thank you in advance.

hideakitai commented 1 year ago

Hi, could you give me a minimal code that can reproduce the problem based on this example?

marf41 commented 1 year ago

Thank you for quick reply! After retesting with minimal code, and checking network connections, I have to admit I was wrong - wired variant works flawlessly, problem exists only on WiFi connection.

Code I am currently trying:

#include <FastLED.h>
#include <ArtnetWiFi.h>
const IPAddress ip(192, 168, 0, 11);
const IPAddress gateway(192, 168, 0, 1);
const IPAddress subnet(255, 255, 255, 0);

ArtnetWiFiReceiver artnet;
CRGB leds[1];

void callback(const uint8_t* data, const uint16_t size) {
    if (size < 4) { Serial.println("Packet too small."); return; }
    leds[0].setRGB(data[0], data[1], data[2]);
    Serial.println();
    Serial.print(millis());
    Serial.print(": ");
    Serial.print(data[0]);
    Serial.print(", ");
    Serial.print(data[1]);
    Serial.print(", ");
    Serial.print(data[2]);
    Serial.print(", ");
    Serial.print(data[3]);
    Serial.println();
    FastLED.show();
}

void setup() {
    Serial.begin(115200);
    Serial.println("PWR ON");
    WiFi.begin("ssid", "pass");
    WiFi.config(ip, gateway, subnet);
    while (WiFi.status() != WL_CONNECTED) {
        Serial.print(".");
        delay(500);
    }
    Serial.print("WiFi connected, IP = ");
    Serial.println(WiFi.localIP());
    artnet.begin();
    FastLED.addLeds<NEOPIXEL, 15>(leds, 1);
    leds[1] = CRGB::Red;
    artnet.subscribe(1, callback);
}

void loop() {
    artnet.parse();
    if ((millis() % 100) == 0) { Serial.print("."); }
}

After a few seconds with quick effect (speed set to 0.01s), delay between clearing effect and LEDs turning off is about eight seconds. On wired, difference in millis output in callback was constant 30 ms on quick effect, on WiFi it is 10 ms, then 100 ms, then 10 ms again, and so on... Also, in MagicQ's Net Manager, WiFi version is constantly disappearing and reappearing in Art-Net node table. Wired version is there all the time.

hideakitai commented 1 year ago

The ArtNet WiFi receiver implementation is almost the same as the Ethernet one. So I think the problem may be in your environment or code. I recommend testing it again in a clean local network (access point with only ArtNet controller and your device).

Also please try to adjust your code:

By the way, I think ArtNet's default update rate is 40 fps (25 ms).

marf41 commented 1 year ago

Even after switching to another, more powerful router, where PC and ESP are alone, the problem still persists. WiFi version has 8-10 second delay, wired version works without problems. Sorry for mistake in the code, the night was late, and I wanted to see the timings. Current code at ESP:

#include <FastLED.h>
#include <ArtnetWiFi.h>
const IPAddress ip(192, 168, 1, 11);
const IPAddress gateway(192, 168, 1, 1);
const IPAddress subnet(255, 255, 255, 0);

ArtnetWiFiReceiver artnet;
CRGB leds[1];

void callback(const uint8_t* data, const uint16_t size) {
    leds[0].setRGB(data[0], data[1], data[2]);
}

void setup() {
    Serial.begin(115200);
    Serial.println("PWR ON");
    WiFi.begin("ssid", "pass");
    WiFi.config(ip, gateway, subnet);
    while (WiFi.status() != WL_CONNECTED) {
        Serial.print(".");
        delay(500);
    }
    Serial.print("WiFi connected, IP = ");
    Serial.println(WiFi.localIP());
    artnet.begin();
    FastLED.addLeds<NEOPIXEL, 15>(leds, 1);
    leds[0] = CRGB::Red;
    artnet.subscribe(1, callback);
}

void loop() {
    artnet.parse();
    FastLED.show();
}

By the way, I think ArtNet's default update rate is 40 fps (25 ms).

Art-Net protocol only limits max rate at 44 Hz ("the maximum refresh rate that can be achieved on the DMX512-A physical layer with a full 512 channel (data slot) payload"). The actual refresh rate is controller-dependant. For MagicQ, it is 39 Hz.

hideakitai commented 1 year ago

Where does the delay exist? Receiving the packet itself? Or between receiving a packet and calling a callback? You can see it by inserting Serial.println() around here

https://github.com/hideakitai/ArtNet/blob/f0cd567fb36f76d74077056e44181ab31b2af5e7/Artnet/ArtnetCommon.h#L298-L303

Like:

            const size_t size = stream->parsePacket();
            if (size == 0) return OpCode::NA;

            Serial.print("Received packet at ");
            Serial.println(millis());

            uint8_t* d = new uint8_t[size];
            stream->read(d, size);

Also, you can see the delay between receiving a packet and the callback by inserting Serial.println() as you did before in your callback.

marf41 commented 1 year ago

Sorry for late reply. No delay between the print at parse and at callback (two values at parse are before and after stream->read).

Reading stream 31665 31665
Callback 0 31665

Delay of few seconds exists even between closing the MagicQ and the last "Reading stream" message. This suggests the problem may be in the arduino-esp32 code, or the ESP32 itself?

hideakitai commented 1 year ago

A possibility lies on:

  1. MagicQ WiFi Configuration
  2. WiFi AP Configuration
  3. esp-idf/arduino-esp32 code

I think 3 is not a cause of this issue. Because it works fine in my environment. Please try to configure your environment correctly. I'm closing this issue, but if you still need help, it's ok to continue your question.