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.
//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
you mean da_tester_1060.zip?
can´t dpwnload it.
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?
View attachment 15611
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;
^
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
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
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
// 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;
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
}
}
}
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
...
14:26:30.427 -> W5500 16K_BUFFER_ACTIVE
14:26:38.631 -> server is at 169.254.190.15
// 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;
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);
}
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.
FYI: crees project is closed and no longer supports his megapixel octoluminair product.