rstephan / ArtnetWifi

Arduino library for Art-Net (artnet) over WiFi, send and receive DMX data. Runs on ESP8266, ESP32, Pi Pico W, WiFi101 and WiFiNINA devices.
Other
353 stars 59 forks source link

Latency When Writing to 620 LEDs (1860 Channels) #31

Open smcd253 opened 3 years ago

smcd253 commented 3 years ago

Using 5 universes ( i know could be less but the way my fixtures are set up makes 5 universes easier). Using Adafruit NeoPixel as my LED driver. Writing out of GPIO3 (Rx). Board: Nodemcu 1.0 ESP12E

I've been experiencing pretty drastic latency with this setup, but this makes no sense given the refresh time for NeoPixel is 30ms for 1000LEDs as is described in this article.

I've simplified onDmxFrame() as follows:

void onDmxFrame(uint16_t universe, uint16_t length, uint8_t sequence, uint8_t* data)
{
  // Serial.printf("Universe = %u | Length = %u | Sequence = %u | Data[0] = %u\n", 
  //               universe, length, sequence, data[0]);
  for (int i = 0; i < num_universes; i++) {
    if (universe == universes[i]) {
      int k = 0;
      for (int j = start_pixel[i]; j < start_pixel[i] + leds_per_universe[i]; j++) {
        int l = k * 3;
        leds.setPixelColor(j, data[l], data[l + 1], data[l + 2]);
        k++;      
      }
    }
  }
  leds.show();
}

Here are the relevant definitions as well:

IPAddress ip(192,168,1,109);
const int num_universes = 5;
const int universes[num_universes] = {11, 12, 13, 14, 15};
const int leds_per_universe[num_universes] = {138, 137, 138, 138, 69};
const int start_pixel[num_universes] = {0, 138, 275, 413, 521};   
const int numLeds = 620;
const int data_pin = 3;

I guess I could hash the universe matching but i don't think that's the issue. I'm thinking it's because the Artnet packets are being dropped when the esp is stuck in onDmxFrame(). I found an interrupt-based (async) sACN library that solved this issue, but my visualizer program only supports artnet.

I have 9 strips all being powered in parallel by a 5v/10a power supply with 16AWG wiring, so no voltage drop to contribute to signal loss. The data line snakes through the setup with the 22AWG wire that is standard for the ws2812b. The lag isuniversal for the whole setup, though, so i don't think this is the issue.

I'm unicasting packets for each universe using Resolume at 30 fps. My computer is also hard-wired in, so the only considerable network latency is between the router and the node. I can also unicast to 7+ nodes with no drop in performance.

I have a feeling there's a way to make this many LEDs possible with the esp8266, but I can't see any readily available solutions. Would love any tips!

Here's a link to the client code for more detail.

rstephan commented 3 years ago

I see some improvements for you.

  1. Move the leds.show() two lines up. Inside the if-statement. Don't update the LEDs on every frame, only if they match your universe-filter.
  2. 1860 Channels take roughly 60ms by my calculations. Keep in mind that 30fps are only 33.3ms time in between two "frames". This way you can only achieve about 16fps on the LEDs. This is the theoretical upper limit.
  3. The implementation above has some problems too, even with my correction from point 1. leds.show() is called on every universe. That is 5x60ms equals 300ms! About 3fps.
  4. Update the LEDs only on the last received universe. Writing to the LEDs takes time. The setPixelColor() call is fast. This solution assumes the 5 universes are send/received basically with no gap, an a "long" time after the last one.

These are my first tips. If it doesn't help come back and ask again.

smcd253 commented 3 years ago

Good points! I'll try them out and will let you know what I find.