forked from mtongnz/ESP8266_ArtNetNode_DMX
-
Notifications
You must be signed in to change notification settings - Fork 0
/
artNet.ino
184 lines (147 loc) · 5.17 KB
/
artNet.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
/*
ESP8266_ArtNetNode_DMX - artNet.ino
Copyright (c) 2015, Matthew Tong
https://github.com/mtongnz/ESP8266_ArtNetNode_DMX
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program.
If not, see http://www.gnu.org/licenses/
*/
/* checkForNewData()
* Checks latest array againt current array for len values. Returns the index of the last difference.
*/
int checkForNewData(byte *latest, byte *current, int len) {
#ifdef VERBOSE
Serial.print("Checking ");
Serial.print(len + 1);
Serial.print(" channels for new data... ");
#endif
// Loop through arrays from the end to find the last difference
while (--len >= 0) {
// If a difference is found, return the number of channels to output
if ( latest[len] != current[len] ) {
#ifdef VERBOSE
Serial.print(len);
Serial.println(" new channels!");
#endif
return(len + 1);
}
}
#ifdef VERBOSE
Serial.println("no new data.");
#endif
// All data is equal - return 0 channels to output
return(0);
}
/* artDMXReceived()
* Handles ArtNet DMX packets
*/
void artDMXReceived(unsigned char* pbuff) {
// Don't collect Artnet if we're outputting from stored scenes
if (outputScene == 1)
return;
// Check Subnet
if ( (pbuff[14] >> 4) != artNetSub )
return;
// Which universe is this packet for (Z = neither)
char uni = ((pbuff[14] & 0xF) == artNetUniA) ? 'A' : (((pbuff[14] & 0xF) == artNetUniB) ? 'B' : 'Z');
// If not correct Artnet Universe
if ( uni == 'Z' )
return;
#ifdef VERBOSE
Serial.print("Artnet Uni ");
Serial.print(uni);
Serial.println(" Received");
#endif
// Number of dimmers hi byte first
int numberOfDimmers = pbuff[16]*256 + pbuff[17];
// If there's new data, output DMX
if ( numberOfDimmers > 0 ) {
if ( uni == 'A')
dmxA.setChans(&pbuff[ARTNET_ADDRESS_OFFSET], numberOfDimmers);
if ( uni == 'B')
dmxB.setChans(&pbuff[ARTNET_ADDRESS_OFFSET], numberOfDimmers);
}
}
/* sendArtNetReply()
* Sends a packet with information such as the Arduino's IP address, univers and subnet settings to other Art-Net
* devices listening to the network.
*/
void sendArtNetReply() {
unsigned char replyBuffer[ARTNET_REPLY_SIZE];
int i;
#ifdef VERBOSE
Serial.println("Sending Artnet Reply");
#endif
for ( i=0; i<ARTNET_REPLY_SIZE; i++ ) {
replyBuffer[i] = 0;
}
replyBuffer[0] = 'A';
replyBuffer[1] = 'r';
replyBuffer[2] = 't';
replyBuffer[3] = '-';
replyBuffer[4] = 'N';
replyBuffer[5] = 'e';
replyBuffer[6] = 't';
replyBuffer[7] = 0;
replyBuffer[8] = 0; //op code lo-hi
replyBuffer[9] = 0x21;
replyBuffer[10] = ip[0]; //ip address
replyBuffer[11] = ip[1];
replyBuffer[12] = ip[2];
replyBuffer[13] = ip[3];
replyBuffer[14] = 0x36; // port lo first always 0x1936
replyBuffer[15] = 0x19;
replyBuffer[16] = 0; //firmware hi-lo
replyBuffer[17] = 0;
replyBuffer[18] = highByte(subnet+1); //subnet hi-lo
replyBuffer[19] = lowByte(subnet+1);
replyBuffer[20] = 0; //oem hi-lo
replyBuffer[21] = 0;
replyBuffer[22] = 0; // ubea
replyBuffer[23] = 160; // status 1
replyBuffer[24] = 't'; // ESTA Code (2 bytes)
replyBuffer[25] = 'm';
//short name
for (int x = 26; x < 43; x++) {
replyBuffer[x] = nodeName[x-26];
if (nodeName[x-26] == 0)
break;
}
//long name
for (int x = 44; x < 70; x++) {
replyBuffer[x] = nodeName[x-44];
if (nodeName[x-44] == 0)
break;
}
replyBuffer[173] = 2; //number of ports
replyBuffer[174] = 128; //Port 1 can output DMX from network
replyBuffer[175] = 128; //Port 2 can output DMX from network
replyBuffer[182] = 128; //Port 1 good output (128 = data being transmitted)
replyBuffer[183] = 128; //Port 2 good output (128 = data being transmitted)
replyBuffer[190] = artNetUniA + 16*artNetSub; // Port 1 address
replyBuffer[191] = artNetUniB + 16*artNetSub; // Port 2 address
// MAC Address
for (int x = 0; x < 6; x++)
replyBuffer[201 + x] = MAC_array[x];
replyBuffer[212] = (dhcp) ? 15 : 13; // status 2
// Send packet
eUDP.beginPacket(broadcast_ip, ARTNET_PORT);
int test = eUDP.write(replyBuffer,ARTNET_REPLY_SIZE);
eUDP.endPacket();
}
/* artNetOpCode()
* Checks to see that the packet is actually Art-Net and returns the opcode telling what kind of Art-Net message it is.
*/
int artNetOpCode(unsigned char* pbuff) {
String test = String((char*)pbuff);
if ( test.equals("Art-Net") ) {
if ( pbuff[11] >= 14 ) { //protocol version [10] hi byte [11] lo byte
return pbuff[9] *256 + pbuff[8]; //opcode lo byte first
}
}
return 0;
}