Hi all,
I have a project that uses the Arduino ethernet shield (w5100) for controlling WS2812b RGB Leds via sACN/E1.31 lighting protocol. This works exceptional on a normal Arduino but the amount of leds I can control is seriously limited by the 2k of SRAM on the arduino.
I bought a Teensy 3.1 thinking faster processor + 64k SRAM = much more LEDS that i could control but so far i have been disappointed with the performance. i.e I cant even get the teensy 3.1 to perform as well as a stock arduino controlling about 240 leds with the same code.
I have it connected as per: http://www.epyon.be/2013/07/06/using-the-teensy-3-0-with-the-arduino-ethernet-shield/ with the exception of IOREF since the 3.1 is 5v tolerant and that part is working fine.
The Teensy 3.1 works fine running about 1500 leds by itself - No problems there at all but when using ethernet, its as if the SPI bus is 'lagging' and cant receive the data fast enough and is missing the packets. If I delay the transmission of the packets to ~100ms, it seems to work better but at 20ms (where the arduino is fine) it basically will only process the first packet each time.
Is there a setting that defines the SPI bus speed or is there an alternative UDP library for Teensy that I am not using?
This is the working code on arduino:
I have a project that uses the Arduino ethernet shield (w5100) for controlling WS2812b RGB Leds via sACN/E1.31 lighting protocol. This works exceptional on a normal Arduino but the amount of leds I can control is seriously limited by the 2k of SRAM on the arduino.
I bought a Teensy 3.1 thinking faster processor + 64k SRAM = much more LEDS that i could control but so far i have been disappointed with the performance. i.e I cant even get the teensy 3.1 to perform as well as a stock arduino controlling about 240 leds with the same code.
I have it connected as per: http://www.epyon.be/2013/07/06/using-the-teensy-3-0-with-the-arduino-ethernet-shield/ with the exception of IOREF since the 3.1 is 5v tolerant and that part is working fine.
The Teensy 3.1 works fine running about 1500 leds by itself - No problems there at all but when using ethernet, its as if the SPI bus is 'lagging' and cant receive the data fast enough and is missing the packets. If I delay the transmission of the packets to ~100ms, it seems to work better but at 20ms (where the arduino is fine) it basically will only process the first packet each time.
Is there a setting that defines the SPI bus speed or is there an alternative UDP library for Teensy that I am not using?
This is the working code on arduino:
Code:
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include "FastLED.h"
//*********************************************************************************
// enter desired universe and subnet (sACN first universe is 1)
#define DMX_SUBNET 0
#define DMX_UNIVERSE 15 //**Start** universe
// Set a different MAC address for each...
byte mac[] = { 0x74, 0x69, 0x69, 0x2D, 0x30, 0x18 };
// Uncomment if you want to use static IP
//*******************************************************
// ethernet interface ip address
IPAddress ip(10, 0, 0, 18); //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 540
#define CHANNEL_COUNT 360 //because it divides by 3 nicely
#define NUM_LEDS 240 // can not go higher than this - Runs out of SRAM on Arduino
#define UNIVERSE_COUNT 2
#define LEDS_PER_UNIVERSE 120
// The pin the data line is connected to for WS2812b
#define DATA_PIN 7
//********************************************************************************
// Define the array of leds
CRGB leds[NUM_LEDS];
unsigned char packetBuffer[ETHERNET_BUFFER];
void setup() {
// Using different LEDs or colour order? Change here...
// ********************************************************
FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
// ********************************************************
// ********************************************************
Ethernet.begin(mac,ip);
Udp.begin(5568);
// ********************************************************
}
void loop() {
//Process packets
int packetSize = Udp.parsePacket(); //Read UDP packet count
if(packetSize){
Udp.read(packetBuffer,ETHERNET_BUFFER); //read UDP packet
int count = checkACNHeaders(packetBuffer, packetSize);
if (count) {
sacnDMXReceived(packetBuffer, count); //process data function
}
}
}
void sacnDMXReceived(unsigned char* pbuff, int count) {
if (count > CHANNEL_COUNT) count = CHANNEL_COUNT;
byte b = pbuff[113]; //DMX Subnet
if ( b == DMX_SUBNET) {
b = pbuff[114]; //DMX Universe
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].setRGB(charValueR,charValueG,charValueB);
ledNumber++;
}
FastLED.show(); //Do it!
}
}
}
}
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 = messagein[123] * 256 + messagein[124]; // number of values plus start code
return addresscount -1; //Return how many values are in the packet.
}
return 0;
}