-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathMegaPixel_E1.31.ino
272 lines (189 loc) · 8.55 KB
/
MegaPixel_E1.31.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
// E1.31 Receiver and pixel controller by Chris Rees ([email protected]) for the Teensy 3.2 This code was modified from
// Andrew Huxtable base code. ([email protected])
// 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:
// [url]https://www.pjrc.com/teensy/teensyduino.html[/url]
// [url]https://github.com/mrrees/MegaPixel-One-Socket-Ethernet[/url]
// [url]https://github.com/FastLED/FastLED/releases[/url]
//
// 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>
//*********************************************************************************
// 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, 0x14 };
// Uncomment if you want to use static IP
//*******************************************************
// ethernet interface ip address
IPAddress ip(192, 168, 2, 21); //IP address of ethernet shield
//*******************************************************
// E1.31 is UDP. One socket library will only allow one protocol to be defined.
EthernetUDP Udp;
//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
/// Change Values and needed.
#define CHANNEL_COUNT 16320 //because it divides by 3 nicely
#define NUM_LEDS 5440 // with current fastLED and OctoWs2811 libraries buffers... do not go higher than this - Runs out of SRAM
#define NUM_LEDS_PER_STRIP 680
#define NUM_STRIPS 8
#define UNIVERSE_COUNT 32
#define LEDS_PER_UNIVERSE 170
//***********************************************************
// 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;
void setup() {
//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(100);
// ********************************************************
//pins 3,4,22 are to the RGB Status LED
// ********************************************************
Ethernet.begin(mac,ip);
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());
//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
byte s = pbuff[111]; //sequence
//turn framing LED OFF
digitalWrite(4, HIGH);
//Serial.println(s );
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 == UNIVERSE_COUNT){
//Turn Framing LED ON
digitalWrite(4, LOW);
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 > UNIVERSE_COUNT){
c = 1;
}
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);
//Calculation of FPS. Not working correcly..... Commented out untill resolved
// 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); // show FPS (needs fixing)
sacnDMXReceived(packetBuffer, count, c); //process data function
c = c + 1;
}
}
}