Forum Rule: Always post complete source code & details to reproduce any issue!
Page 3 of 3 FirstFirst 1 2 3
Results 51 to 75 of 75

Thread: E1.31 sACN Ethernet DMX Performance help - 6 Universe Limit improvements?

  1. #51
    Junior Member
    Join Date
    Mar 2019
    Posts
    7
    Hi everybody, hope youīre fine. I just wanne play around with the "Mega Pixel E1.31" software but i canīt get anything out. Just the Test was working but no sACN. I can ping the node. iīm using the teensy 3,2 and the wiz820io with adapter board. Maybe someone has an ideal. thanks.

  2. #52
    Senior Member crees's Avatar
    Join Date
    Dec 2016
    Location
    Utah
    Posts
    216
    Quote Originally Posted by TSC View Post
    Hi everybody, hope youīre fine. I just wanne play around with the "Mega Pixel E1.31" software but i canīt get anything out. Just the Test was working but no sACN. I can ping the node. iīm using the teensy 3,2 and the wiz820io with adapter board. Maybe someone has an ideal. thanks.
    Post your code and I can take a look

  3. #53
    Junior Member
    Join Date
    Mar 2019
    Posts
    7
    @crees
    itīs your original code. the MegaPixel_E1.31. just the ip was changed.





    // E1.31 Receiver and pixel controller by Chris Rees (crees@bearrivernet.net) for the Teensy 3.2 This code was modified from
    // Andrew Huxtable base code. (andrew@hux.net.au)
    // This code may be freely distributed and used as you see fit for non-profit
    // purposes and as long as the original author is credited and it remains open
    // source
    //
    // Please configure your Lighting product to use Unicast to the IP the device is given from your DHCP server
    // Multicast is not currently supported at the moment


    // You will need the, Teensy utility installed with the added Ethernet One Socket and FastLed Libraries from:
    // https://www.pjrc.com/teensy/teensyduino.html
    // https://github.com/mrrees/MegaPixel-One-Socket-Ethernet
    // https://github.com/FastLED/FastLED/releases
    //
    // Please note the one socket library may throw errors in compiling. The error was in realation to the chip speed detection and using the
    // correct SPI speed.
    //
    // The Teensy with the Octows2811 and FastLED will allow up to 5440 Pixels (32 Universes) to run. One thing to note is if you desire
    // high frame rates your pixel count must not exceed over 680 Pixels per Octo Pin. The reason why is the ammount of time to write out to
    // these LED's takes time to shift from one LED to the next. The more LED's per SPI or Octo Pin the more time it takes and the less frame
    // rate you will acheive. In the Pixel Controller Wolrd 680 per SPI port is the desired balance. For the Teensy this is a perfect balance
    // any more pixels and memory starts to become an issue. Those who whish to push more pixels per port can do so but must sacrifice the
    // fastLED and or Octows2811 libraries to free up buffer space.. but your on your own and we welcome you to share your improved methods
    // with the community!


    // in the code structure there is some serial feedback. Please note enableing serial feedback will interrupt with the pixel performance
    // and will slow it down. use only for debugging and omit during production run.

    #include <SPI.h>
    #include <Ethernet.h>
    #include <EthernetUdp.h>
    #define USE_OCTOWS2811
    #include<OctoWS2811.h>
    #include<FastLED.h>
    #include <EEPROM.h>


    //************************************************** *******************************


    // enter desired universe and subnet (sACN first universe is 1)
    #define DMX_SUBNET 0
    //#define DMX_UNIVERSE 1 //**Start** universe


    // Set a different MAC address for each controller IMPORTANT!!!! you can change the last value but make sure its HEX!...
    byte mac[] = { 0x74, 0x69, 0x69, 0x2D, 0x30, 0x21 };

    //DEFINES for at Compile time.
    //Leave this alone. At current a full e1.31 frame is 636 bytes..
    #define ETHERNET_BUFFER 636 //540 is artnet leave at 636 for e1.31
    #define NUM_LEDS_PER_STRIP 240 //170
    #define NUM_STRIPS 8


    ///GLOBALS
    int unsigned DMX_UNIVERSE = 1; //**Start** universe 1, 9, 17, 25, 33, 41
    int unsigned UNIVERSE_COUNT = 32; //How Many Universes 8, 8, 8, 4, 8, 8
    int unsigned UNIVERSE_LAST = 32; // List the last universe typically its sequencially from start but does not have to. 8, 16, 24, 28, 32, 40
    int unsigned CHANNEL_COUNT = 510; //max channels per dmx packet
    byte unsigned LEDS_PER_UNIVERSE = 170; // Max RGB pixels

    //
    int unsigned NUM_LEDS = UNIVERSE_COUNT * LEDS_PER_UNIVERSE; // with current fastLED and OctoWs2811 libraries buffers... do not go higher than this - Runs out of SRAM

    ///



    //************************************************** *********
    // BEGIN Dont Modify unless you know what your doing below
    //************************************************** *********

    // Define the array of leds

    CRGB leds[NUM_STRIPS * NUM_LEDS_PER_STRIP];

    // Pin layouts on the teensy 3:
    // OctoWS2811: 2,14,7,8,6,20,21,5


    unsigned char packetBuffer[ETHERNET_BUFFER];
    int c = 0;
    float fps = 0;
    unsigned long currentMillis = 0;
    unsigned long previousMillis = 0;

    EthernetUDP Udp;

    void setup() {

    //byte ipadd[4] ; //Variable to store data read from EEPROM.
    //unsigned int eeAddress = 39; //EEPROM address to start reading from
    //EEPROM.get( eeAddress, ipadd );

    //************************************************** *****
    // ethernet interface ip address
    //IPAddress ip(ipadd[0], ipadd[1], ipadd[2], ipadd[3]); //IP address of ethernet shield
    IPAddress ip(192, 168, 0, 10); //IP address of ethernet shield

    //IPAddress mip(192,168,0,255); //multicast IP
    //************************************************** *****

    // E1.31 is UDP. One socket library will only allow one protocol to be defined.




    //WIZNET RESET AND INITIALIZE
    pinMode(9, OUTPUT);
    digitalWrite(9, LOW); // reset the WIZ820io
    delay(10);
    digitalWrite(9, HIGH); // reset the WIZ820io

    //SD CARD INITIALIZE
    //pinMode(10, OUTPUT); // For SD Card Stuff
    //digitalWrite(10, HIGH); // de-select WIZ820io
    //pinMode(4, OUTPUT); //SD Card Stuff
    //digitalWrite(4, HIGH); // de-select the SD Card

    //Serial Port Stuff
    Serial.begin(115200);
    delay(10);


    // Using different LEDs or colour order? Change here...
    // ************************************************** ******
    LEDS.addLeds<OCTOWS2811>(leds, NUM_LEDS_PER_STRIP);
    LEDS.setBrightness(255); //value should be 0-255 Very Bright after 100 default is 50 to save on current and eyes!
    // ************************************************** ******
    Serial.println("setup");
    //pins 3,4,22 are to the RGB Status LED

    // ************************************************** ******
    //Ethernet.init(1); //-> 1 Socket with 16k RX/TX buffer for ethernet3

    Ethernet.begin(mac,ip);

    //int success = Udp.beginMulticast(mip, 5568);
    //Serial.print( "begin, success: " );
    //Serial.println( success );

    Udp.begin(5568);

    //DEFINE AND Turn Framing LED OFF
    pinMode(4, OUTPUT);
    digitalWrite(4, HIGH);
    //DEFINE AND TURN STATUS LED ON
    pinMode(3, OUTPUT);

    digitalWrite(3, LOW);
    delay(1000);
    //Turn Status LED OFF
    digitalWrite(3, HIGH);
    // ************************************************** ******
    Serial.print("server is at ");
    Serial.println(Ethernet.localIP());
    Serial.println(F_BUS);

    //Once the Ethernet is initialised, run a test on the LEDs
    initTest();
    }



    static inline void fps2(const int seconds){
    // Create static variables so that the code and variables can
    // all be declared inside a function
    static unsigned long lastMillis;
    static unsigned long frameCount;
    static unsigned int framesPerSecond;

    // It is best if we declare millis() only once
    unsigned long now = millis();
    frameCount ++;
    if (now - lastMillis >= seconds * 1000) {
    framesPerSecond = frameCount / seconds;

    Serial.print("FPS @ ");
    Serial.println(framesPerSecond);
    frameCount = 0;
    lastMillis = now;
    }

    }

    static inline void pixelrefresh(const int syncrefresh){
    // Create static variables so that the code and variables can
    // all be declared inside a function
    static unsigned long frametimestart;
    static unsigned long frametimeend;
    static unsigned long frametimechk;
    static unsigned long frameonce;
    unsigned long now = micros();


    //start frame time
    frametimestart = now;

    //Serial.println(frametimechk)
    //If we have framed no need to frame again update time to most recent
    if (syncrefresh == 1){
    frametimeend = frametimestart;
    frameonce = 1;
    }

    //If we havent framed this will increment via time and at some point will be true,
    //if so we need to frame to clear out any buffer and the hold off untill
    //we receive our next valid dmx packet. We use the pixel protocol to get a general rule of timing to compare to.

    frametimechk = frametimestart - frametimeend;
    // num leds time 30us + 300us reset to simulate the time it would take to write out pixels.
    //this should help us not loop to fast and risk premature framing and jeopordize ethernet buffer
    if (frametimechk >= (NUM_LEDS * 30) + 300){
    frametimeend = frametimestart;


    if (frameonce == 1){
    LEDS.show();
    Serial.println ("Partial framing detected");
    frameonce = 0;
    }

    }

    }



    void sacnDMXReceived(unsigned char* pbuff, int count) {
    static unsigned long uniloopcount;
    if (count > CHANNEL_COUNT) count = CHANNEL_COUNT;
    byte b = pbuff[113]; //DMX Subnet
    if ( b == DMX_SUBNET) {
    b = pbuff[114]; //DMX Universe
    byte s = pbuff[111]; //sequence
    static unsigned long ls; // Last Sequence
    if (s > ls){
    uniloopcount = 0;
    ls = s;
    }
    //turn framing LED OFF
    digitalWrite(4, HIGH);
    Serial.print("UNI ");
    Serial.println(count );
    Serial.println(s);
    if ( b >= DMX_UNIVERSE && b <= UNIVERSE_LAST) {
    Serial.println(b );
    if ( pbuff[125] == 0 ) { //start code must be 0
    int ledNumber = (b - DMX_UNIVERSE) * LEDS_PER_UNIVERSE;
    // sACN packets come in seperate RGB but we have to set each led's RGB value together
    // this 'reads ahead' for all 3 colours before moving to the next led.
    Serial.println("*");
    for (int i = 126;i < 126+count;i = i + 3){
    byte charValueR = pbuff[i];
    byte charValueG = pbuff[i+1];
    byte charValueB = pbuff[i+2];
    leds[ledNumber] = CRGB(charValueR,charValueG,charValueB); //RBG GRB
    Serial.println(ledNumber);
    ledNumber++;
    }







    }








    }



    }

    uniloopcount ++;
    Serial.print("UNILOOP");
    Serial.println(uniloopcount);

    //if (b == UNIVERSE_LAST){
    if (uniloopcount >= UNIVERSE_COUNT){
    //Turn Framing LED ON
    digitalWrite(4, LOW);
    LEDS.show();
    pixelrefresh(1);
    uniloopcount = 0;
    //Frames Per Second Function fps(every_seconds)
    fps2(5);
    }

    }


    int checkACNHeaders(unsigned char* messagein, int messagelength) {
    //Do some VERY basic checks to see if it's an E1.31 packet.
    //Bytes 4 to 12 of an E1.31 Packet contain "ACN-E1.17"
    //Only checking for the A and the 7 in the right places as well as 0x10 as the header.
    //Technically this is outside of spec and could cause problems but its enough checks for us
    //to determine if the packet should be tossed or used.
    //This improves the speed of packet processing as well as reducing the memory overhead.
    //On an Isolated network this should never be a problem....
    if ( messagein[1] == 0x10 && messagein[4] == 0x41 && messagein[12] == 0x37) {
    int addresscount = (byte) messagein[123] * 256 + (byte) messagein[124]; // number of values plus start code
    return addresscount -1; //Return how many values are in the packet.
    }
    return 0;
    }



    void initTest() //runs at board boot to make sure pixels are working
    {
    LEDS.showColor(CRGB(255, 0, 0)); //turn all pixels on red
    delay(1000);
    LEDS.showColor(CRGB(0, 255, 0)); //turn all pixels on green
    delay(1000);
    LEDS.showColor(CRGB(0, 0, 255)); //turn all pixels on blue
    delay(1000);
    LEDS.showColor(CRGB(0, 0, 0)); //turn all pixels off
    Serial.println ("TEST");
    }

    void loop() {
    Serial.println("loop");//Process packets
    int packetSize = Udp.parsePacket(); //Read UDP packet count

    if(packetSize){
    Serial.println(packetSize);
    Udp.read(packetBuffer,ETHERNET_BUFFER); //read UDP packet


    int count = checkACNHeaders(packetBuffer, packetSize);
    if (count) {

    Serial.print("packet size first ");
    Serial.println(packetSize);





    sacnDMXReceived(packetBuffer, count); //process data function




    }



    }

    pixelrefresh(0);


    }

  4. #54
    Senior Member crees's Avatar
    Join Date
    Dec 2016
    Location
    Utah
    Posts
    216
    Try


    Code:
    //DEFINES for at Compile time.
    //Leave this alone. At current a full e1.31 frame is 636 bytes..
    #define ETHERNET_BUFFER 636 //540 is artnet leave at 636 for e1.31
    #define NUM_LEDS_PER_STRIP 240 //170
    #define NUM_STRIPS 8
    
    
    ///GLOBALS
    int unsigned DMX_UNIVERSE = 1; //**Start** universe 1, 9, 17, 25, 33, 41
    int unsigned UNIVERSE_COUNT = 12; //How Many Universes 8, 8, 8, 4, 8, 8
    int unsigned UNIVERSE_LAST = 12; // List the last universe typically its sequencially from start but does not have to. 8, 16, 24, 28, 32, 40
    int unsigned CHANNEL_COUNT = 510; //max channels per dmx packet
    byte unsigned LEDS_PER_UNIVERSE = 170; // Max RGB pixels
    Do you get any serial output

  5. #55
    Junior Member
    Join Date
    Oct 2018
    Posts
    15
    When you have testpatterns, it means the connection between Teensy and your LEDs are ok. You can ping, then the teensy is running ok. So, I would expect a problem with your software on the PC?

    Try with the Scan test software: maybe this makes thins more clear on what happens or not? My first tests with Jinx where also not succesfull. But after some playin around, I figured it out.

    da_tester_1060.zip

    Good luck

  6. #56
    Junior Member
    Join Date
    Mar 2019
    Posts
    7
    thatīs the confusing part. Iīm using Madrix Ultimate and tested it with another node. Thatīs worked fine. I also use my scope to look what is happening at the LED-out pins 2,14,...,...,etc but they were just low. so they are just doing the test at the beginning of the scetch. I tri to debug, but it seams that the scetch is only running in the main loop without recieveing any data or donīt try to read it. A test with a webserver from the examples works fine.
    greetz TS

  7. #57
    Junior Member
    Join Date
    Oct 2018
    Posts
    15
    Can you run a test with the software I told you? Does it work with Jinx?

  8. #58
    Junior Member
    Join Date
    Mar 2019
    Posts
    7
    you mean da_tester_1060.zip?
    canīt dpwnload it.

  9. #59
    Junior Member
    Join Date
    Oct 2018
    Posts
    15
    Quote Originally Posted by TSC View Post
    you mean da_tester_1060.zip?
    canīt dpwnload it.

    yes

    https://www.da-share.com/software/da_tester/

    I downloaded it from here.

    PS. I tried MAdrix with my LED-screen, but the demo-version does not allow 'output' :-(

  10. #60
    Junior Member
    Join Date
    Mar 2019
    Posts
    7
    yes the demo version of madrix 5 doesnīt allow output. but version 3 allows output with some blackouts. i tested again with jinx, i can see traffic on the led pins. but with da tester, same like madrix.

  11. #61
    Junior Member
    Join Date
    Oct 2018
    Posts
    15
    Can you try once with lower universe count?

    int unsigned UNIVERSE_COUNT = 8; //How Many Universes 8, 8, 8, 4, 8, 8
    int unsigned UNIVERSE_LAST = 8; // List the last universe typically its sequencially from start but does not have to. 8, 16, 24, 28, 32, 40

  12. #62
    Senior Member crees's Avatar
    Join Date
    Dec 2016
    Location
    Utah
    Posts
    216
    Do you get any output from

    Code:
    Serial.print("UNI ");
    Serial.println(count );
    Serial.println(s);
    if ( b >= DMX_UNIVERSE && b <= UNIVERSE_LAST) {
    Serial.println(b );

  13. #63
    Senior Member crees's Avatar
    Join Date
    Dec 2016
    Location
    Utah
    Posts
    216
    What is your output with

    Code:
    if(packetSize){
    Serial.println(packetSize);

  14. #64
    Junior Member
    Join Date
    Mar 2019
    Posts
    7
    he prints nothing. only the start text. server etc... then heīs in the main loop.very confuzed about it. i also tried to change to artnet, but receiving over 3 unverses the fps collaps and it begins to stutter.

  15. #65
    Senior Member crees's Avatar
    Join Date
    Dec 2016
    Location
    Utah
    Posts
    216
    Yes very odd you should be seeing serial print data even if it’s an invalid packet. I suspect an error in the code is crashing or there is no packet data. I will post some code here soon for you to test to see if it is any different.

  16. #66
    Junior Member
    Join Date
    Jul 2019
    Posts
    3
    hello folks,

    i have a project with 8 strip 300 pixel, total for 2400 pixels, i own teensy 3.2 and 3.6 with octows2811 and wiz850io. i already follow the Cree code and library


    Quote Originally Posted by GeertDierckx View Post
    Hi Guys,

    I'm nearly there.
    I have a running setup with 22 universes.
    But my setup (I have 4 panels of 60 x 15 LEDs) requires 23 universes.
    With 22 Universes, my last 40 LEDs are not lit by LINX. (see photograph)

    When I change the code to 23 universes, nothing happens anymore: no data to the controller, no display lit at all.
    (Last working code with 22 universes attached)

    Any ideas?
    Attachment 15611
    i still have error while compiling with teensyduino.

    Code:
    C:\Users\Laimena\Documents\Arduino\libraries\FastLED/FastLED.h:14:21: note: #pragma message: FastLED version 3.002.010
    
     #    pragma message "FastLED version 3.002.010"
    
                         ^
    
    sacn_coba_11_juli_2019_jam_2018: In function 'void fps2(int)':
    sacn_coba_11_juli_2019_jam_2018:178: warning: comparison between signed and unsigned integer expressions 
       if (now - lastMillis >= seconds * 1000) {
    
                            ^
    
    sacn_coba_11_juli_2019_jam_2018: In function 'void sacnDMXReceived(unsigned char*, int)':
    sacn_coba_11_juli_2019_jam_2018:234: warning: comparison between signed and unsigned integer expressions 
       if (count > CHANNEL_COUNT) count = CHANNEL_COUNT;
    
                 ^
    perhaps somebody can enlight me with the patching with JINX and i only need 16 universe with this project.
    thank you in advance.

  17. #67
    Junior Member
    Join Date
    Jul 2019
    Posts
    3
    this is the serial monitor from the code i'm using

    Code:
    18:03:01.757 -> FPS @ 4
    18:03:01.825 -> Partial framing detected
    18:03:01.995 -> Partial framing detected
    18:03:02.199 -> Partial framing detected
    18:03:02.403 -> Partial framing detected
    18:03:02.641 -> Partial framing detected
    18:03:02.845 -> Partial framing detected
    18:03:03.015 -> Partial framing detected
    18:03:03.219 -> Partial framing detected
    18:03:03.457 -> Partial framing detected
    18:03:03.627 -> Partial framing detected
    18:03:03.865 -> Partial framing detected
    18:03:04.069 -> Partial framing detected
    18:03:04.273 -> Partial framing detected
    18:03:04.510 -> Partial framing detected

  18. #68
    Senior Member crees's Avatar
    Join Date
    Dec 2016
    Location
    Utah
    Posts
    216
    Hi make sure your using the one socket library. However since your using w5500 chip you will need to adapt the one socket detect the w5500 chip. Check the github for the original one socket that I forked and see if there is a newer one for proper w5500 detection.

    Once you get the proper buffers ans spi speed you should see the increase of universe capacity.

  19. #69
    Junior Member
    Join Date
    Jul 2019
    Posts
    3
    thanks for your fast replying. i already using your socket one library. there is no update. the lastest update is your github.
    can you pinpoint me which i need to change W5100.h or W5100.ccp
    thank you

  20. #70
    Senior Member crees's Avatar
    Join Date
    Dec 2016
    Location
    Utah
    Posts
    216
    Quote Originally Posted by Cakmbruz View Post
    thanks for your fast replying. i already using your socket one library. there is no update. the lastest update is your github.
    can you pinpoint me which i need to change W5100.h or W5100.ccp
    thank you
    I forgot that I did have some test code in post 29 of this thread that might get you what you need.

  21. #71
    Junior Member
    Join Date
    Jun 2020
    Posts
    2
    Hello to all of you. First I want to thank you for your great work you have done so far!

    To my setup:

    I have 2400leds on 8 strips => 300led/strip, teensy 3.2 (120MHz, obverclock), octows2811, sd-card-board and the WIZ850io (W5500) adapter.
    I tried Crees code from github (post #5, https://gist.github.com/mrrees/d4ab8...d8b4f69d8105ec) and have the the Ethermet-lib for w5500 from the dropbox (post #29, https://www.dropbox.com/sh/98vhmyne0..._wPg8hHma?dl=0).

    I can ping the teensy, but the leds are not working (also not the test-routine, but this worked with other code, so the leds are ok)
    I tried "Da-Tester" (unicast with the IP of the teensy): no led respons. but less than 10FPS (probably due to the serial.print stuff?)

    Here is the serial-monitor-output:
    13:50:21.178 -> W5500 16K_BUFFER_ACTIVE
    13:50:21.178 -> server is at 169.254.190.15
    13:50:53.216 -> 638
    13:50:53.216 -> 638
    13:50:53.216 -> 6
    13:50:53.216 -> *
    13:50:53.216 -> 1
    13:50:53.216 -> 638
    13:50:53.216 -> 638
    13:50:53.216 -> 7
    13:50:53.216 -> *
    13:50:53.216 -> 2
    13:50:53.216 -> 638
    13:50:53.216 -> 638
    13:50:53.216 -> 8
    13:50:53.216 -> *
    13:50:53.216 -> 3
    13:50:53.216 -> 638
    13:50:53.216 -> 638
    13:50:53.216 -> 9
    13:50:53.216 -> *
    13:50:53.216 -> 4
    Here it stops.

    Here is my code: ( I also tried with 1 universe, 170led, didnt work!)
    // E1.31 Receiver code base by Andrew Huxtable (andrew@hux.net.au).Adapted and modified by
    // ccr (megapixel.lighting).
    //
    // This code may be freely distributed and used as you see fit for non-profit
    // purposes and as long as the original author is credited and it remains open
    // source
    //
    // Please configure your Lighting product to use Unicast to the IP the device is given from your DHCP server
    // Multicast is not currently supported due to bandwidth/processor limitations


    // You will need the Ethercard and FastLed Libraries from:
    // https://github.com/FastLED/FastLED/releases
    //
    // The Atmega328 only has 2k of SRAM. This is a severe limitation to being able to control large
    // numbers of smart pixels due to the pixel data needing to be stored in an array as well as
    // a reserved buffer for receiving Ethernet packets. This code will allow you to use a maximum of 240 pixels
    // as that just about maxes out the SRAM on the Atmega328.


    // There is deliberately no serial based reporting from the code to conserve SRAM. There is a **little**
    // bit available if you need to add some in for debugging but keep it to an absolute minimum for debugging
    // only.


    #include <SPI.h>
    #include <Ethernet.h>
    #include <EthernetUdp.h>
    #define USE_OCTOWS2811
    #include<OctoWS2811.h>
    #include<FastLED.h>


    //************************************************** *******************************


    // enter desired universe and subnet (sACN first universe is 1)
    #define DMX_SUBNET 0
    #define DMX_UNIVERSE 1 //**Start** universe


    // Set a different MAC address for each...
    byte mac[] = { 0x74, 0x69, 0x69, 0x2D, 0x30, 0x15 };


    // Uncomment if you want to use static IP
    //************************************************** *****
    // ethernet interface ip address
    IPAddress ip(169, 254, 190, 15); //IP address of ethernet shield
    //************************************************** *****


    EthernetUDP Udp;


    // By sacrificing some of the Ethernet receive buffer, we can allocate more to the LED array
    // but this is **technically** slower because 2 packets must be processed for all 240 pixels.


    /// DONT CHANGE unless you know the consequences...
    #define ETHERNET_BUFFER 636 //540
    #define CHANNEL_COUNT 7200 //because it divides by 3 nicely
    #define NUM_LEDS 2400 // can not go higher than this - Runs out of SRAM
    #define NUM_LEDS_PER_STRIP 170
    #define NUM_STRIPS 8
    #define UNIVERSE_COUNT 15
    #define LEDS_PER_UNIVERSE 170
    //#define BRIGHTNESS 100





    //************************************************** ******************************


    // Define the array of leds
    CRGB leds[NUM_STRIPS * NUM_LEDS_PER_STRIP];

    // Pin layouts on the teensy 3:
    // OctoWS2811: 2,14,7,8,6,20,21,5


    unsigned char packetBuffer[ETHERNET_BUFFER];
    int c = 0;
    float fps = 0;
    unsigned long currentMillis = 0;
    unsigned long previousMillis = 0;

    void setup() {

    pinMode(9, OUTPUT);
    digitalWrite(9, LOW); // reset the WIZ820io
    delay(10);
    digitalWrite(9, HIGH); // reset the WIZ820io
    //pinMode(10, OUTPUT);
    // digitalWrite(10, HIGH); // de-select WIZ820io
    //pinMode(4, OUTPUT);
    //digitalWrite(4, HIGH); // de-select the SD Card
    Serial.begin(115200);
    delay(10);
    // Using different LEDs or colour order? Change here...
    // ************************************************** ******
    LEDS.addLeds<OCTOWS2811>(leds, NUM_LEDS_PER_STRIP);
    LEDS.setBrightness(32);
    // ************************************************** ******



    // ************************************************** ******
    Ethernet.begin(mac,ip);
    Udp.begin(5568);
    // ************************************************** ******
    Serial.print("server is at ");
    Serial.println(Ethernet.localIP());

    //Once the Ethernet is initialised, run a test on the LEDs
    //initTest();
    }







    void sacnDMXReceived(unsigned char* pbuff, int count, int unicount) {
    if (count > CHANNEL_COUNT) count = CHANNEL_COUNT;
    byte b = pbuff[113]; //DMX Subnet
    if ( b == DMX_SUBNET) {
    b = pbuff[114]; //DMX Universe



    Serial.println(b );
    if ( b >= DMX_UNIVERSE && b <= DMX_UNIVERSE + UNIVERSE_COUNT ) {






    if ( pbuff[125] == 0 ) { //start code must be 0
    int ledNumber = (b - DMX_UNIVERSE) * LEDS_PER_UNIVERSE;
    // sACN packets come in seperate RGB but we have to set each led's RGB value together
    // this 'reads ahead' for all 3 colours before moving to the next led.
    Serial.println("*");
    for (int i = 126;i < 126+count;i = i + 3){
    byte charValueR = pbuff[i];
    byte charValueG = pbuff[i+1];
    byte charValueB = pbuff[i+2];
    leds[ledNumber] = CRGB(charValueR,charValueG,charValueB);
    //Serial.println(ledNumber);
    ledNumber++;
    }





    Serial.println(unicount);
    if (unicount == 15){

    LEDS.show();
    }


    }



    }
    }

    }


    int checkACNHeaders(unsigned char* messagein, int messagelength) {
    //Do some VERY basic checks to see if it's an E1.31 packet.
    //Bytes 4 to 12 of an E1.31 Packet contain "ACN-E1.17"
    //Only checking for the A and the 7 in the right places as well as 0x10 as the header.
    //Technically this is outside of spec and could cause problems but its enough checks for us
    //to determine if the packet should be tossed or used.
    //This improves the speed of packet processing as well as reducing the memory overhead.
    //On an Isolated network this should never be a problem....
    if ( messagein[1] == 0x10 && messagein[4] == 0x41 && messagein[12] == 0x37) {
    int addresscount = (byte) messagein[123] * 256 + (byte) messagein[124]; // number of values plus start code
    return addresscount -1; //Return how many values are in the packet.
    }
    return 0;
    }


    void initTest() //runs at board boot to make sure pixels are working
    {
    LEDS.showColor(CRGB(255, 0, 0)); //turn all pixels on red
    delay(1000);
    LEDS.showColor(CRGB(0, 255, 0)); //turn all pixels on green
    delay(1000);
    LEDS.showColor(CRGB(0, 0, 255)); //turn all pixels on blue
    delay(1000);
    LEDS.showColor(CRGB(0, 0, 0)); //turn all pixels off
    }

    void loop() {
    //Process packets
    int packetSize = Udp.parsePacket(); //Read UDP packet count
    if (c >= 10){

    c = 0;
    }
    if(packetSize){
    Serial.println(packetSize);
    Udp.read(packetBuffer,ETHERNET_BUFFER); //read UDP packet


    int count = checkACNHeaders(packetBuffer, packetSize);
    if (count) {

    //Serial.print("packet size first ");
    Serial.println(packetSize);

    c = c + 1;

    // calculate framerate
    currentMillis = millis();
    if(currentMillis > previousMillis){
    fps = 1 / ((currentMillis - previousMillis) * 0.001);
    } else {
    fps = 0;
    }
    previousMillis = currentMillis;

    if (fps > 10 && fps < 500)// don't show numbers below or over given ammount
    Serial.println(fps);

    sacnDMXReceived(packetBuffer, count, c); //process data function



    }


    }


    }

    EDIT

    After deactivating all the serial.print-stuff, the serial monitor output looks like this and doesnt stop. But still no led response!
    14:03:41.015 -> W5500 16K_BUFFER_ACTIVE
    14:03:41.015 -> server is at 169.254.190.15
    14:03:41.015 -> 638
    14:03:41.015 -> 638
    14:03:41.015 -> 638
    14:03:41.015 -> 638
    ...
    Any ideas!?



    EDIT 2

    When I use the following code, I get the leds-test-patern! The serial output is only:
    14:26:30.427 -> W5500 16K_BUFFER_ACTIVE
    14:26:38.631 -> server is at 169.254.190.15
    Here is the code I used
    ...
    // E1.31 Receiver and pixel controller by Chris Rees (crees@bearrivernet.net) for the Teensy 3.2 This code was modified from
    // Andrew Huxtable base code. (andrew@hux.net.au)
    // This code may be freely distributed and used as you see fit for non-profit
    // purposes and as long as the original author is credited and it remains open
    // source
    //
    // Please configure your Lighting product to use Unicast to the IP the device is given from your DHCP server
    // Multicast is not currently supported at the moment


    // You will need the, Teensy utility installed with the added Ethernet One Socket and FastLed Libraries from:
    // https://www.pjrc.com/teensy/teensyduino.html
    // https://github.com/mrrees/MegaPixel-One-Socket-Ethernet
    // https://github.com/FastLED/FastLED/releases
    //
    // Please note the one socket library may throw errors in compiling. The error was in realation to the chip speed detection and using the
    // correct SPI speed.
    //
    // The Teensy with the Octows2811 and FastLED will allow up to 5440 Pixels (32 Universes) to run. One thing to note is if you desire
    // high frame rates your pixel count must not exceed over 680 Pixels per Octo Pin. The reason why is the ammount of time to write out to
    // these LED's takes time to shift from one LED to the next. The more LED's per SPI or Octo Pin the more time it takes and the less frame
    // rate you will acheive. In the Pixel Controller Wolrd 680 per SPI port is the desired balance. For the Teensy this is a perfect balance
    // any more pixels and memory starts to become an issue. Those who whish to push more pixels per port can do so but must sacrifice the
    // fastLED and or Octows2811 libraries to free up buffer space.. but your on your own and we welcome you to share your improved methods
    // with the community!


    // in the code structure there is some serial feedback. Please note enableing serial feedback will interrupt with the pixel performance
    // and will slow it down. use only for debugging and omit during production run.

    #include <SPI.h>
    #include <Ethernet.h>
    #include <EthernetUdp.h>
    #define USE_OCTOWS2811
    #include<OctoWS2811.h>
    #include<FastLED.h>
    #include <EEPROM.h>


    //************************************************** *******************************


    // enter desired universe and subnet (sACN first universe is 1)
    #define DMX_SUBNET 0
    //#define DMX_UNIVERSE 1 //**Start** universe


    // Set a different MAC address for each controller IMPORTANT!!!! you can change the last value but make sure its HEX!...
    byte mac[] = { 0x74, 0x69, 0x69, 0x2D, 0x30, 0x21 };

    //DEFINES for at Compile time.
    //Leave this alone. At current a full e1.31 frame is 636 bytes..
    #define ETHERNET_BUFFER 636 //540 is artnet leave at 636 for e1.31
    #define NUM_LEDS_PER_STRIP 300 //170
    #define NUM_STRIPS 8


    ///GLOBALS
    int unsigned DMX_UNIVERSE = 1; //**Start** universe 1, 9, 17, 25, 33, 41
    int unsigned UNIVERSE_COUNT = 15; //How Many Universes 8, 8, 8, 4, 8, 8
    int unsigned UNIVERSE_LAST = 15; // List the last universe typically its sequencially from start but does not have to. 8, 16, 24, 28, 32, 40
    int unsigned CHANNEL_COUNT = 510; //max channels per dmx packet
    byte unsigned LEDS_PER_UNIVERSE = 170; // Max RGB pixels

    //
    int unsigned NUM_LEDS = UNIVERSE_COUNT * LEDS_PER_UNIVERSE; // with current fastLED and OctoWs2811 libraries buffers... do not go higher than this - Runs out of SRAM

    ///



    //************************************************** *********
    // BEGIN Dont Modify unless you know what your doing below
    //************************************************** *********

    // Define the array of leds

    CRGB leds[NUM_STRIPS * NUM_LEDS_PER_STRIP];

    // Pin layouts on the teensy 3:
    // OctoWS2811: 2,14,7,8,6,20,21,5


    unsigned char packetBuffer[ETHERNET_BUFFER];
    int c = 0;
    float fps = 0;
    unsigned long currentMillis = 0;
    unsigned long previousMillis = 0;

    EthernetUDP Udp;

    void setup() {

    //byte ipadd[4] ; //Variable to store data read from EEPROM.
    //unsigned int eeAddress = 39; //EEPROM address to start reading from
    //EEPROM.get( eeAddress, ipadd );

    //************************************************** *****
    // ethernet interface ip address
    //IPAddress ip(ipadd[0], ipadd[1], ipadd[2], ipadd[3]); //IP address of ethernet shield
    IPAddress ip(169, 254, 190, 15); //IP address of ethernet shield

    //IPAddress mip(239,255,0,1); //multicast IP
    //************************************************** *****

    // E1.31 is UDP. One socket library will only allow one protocol to be defined.




    //WIZNET RESET AND INITIALIZE
    pinMode(9, OUTPUT);
    digitalWrite(9, LOW); // reset the WIZ820io
    delay(10);
    digitalWrite(9, HIGH); // reset the WIZ820io

    //SD CARD INITIALIZE
    //pinMode(10, OUTPUT); // For SD Card Stuff
    //digitalWrite(10, HIGH); // de-select WIZ820io
    //pinMode(4, OUTPUT); //SD Card Stuff
    //digitalWrite(4, HIGH); // de-select the SD Card

    //Serial Port Stuff
    Serial.begin(115200);
    delay(10);


    // Using different LEDs or colour order? Change here...
    // ************************************************** ******
    LEDS.addLeds<OCTOWS2811>(leds, NUM_LEDS_PER_STRIP);
    LEDS.setBrightness(50); //value should be 0-255 Very Bright after 100 default is 50 to save on current and eyes!
    // ************************************************** ******

    //pins 3,4,22 are to the RGB Status LED

    // ************************************************** ******
    //Ethernet.init(1); //-> 1 Socket with 16k RX/TX buffer for ethernet3

    Ethernet.begin(mac,ip);

    //int success = Udp.beginMulticast(mip, 5568);
    //Serial.print( "begin, success: " );
    //Serial.println( success );

    Udp.begin(5568);

    //DEFINE AND Turn Framing LED OFF
    pinMode(4, OUTPUT);
    digitalWrite(4, HIGH);
    //DEFINE AND TURN STATUS LED ON
    pinMode(3, OUTPUT);

    digitalWrite(3, LOW);
    delay(9000);
    //Turn Status LED OFF
    digitalWrite(3, HIGH);
    // ************************************************** ******
    Serial.print("server is at ");
    Serial.println(Ethernet.localIP());
    //Serial.println(F_BUS);

    //Once the Ethernet is initialised, run a test on the LEDs
    initTest();
    }



    static inline void fps2(const int seconds){
    // Create static variables so that the code and variables can
    // all be declared inside a function
    static unsigned long lastMillis;
    static unsigned long frameCount;
    static unsigned int framesPerSecond;

    // It is best if we declare millis() only once
    unsigned long now = millis();
    frameCount ++;
    if (now - lastMillis >= seconds * 1000) {
    framesPerSecond = frameCount / seconds;

    Serial.print("FPS @ ");
    Serial.println(framesPerSecond);
    frameCount = 0;
    lastMillis = now;
    }

    }

    static inline void pixelrefresh(const int syncrefresh){
    // Create static variables so that the code and variables can
    // all be declared inside a function
    static unsigned long frametimestart;
    static unsigned long frametimeend;
    static unsigned long frametimechk;
    static unsigned long frameonce;
    unsigned long now = micros();


    //start frame time
    frametimestart = now;

    //Serial.println(frametimechk)
    //If we have framed no need to frame again update time to most recent
    if (syncrefresh == 1){
    frametimeend = frametimestart;
    frameonce = 1;
    }

    //If we havent framed this will increment via time and at some point will be true,
    //if so we need to frame to clear out any buffer and the hold off untill
    //we receive our next valid dmx packet. We use the pixel protocol to get a general rule of timing to compare to.

    frametimechk = frametimestart - frametimeend;
    // num leds time 30us + 300us reset to simulate the time it would take to write out pixels.
    //this should help us not loop to fast and risk premature framing and jeopordize ethernet buffer
    if (frametimechk >= (NUM_LEDS * 30) + 300){
    frametimeend = frametimestart;


    if (frameonce == 1){
    LEDS.show();
    Serial.println ("Partial framing detected");
    frameonce = 0;
    }

    }

    }



    void sacnDMXReceived(unsigned char* pbuff, int count) {
    static unsigned long uniloopcount;
    if (count > CHANNEL_COUNT) count = CHANNEL_COUNT;
    byte b = pbuff[113]; //DMX Subnet
    if ( b == DMX_SUBNET) {
    b = pbuff[114]; //DMX Universe
    byte s = pbuff[111]; //sequence
    static unsigned long ls; // Last Sequence
    if (s > ls){
    uniloopcount = 0;
    ls = s;
    }
    //turn framing LED OFF
    digitalWrite(4, HIGH);
    //Serial.print("UNI ");
    //Serial.println(count );
    //Serial.println(s);
    if ( b >= DMX_UNIVERSE && b <= UNIVERSE_LAST) {
    //Serial.println(b );
    if ( pbuff[125] == 0 ) { //start code must be 0
    int ledNumber = (b - DMX_UNIVERSE) * LEDS_PER_UNIVERSE;
    // sACN packets come in seperate RGB but we have to set each led's RGB value together
    // this 'reads ahead' for all 3 colours before moving to the next led.
    //Serial.println("*");
    for (int i = 126;i < 126+count;i = i + 3){
    byte charValueR = pbuff[i];
    byte charValueG = pbuff[i+1];
    byte charValueB = pbuff[i+2];
    leds[ledNumber] = CRGB(charValueR,charValueG,charValueB); //RBG GRB
    //Serial.println(ledNumber);
    ledNumber++;
    }







    }








    }



    }

    uniloopcount ++;
    //Serial.print("UNILOOP");
    //Serial.println(uniloopcount);

    //if (b == UNIVERSE_LAST){
    if (uniloopcount >= UNIVERSE_COUNT){
    //Turn Framing LED ON
    digitalWrite(4, LOW);
    LEDS.show();
    pixelrefresh(1);
    uniloopcount = 0;
    //Frames Per Second Function fps(every_seconds)
    fps2(5);
    }

    }


    int checkACNHeaders(unsigned char* messagein, int messagelength) {
    //Do some VERY basic checks to see if it's an E1.31 packet.
    //Bytes 4 to 12 of an E1.31 Packet contain "ACN-E1.17"
    //Only checking for the A and the 7 in the right places as well as 0x10 as the header.
    //Technically this is outside of spec and could cause problems but its enough checks for us
    //to determine if the packet should be tossed or used.
    //This improves the speed of packet processing as well as reducing the memory overhead.
    //On an Isolated network this should never be a problem....
    if ( messagein[1] == 0x10 && messagein[4] == 0x41 && messagein[12] == 0x37) {
    int addresscount = (byte) messagein[123] * 256 + (byte) messagein[124]; // number of values plus start code
    return addresscount -1; //Return how many values are in the packet.
    }
    return 0;
    }



    void initTest() //runs at board boot to make sure pixels are working
    {
    LEDS.showColor(CRGB(255, 0, 0)); //turn all pixels on red
    delay(1000);
    LEDS.showColor(CRGB(0, 255, 0)); //turn all pixels on green
    delay(1000);
    LEDS.showColor(CRGB(0, 0, 255)); //turn all pixels on blue
    delay(1000);
    LEDS.showColor(CRGB(0, 0, 0)); //turn all pixels off
    }

    void loop() {
    //Process packets
    int packetSize = Udp.parsePacket(); //Read UDP packet count

    if(packetSize){
    //Serial.println(packetSize);
    Udp.read(packetBuffer,ETHERNET_BUFFER); //read UDP packet


    int count = checkACNHeaders(packetBuffer, packetSize);
    if (count) {

    //Serial.print("packet size first ");
    //Serial.println(packetSize);





    sacnDMXReceived(packetBuffer, count); //process data function




    }



    }

    pixelrefresh(0);


    }
    Last edited by TheGuruu; 06-04-2020 at 01:39 PM.

  22. #72
    Senior Member crees's Avatar
    Join Date
    Dec 2016
    Location
    Utah
    Posts
    216
    Hi! Ok looks like your getting buffer info! thats good! Looking at your setup the way we need to think of this is budgeting the correct pixel per port settings. since you are using 300 pixels we need to use the correct universe budget. To make sure the buffers are setup correctly we need to use and define 16 universes. sACN uses start universe 1 (not 0 like artnet)

    Next troubleshooting step is to place a serial output on the buffer validation where it detects if its sACN or not. By doing this you verifying that the sacn portion is being detected. Onced verfied the buffer needs to be placed in the correct location of the pixel buffer so it can be written out (LEDshow). in the sloppy code I check the values of the array to validate that the universe fits the criteria (range that I expect). What I mean by sloppy is that I used a lazy count method or a last universe detect method to fire the LED's. Interestingly Using Jinx to send the LED data is that its very good at sending all universes. This is great because it was a reliable way to rely on in code when to send the LEDshow command. However using this code for GrandMA or other high end DMX consoles they seem to only send changed universe data so that makes it more difficult to know when to send the LED show command without compromising the incoming buffer (another discussion for another day).

    Once you validate that your detecting the universe data and that its making it to the LED buffer code (getting inserted into the array) then you should be able to see if the Last universe or universe count is being satisfied and allowing the LEDshow to happen.

    Hope this helps. The best part of this code is teaching how to process packets and place the data into LED buffers to be sent out.

  23. #73
    Junior Member
    Join Date
    Jun 2020
    Posts
    2
    Quote Originally Posted by crees View Post
    Hi! Ok looks like your getting buffer info! thats good! Looking at your setup the way we need to think of this is budgeting the correct pixel per port settings. since you are using 300 pixels we need to use the correct universe budget. To make sure the buffers are setup correctly we need to use and define 16 universes. sACN uses start universe 1 (not 0 like artnet)

    Next troubleshooting step is to place a serial output on the buffer validation where it detects if its sACN or not. By doing this you verifying that the sacn portion is being detected. Onced verfied the buffer needs to be placed in the correct location of the pixel buffer so it can be written out (LEDshow). in the sloppy code I check the values of the array to validate that the universe fits the criteria (range that I expect). What I mean by sloppy is that I used a lazy count method or a last universe detect method to fire the LED's. Interestingly Using Jinx to send the LED data is that its very good at sending all universes. This is great because it was a reliable way to rely on in code when to send the LEDshow command. However using this code for GrandMA or other high end DMX consoles they seem to only send changed universe data so that makes it more difficult to know when to send the LED show command without compromising the incoming buffer (another discussion for another day).

    Once you validate that your detecting the universe data and that its making it to the LED buffer code (getting inserted into the array) then you should be able to see if the Last universe or universe count is being satisfied and allowing the LEDshow to happen.

    Hope this helps. The best part of this code is teaching how to process packets and place the data into LED buffers to be sent out.
    Hello Crees,
    thank you for your fast reply. Unfortunately Iīm not a software engenieer or IT-person, therefor I would need a little bit more guidance.

    Ok 16 universes makes sence, so i get 2 universes per stripe without switching one universe to the next strip, right?

    Would be great if you could help ma bit further.

  24. #74
    Junior Member
    Join Date
    Aug 2018
    Posts
    6
    FYI: crees project is closed and no longer supports his megapixel octoluminair product.

  25. #75
    Senior Member crees's Avatar
    Join Date
    Dec 2016
    Location
    Utah
    Posts
    216
    Quote Originally Posted by rgbmike View Post
    FYI: crees project is closed and no longer supports his megapixel octoluminair product.
    yes and no. Do to reasons I had to take down my pcb board and DIY kits, however the github code and forum posts and occasional help is still there. If your good with combining wiznet schematics to teensy and the octows2811 your pretty much the same level as where I left the project.
    Last edited by crees; 09-14-2020 at 08:33 PM. Reason: irrelevant statement removed

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •