Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LED Panels Only Receiving Broadcast Artnet #52

Open
aminakirby opened this issue Jul 1, 2023 · 1 comment
Open

LED Panels Only Receiving Broadcast Artnet #52

aminakirby opened this issue Jul 1, 2023 · 1 comment

Comments

@aminakirby
Copy link

aminakirby commented Jul 1, 2023

Hi there- thanks much for putting together this library!

I'm working on a project that uses 8 32 x 32 RGB LED panels; so in total about 65 universes. Each LED panel has it's own ESP8266 that is running the ArtnetWifi library. All the panels are tied to a router in AP mode- my laptop which runs MadMapper is connected to the AP through a managed network switch. When all panels are running and complex light changes are happening I sometimes get some panels lagging behind- however overall they're fairly stable if I output unicast Artnet to them from MadMapper.

I've been troubleshooting some of the lag issues to see if I could get it cleaned up a bit. I recently used Wireshark to monitor the network traffic while sending Artnet to the panels from my laptop, and see a ton of ArtSync packets being sent over the broadcast IP, but I don't see any of the ArtDMX I'm assuming I should be seeing sent to individual panels. The panels are definitely receiving packets, as they're lighting up, but I'm not seeing it in Wireshark.

Is there something I'm missing that is causing the Artnet packets to be sent as broadcast rather than unicast? I've included my code below. Any suggestions on how to cut down the lag even further when using a lot of universes is much appreciated!

Thanks,
Amina

#include <ArtnetWifi.h>
#include <Arduino.h>

#include <Adafruit_BusIO_Register.h>
#include <Adafruit_I2CDevice.h>
#include <Adafruit_I2CRegister.h>
#include <Adafruit_SPIDevice.h>
#include <PxMatrix.h>

#include <Ticker.h>
Ticker display_ticker;
#define P_LAT 16
#define P_A 5
#define P_B 4
#define P_C 15
#define P_D 12
#define P_E 0
#define P_OE 2

#define matrix_width 32
#define matrix_height 32                                    //Adjust as needed based on display size.

// Display settings
const uint8_t panelNumber = 7;                              //Number of LED matrix panel in array of panels. Added mostly for convenience to alter startUniverse and last octect of IP address with 1 variable.
const uint8_t scan_rate = 16;                               //8 for 1/8, 16 for 1/16, 32 for 1/32.
uint8_t display_draw_time = 30;                             //30-70 is usually fine
//PxMATRIX display(32,16,P_LAT,P_OE,P_A,P_B,P_C);           //Enable for 1/8 scan.
PxMATRIX display(32,32,P_LAT,P_OE,P_A,P_B,P_C,P_D);         //Enable for 1/16 scan.
//PxMATRIX display(32,32,P_LAT,P_OE,P_A,P_B,P_C,P_D,P_E);   //Enable for 1/32 scan.

// Wifi settings
const uint8_t ipOctet = 110 + panelNumber;                  //Sets last octet of ip address based on panelNumber.
const char* ssid = "xxx";
const char* password = "xxx";
IPAddress ip(10, 0, 0, ipOctet);
IPAddress gateway(10, 0, 0, 1);
IPAddress subnet(255, 255, 255, 0);

// LED settings
const int numLeds = (matrix_width*matrix_height);
const int numberOfChannels = numLeds * 3;

// Art-Net settings
ArtnetWifi artnet;
const int startUniverse = 50 + (7 * panelNumber);           //Start universe 
const int maxUniverses = 7;
bool universesReceived[maxUniverses];
bool sendFrame = 1;
int previousDataLength = 0;

const int CHANNELS_PER_UNIVERSE = 510;                      //510 because 170 LEDS * 3 = 510. 512 causes an LED to overlap into multiple universes.
uint8_t CHANNEL_VAL[510 * maxUniverses];
uint8_t PAST_CHANNEL_VAL[510 * maxUniverses];

void display_updater(){
  display.display(display_draw_time);
}

void display_update_enable(bool is_enable){
  if (is_enable)
    display_ticker.attach(0.004, display_updater);
  else
    display_ticker.detach();
}

bool newValue(uint8_t x, uint8_t y){                        //Checks if each LED's RGB values have changed since previous packet.
  uint16_t channel = ((x*3)*matrix_height)+(y*3);
  
  if(CHANNEL_VAL[channel]   != PAST_CHANNEL_VAL[channel]   ||
     CHANNEL_VAL[channel+1] != PAST_CHANNEL_VAL[channel+1] ||
     CHANNEL_VAL[channel+2] != PAST_CHANNEL_VAL[channel+2])
  {
    PAST_CHANNEL_VAL[channel]   = CHANNEL_VAL[channel];
    PAST_CHANNEL_VAL[channel+1] = CHANNEL_VAL[channel+1];
    PAST_CHANNEL_VAL[channel+2] = CHANNEL_VAL[channel+2];
    return true;
  }
  else{return false;};
}

void drawPixels(){                                          //Draws all pixels that have changed values since last packet.
  for(uint8_t x=0; x<matrix_width; x++){
    for(uint8_t y=0; y<matrix_height; y++){
      if(newValue(x,y)){
        uint16_t channel = ((x*3)*matrix_height)+(y*3);
        display.drawPixelRGB888(x,y,CHANNEL_VAL[channel],CHANNEL_VAL[channel+1],CHANNEL_VAL[channel+2]);
      };
    };
  };
}

void onDmxFrame(uint16_t universe, uint16_t length, uint8_t sequence, uint8_t* data){
  sendFrame = 1;

  uint16_t lastUniverse = universe == ((startUniverse + (maxUniverses - 1)) ? CHANNELS_PER_UNIVERSE - (CHANNELS_PER_UNIVERSE - 12) : 0);
  uint16_t numChannels = CHANNELS_PER_UNIVERSE - lastUniverse;

  for(uint8_t i=0; i<maxUniverses; i++){
    if (!universesReceived[i]){
      sendFrame = 0;
      break;
    };
  };

  for(uint8_t i=0; i<maxUniverses; i++){
    if(universe == startUniverse + i){
      universesReceived[i] = 1;
      for(uint16_t channel=0; channel<numChannels; channel++){
        CHANNEL_VAL[channel + (CHANNELS_PER_UNIVERSE * i)] = data[channel];
      };
      break;
    };
  };

  drawPixels();

  if (sendFrame){
    drawPixels();
    memset(universesReceived, 0, maxUniverses);
  };
};

void setup(){
  WiFi.config(ip, gateway, subnet);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {delay(10);};

  artnet.begin();
  artnet.setArtDmxCallback(onDmxFrame);

  display.begin(scan_rate);
  display.clearDisplay();
  display_update_enable(true);
}

void loop(){
  artnet.read();
};
@rstephan
Copy link
Owner

Hi,

you should see all traffic, especially the ArtDMX frames with the "light" data.
The amount of ArtSync looks a bit odd. But this can be a "feature" of your transmitter software to keep the universes lined up. Maybe??
The ArtnetWifi library is handling ArtDMX only, so no other frames are necessary to function.
Broadcast or unicast frames should also be not matter for blinking lights.
Try to find the DMX packets with a wireshark filter like this one artnet.header.opcode == 0x5000. Maybe a configuration problem in your setup?

Lag is also the result of "excess" traffic on the WiFi channel. Also keep in mind that "drawing" the colors takes some time. In most cases more than you expect. WiFi is fast compared to the some 100 KBit/s to clock bits into the LEDs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants