I am working on a solution to control multiple RGB-LED (via a PWM-Driver TLC5947 from Adafruit) from a software on my computer, that sends out DMX signal (Node Management Utility). The software is very basic, it has 512 channels that can fade from 0 to 255. The DMX signal is sent via ethernet cable to an EthernetShield that is attached to my Arduino Uno.
I downloaded the TLC5947 library and run the test programm. Everything worked just fine. Then I tried to receive Art-Net packets (the TLC5947 Driver was disconnected at the time). I got the different values on the console, when I played with the first fader from the software.
I am running into a problem, when i try to combine these two objects. I initialise the PWM Driver in the void setup() in the Art-Net-Receiving-Sketch:
void setup() {
Serial.begin(9600);
Ethernet.begin(mac,ip);
Udp.begin(localPort);
// PWM Driver initialisation
PWM_DRIVER.begin(); //this somehow causes trouble with the code...
if (OE >= 0) {
pinMode(OE, OUTPUT);
digitalWrite(OE, LOW);
}
}
But then, somehow the void loop() is playing crazy! The loop seems to run very slowly, I can't fade properly anymore. Sometimes it even seems that the loop is stucked. :o Though I haven't even sent an order to the PWM Driver... The only thing I did is trying to set it up. When I outcomment PWM_DRIVER.begin(); , it works again.
What could be the reason for this clash? Thanks for any help!
full code:
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h> // UDP library from: bjoern@cs.stanford.edu 12/30/2008
#include "Adafruit_TLC5947.h"
#define short_get_high_byte(x) ((HIGH_BYTE & x) >> 8)
#define short_get_low_byte(x) (LOW_BYTE & x)
#define bytes_to_short(h,l) ( ((h << 8) & 0xff00) | (l & 0x00FF) );
// ADAFRUIT TLC5947 settings
#define NR_OF_DRIVERS 1
#define DATA 4
#define CLOCK 5
#define LATCH 6
#define OE -1 // set to -1 to not use the enable pin (its optional)
Adafruit_TLC5947 PWM_DRIVER = Adafruit_TLC5947(NR_OF_DRIVERS, CLOCK, DATA, LATCH);
// network settings
byte mac[] = {0xA8, 0x61, 0x0A, 0xAE, 0x51, 0x3D} ;
byte ip[] = {169, 254, 170, 13};
byte remoteIp[4];
unsigned int remotePort;
byte SubnetID = {0};
byte UniverseID = {0};
short select_universe = ((SubnetID*16)+UniverseID);
// Art-Net receiving "settings"
const int NR_OF_CHANNELS = 4;
const int START_ADDRESS = 0;
const int MAX_BUFFER_UDP = 768;
char packet_buffer[MAX_BUFFER_UDP]; // buffer to store incoming data
byte buffer_channel_arduino[NR_OF_CHANNELS];
unsigned int localPort = 6454; // artnet UDP port is by default 6454
const int art_net_header_size = 17;
const int max_packet_size = 576;
char ArtNetHead[8] = "Art-Net";
char OpHbyteReceive = 0;
char OpLbyteReceive = 0;
short incoming_universe = 0;
boolean is_opcode_is_dmx = 0;
boolean is_opcode_is_artpoll = 0;
boolean match_artnet = 1;
short opcode = 0;
EthernetUDP Udp;
void setup() {
Serial.begin(9600);
Ethernet.begin(mac,ip);
Udp.begin(localPort);
// PWM Driver initialisation
PWM_DRIVER.begin(); //this somehow causes trouble with the code...
if (OE >= 0) {
pinMode(OE, OUTPUT);
digitalWrite(OE, LOW);
}
}
void loop() {
int packet_size = Udp.parsePacket();
if(packet_size > art_net_header_size && packet_size <= max_packet_size) {
IPAddress remote = Udp.remoteIP();
remotePort = Udp.remotePort();
Udp.read(packet_buffer, MAX_BUFFER_UDP);
//read header
match_artnet = 1;
for (int i = 0; i<7; i++) {
//if not corresponding, this is not an artnet packet, so we stop reading
if (char(packet_buffer[i]) != ArtNetHead[i]) {
match_artnet = 0;
break;
}
}
//if it is an artnet header
if(match_artnet == 1) {
//operator code enables to know which type of message Art-Net it is
opcode = bytes_to_short(packet_buffer[9], packet_buffer[8]);
//if opcode is DMX type
if(opcode == 0x5000) {
is_opcode_is_dmx = 1;
is_opcode_is_artpoll = 0;
}
//if opcode is artpoll
else if(opcode == 0x2000) {
is_opcode_is_artpoll = 1;
is_opcode_is_dmx = 0;
}
//if its DMX data we will read it now
if(is_opcode_is_dmx = 1) {
//read incoming universe
incoming_universe = bytes_to_short(packet_buffer[15],packet_buffer[14])
//if it is selected universe DMX will be read
if(incoming_universe == select_universe) {
//getting data from a channel position, on a precise amount of channels, this to avoid to much operation if you need only 4 channels for example
//channel position
for(int i=START_ADDRESS;i< NR_OF_CHANNELS;i++) {
buffer_channel_arduino[i-START_ADDRESS]= byte(packet_buffer[i+art_net_header_size+1]);
}
}
}
}
// here we get the values from 0 to 255 on our console when we use the first fader from our software that sends out dmx signal
Serial.print(buffer_channel_arduino[0]);
Serial.println();
}
}