I have been working on an off with Arduinos for a couple of years and have made some interesting projects with them.
I am however hit a stumbling block with artnet, most of my previous projects were simple, buttons - relays etc, serial/midi in.
There is lots of documentation out there for controlling LED strips with artnet data however I have not been successful in finding anyone that has posted any information on RS232 strings from Artnet,
Essentially what I am aiming to do for example, on receiving artnet universe 1 channel 1 @ 255 the Arduino will print out a serial command through a RS232 shield to control a serial device.
Would it be something along the lines of reading the incoming artnet data and then an if statement to query this and on correct data println()
If so IS there any good starting point for learning how the data is a) read into the code, and then how it can best be queried and then reacted upon?
Maybe start with providing some information about the RS232 device you want to control and the type of data (format etc.) that it is expecting. Can you post a link to it.
The RS232 device will be some Sony BRC PTZ cameras, by sending a VISCA command like the one below.
The cameras involved will take a preset recall command, currently if I send this from dock lite through the USB serial device for example it will recall a preset 1,
PTZ POS 1 Data= 8101043f0200ff[cr]
I have the RS232 shield from spark fun RS232 Shield - DEV-11958 - SparkFun Electronics, and have used this to send ASCII to a Panasonic projector in a similar way listening to a buttonState
For artnet I can create the data I want to see so will be able to generate the desired artnet values, and then see them on the network through artnetometer or similar, so that part is ok.
Then the point at which I am looking into at the moment, is how to interpret the artnet string, abit like the buttonState so that when it receives this, it will run the Serial.print etc
Hope the above makes sense, essentially I am looking to replace the physical button commands with artnet commands.
OK. So the role of the Arduino is to watch for a sequence of VISCA commands, on its network interface, which are intended for the BRC PTZ cameras, maybe do some reformatting etc. , then send these commands on to the cameras via a Sparkfun RS232 shield.
Well it certainly sound like an interesting project and if you find reasonably close examples of each link in the chain, which it sounds like you have, then the prospects of success are good.
I am planning on having the Arduino listen to artnet data and then on a particular data string channel 1@255 for example, send the command that is written in the code out via the RS232 shield.
Will see how I get on this week with the example you have shown to print the data in the serial plotter. Then work out how to read this data in an if { } statement ? and then send out the command.
Let me know if this needs to go into another forum or if I'm ok continuing with this thread.
I now have the following code which is working and interpreting the data
#include <Artnet.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <SPI.h>
Artnet artnet;
const int maxUniverses = 512;
bool universesReceived[maxUniverses];
// Change ip and mac address for your setup
byte ip[] = {192, 168, 0, 120};
byte mac[] = {0x04, 0xE9, 0xE5, 0x00, 0x69, 0xEC};
void setup()
{
Serial.begin(115200);
artnet.begin(mac, ip);
// this will be called for each packet received
artnet.setArtDmxCallback(onDmxFrame);
}
void loop()
{
// we call the read function inside the loop
artnet.read();
}
void onDmxFrame(uint16_t universe, uint16_t length, uint8_t sequence, uint8_t* data, IPAddress remoteIP)
{
/*
if (universe == 0) this will print a line of recieved whenever Universe one is on the network
{
Serial.println("recieved");
}
*/
if (length == 512)
{
Serial.println("data length");
}
// print out our data
Serial.print("universe number = ");
Serial.print(universe);
Serial.print("\tdata length = ");
Serial.print(length);
Serial.print("\tsequence n0. = ");
Serial.println(sequence);
Serial.print("DMX data: ");
for (int i = 0 ; i < length ; i++)
{
Serial.print(data[i]);
Serial.print(" ");
if (data[i] == 170)
Serial.println("send string");
}
Serial.println();
Serial.println();
}
The next step for me would be to work on change on update only, so currently it prints a line every time it receives a packet which is great, however I would like to only print the "send string" once on change of value, is there a way to do this?
Then the next step then is to work out how to interpret the data string so I can select a particular channel number within the data
In principle, you can store the buffer data[ ] in , say data1[ ].
You can then test if the currently read version of data[ ] is different to the last one and, if so, print it.
You can use strncmp( ) to check if two byte arrays are identical.
You can use strncpy( ) to copy data[ ] into data1[ ].
There are other ways of doing this as well.
Can you find a document describing the format of the data transmitted to assist decoding it ?
So with this code on every frame received will read print the first byte of the data array which in this is 512 long from.
I could also filter the string so that is only one byte long by having the following, with a channel int 512 will result in only one line in the array
void onDmxFrame(uint16_t universe, uint16_t length, uint8_t sequence, uint8_t* data, IPAddress remoteIP)
{
Serial.print("DMX data: ");
for (int i = 0 ; i < length /channels; i++) // divide by channels int (512)
{
Serial.print(data[i]);
}
In the artnet software you can select the universe it is broadcast on. So for my goal ultimately I will query the universe, if this is 1 for example, then query the first data byte and print it, if it is the same in the next DMX frame do nothing, if it has changed print it.