Artnet to Serial String

Hello,

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?

Thanks

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.

Sparkfun has examples of receiving data from an Artnet network Using Artnet DMX and the ESP32 to Drive Pixels - learn.sparkfun.com so maybe the first activity is to print to the serial monitor some of the interesting data from Artnet.

From your artnet network can you easily create the data you want to look at with the Arduino?

Hello,

Thankyou for the reply.

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

//VIDEO MUTE ON
buttonState5 = digitalRead(buttonInput5);
if (buttonState5 == LOW && projectorOn == true && videomute == false) 
{ 
      buttonled5 = true;
      digitalWrite(buttonLight5, buttonled5);
      delay(1000);
      Serial.println("ADZZ;OSH:0");
      delay(2000);
      videomute = true; //set videomute to TRUE
}

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.

I have found a good video where someone controls a laser controlling lasers using artnet arduino and touchdesigner - YouTube via artnet by printing lines to the monitor so I will see if I can replicate that first.

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.

Not quire for this application.

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.

Hello,

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 ?

Thank you for the advice on strings, I will write something to see how these work (I’m still very much at a green phase of coding for these)

There is a good document here about the data string https://art-net.org.uk/structure/streaming-packets/artdmx-packet-definition/

void onDmxFrame(uint16_t universe, uint16_t length, uint8_t sequence, uint8_t* data, IPAddress remoteIP)
{

Serial.println(data[0]);

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.