# Open Lighting Architecture and ArtNet integration

**URL:** <https://community.particle.io/t/open-lighting-architecture-and-artnet-integration/4006>\
**Category:** Project Share\
**Created:** [April 22, 2014, 2:34pm UTC](https://community.particle.io/t/open-lighting-architecture-and-artnet-integration/4006 "2014-04-22T14:34:44Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jeff](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/jeff/32/1206_2.png) [@Jeff](https://community.particle.io/u/Jeff)\
**Post date:** [April 22, 2014, 2:34pm UTC](https://community.particle.io/t/open-lighting-architecture-and-artnet-integration/4006/1 "2014-04-22T14:34:44Z")

</div>

I’m wondering whether anyone has any experience in the OLA protocol and could potentially point me in the right direction.

I’d love to be able to run a Raspberry Pi as an OLA ‘server’ and have it send commands over WiFi, have the Spark Core pick up the signal, and control RGB LED lighting through MOSFET’s connected to its PWM outputs.

So far I’ve only been able to find people successfully doing it on Arduino’s using USB, however this would need to be a WiFi (Ethernet) deal…

Any ideas?

---

<div class="post-metadata">

**Author:** ![kennethlimcp](https://avatars.discourse-cdn.com/v4/letter/k/c0e974/32.png) [@kennethlimcp](https://community.particle.io/u/kennethlimcp)\
**Post date:** [April 22, 2014, 2:39pm UTC](https://community.particle.io/t/open-lighting-architecture-and-artnet-integration/4006/2 "2014-04-22T14:39:14Z")

</div>

Just took a quick look and it seems to use DMX.

There’s a DMX shield coming up but how soon… no idea…

You can search for DMX and see past threads. Haven’t seen a working one so far. Can by done on the :spark: but haven’t seen it yet.

---

<div class="post-metadata">

**Author:** ![Jeff](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/jeff/32/1206_2.png) [@Jeff](https://community.particle.io/u/Jeff)\
**Post date:** [April 22, 2014, 2:45pm UTC](https://community.particle.io/t/open-lighting-architecture-and-artnet-integration/4006/3 "2014-04-22T14:45:01Z")

</div>

That’s right, in this case I’m most interested about the ability to send DMX commands over Ethernet and have them picked up by the :spark:

DMX Shield sounds amazing, but that would require more hardware to get the device talking to RGB LED’s. Ideally I would love to be able to receive the commands and then trigger values on the MOSFET’s.

---

<div class="post-metadata">

**Author:** ![kennethlimcp](https://avatars.discourse-cdn.com/v4/letter/k/c0e974/32.png) [@kennethlimcp](https://community.particle.io/u/kennethlimcp)\
**Post date:** [April 22, 2014, 2:47pm UTC](https://community.particle.io/t/open-lighting-architecture-and-artnet-integration/4006/4 "2014-04-22T14:47:40Z")

</div>

Not sure which you have to port but should be **ArtNet**

See here:

[http://playground.arduino.cc/Learning/DMX](http://playground.arduino.cc/Learning/DMX)

What kind of RGB LED? Must it be the DMX protocol?

We can write up something to control the RGB LEDs via a simple web app or `Spark.function` and get this thing running.

Makes things simpler 🙂

---

<div class="post-metadata">

**Author:** ![Jeff](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/jeff/32/1206_2.png) [@Jeff](https://community.particle.io/u/Jeff)\
**Post date:** [April 22, 2014, 11:00pm UTC](https://community.particle.io/t/open-lighting-architecture-and-artnet-integration/4006/5 "2014-04-22T23:00:04Z")

</div>

Sure, it can probably be another protocol. My thinking was to use openHAB as the hub for my home automation, connecting to various :spark: devices around the house, and DMX over Ethernet seemed to be the easiest to implement.

Not set in stone yet though.

---

<div class="post-metadata">

**Author:** ![kennethlimcp](https://avatars.discourse-cdn.com/v4/letter/k/c0e974/32.png) [@kennethlimcp](https://community.particle.io/u/kennethlimcp)\
**Post date:** [April 22, 2014, 11:03pm UTC](https://community.particle.io/t/open-lighting-architecture-and-artnet-integration/4006/6 "2014-04-22T23:03:08Z")

</div>

Fair enough. I’m not having enough motivation to do the porting since I have never used a DMX device or have no DMX device to test as well! 😃

---

<div class="post-metadata">

**Author:** ![Jeff](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/jeff/32/1206_2.png) [@Jeff](https://community.particle.io/u/Jeff)\
**Post date:** [April 24, 2014, 3:48pm UTC](https://community.particle.io/t/open-lighting-architecture-and-artnet-integration/4006/7 "2014-04-24T15:48:36Z")

</div>

I've been doing a lot of research here and decided to run an OLA server and use ArtNet to talk to the Spark devices. I've actually started putting together a script which I hope will achieve what I want.

It doesn't compile yet, but I've posted the code below. Unfortunately I seem to be getting the following errors:

> In file included from ../inc/spark\_wiring.h:30:0,  
> from ../inc/application.h:31,  
> from artnet\_receiver.cpp:9:  
> ../../core-common-lib/SPARK\_Firmware\_Driver/inc/config.h:12:2: warning: #warning "Defaulting to Release Build" [-Wcpp]  
> artnet\_receiver.cpp: In function 'void loop()':  
> artnet\_receiver.cpp:56:23: error: expected primary-expression before '.' token  
> artnet\_receiver.cpp:69:15: error: expected unqualified-id before '=' token  
> artnet\_receiver.cpp:70:21: error: expected primary-expression before '.' token  
> artnet\_receiver.cpp:71:8: error: expected unqualified-id before '.' token  
> artnet\_receiver.cpp:109:28: warning: suggest parentheses around assignment used as truth value [-Wparentheses]  
> make: \*\*\* [artnet\_receiver.o] Error 1

```
/*
ArtNet-for-Spark-Core
=====================

A script to allow the Spark Core to receive DMX commands from an ArtNet server and trigger lights connected to PWM outputs.

This project is a port of the Arduino based script originally written by Christoph Guillermet.
*/

#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) );

// variables set when a packet is received
byte remoteIp[4]; // holds originating IP
unsigned int remotePort; // holds originating port

// channel 
const int number_of_channels = 512; // amount of total channels
const int channel_position = 1; // start reading from this channel

// buffers
#define MaxSize 1024
char packetBuffer[MaxSize]; // store incoming data
byte buffer_dmx[number_of_channels+channel_position]; // store filetered DMX data

// artnet parameters
unsigned int localPort = 6454; // default artnet port is UDP 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 is_artnet_version_1=0;
short is_artnet_version_2=0;
short seq_artnet=0;
short artnet_physical=0;
short incoming_universe=0;
boolean is_opcode_is_dmx=0;
boolean is_opcode_is_artpoll=0;
boolean match_artnet=1;
short Opcode=0;
UDP Udp;

void setup() {
  //setup pins as PWM output
  pinMode(4, OUTPUT); //check with leds + resistance in pwm
  pinMode(5, OUTPUT); //check with leds + resistance in pwm
  pinMode(6, OUTPUT); //check with leds + resistance in pwm
  
  //setup udp socket
  Udp.begin(localPort);
}

void loop() {
  int packetSize = UDP.parsePacket();
  
  //FIXME: test/debug check
  //if(packetSize>art_net_header_size && packetSize<=max_packet_size)//check size to avoid unneeded checks
  if(packetSize) {
    Serial.print("Packet received! (size: ");
    Serial.print(packetSize);
    Serial.print(") \n");
    Serial.print(art_net_header_size);
    Serial.print("\n");
    Serial.print(max_packet_size);
    Serial.print("\n");
    
    IPAddress = UDP.remoteIP();    
    remotePort = UDP.remotePort();
    UDP.read(packetBuffer, MaxSize);
    
    //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(packetBuffer[i])!=ArtNetHead[i]) {
        match_artnet=0;break;
      } 
    } 
       
     //if its an artnet header
    if(match_artnet==1) { 
        //artnet protocole revision, not really needed
        //is_artnet_version_1=packetBuffer[10]; 
        //is_artnet_version_2=packetBuffer[11];*/
      
        //sequence of data, to avoid lost packets on routeurs
        //seq_artnet=packetBuffer[12];*/
          
        //physical port of dmx N°
        //artnet_physical=packetBuffer[13];*/
        
      //operator code enables to know wich type of message Art-Net it is
      Opcode=bytes_to_short(packetBuffer[9],packetBuffer[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;
         //( we should normally reply to it, giving ip adress of the device)
      } 
       
      //if its DMX data we will read it now
      if(is_opcode_is_dmx=1) {
         //if you need to filter DMX universes, uncomment next line to have the universe rceived
         //incoming_universe= bytes_to_short(packetBuffer[15],packetBuffer[14])
       
          //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=channel_position-1;i< number_of_channels;i++) {
            buffer_dmx[i]= byte(packetBuffer[i+17]);
          }
      }
    }//end of sniffing
     
    for(int k=6; k<9; k++) {
       Serial.print(buffer_dmx[k]);
       Serial.print(", ");  
    }
    Serial.println("");

    //stuff to do on PWM or whatever
    analogWrite(4,buffer_dmx[1]);  
    analogWrite(5,buffer_dmx[2]); 
    analogWrite(6,buffer_dmx[3]);      
  }  
}

```

Any feedback is much appreciated 🙂

---

<div class="post-metadata">

**Author:** ![kennethlimcp](https://avatars.discourse-cdn.com/v4/letter/k/c0e974/32.png) [@kennethlimcp](https://community.particle.io/u/kennethlimcp)\
**Post date:** [April 24, 2014, 3:59pm UTC](https://community.particle.io/t/open-lighting-architecture-and-artnet-integration/4006/8 "2014-04-24T15:59:06Z")

</div>

Just some `UDP.` not changed to `Udp`

There’s only 1 error left to read in the `IPAddress = Udp.remoteIP();` It’s a 4 byte return value and it should not be read this way.

I can’t remember how they do it off hand but let me dig 😄

```
/*
ArtNet-for-Spark-Core
=====================

A script to allow the Spark Core to receive DMX commands from an ArtNet server and trigger lights connected to PWM outputs.

This project is a port of the Arduino based script originally written by Christoph Guillermet.
*/

#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) );

// variables set when a packet is received
byte remoteIp[4]; // holds originating IP
unsigned int remotePort; // holds originating port

// channel 
const int number_of_channels = 512; // amount of total channels
const int channel_position = 1; // start reading from this channel

// buffers
#define MaxSize 1024
char packetBuffer[MaxSize]; // store incoming data
byte buffer_dmx[number_of_channels+channel_position]; // store filetered DMX data

// artnet parameters
unsigned int localPort = 6454; // default artnet port is UDP 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 is_artnet_version_1=0;
short is_artnet_version_2=0;
short seq_artnet=0;
short artnet_physical=0;
short incoming_universe=0;
boolean is_opcode_is_dmx=0;
boolean is_opcode_is_artpoll=0;
boolean match_artnet=1;
short Opcode=0;
UDP Udp;

void setup() {
  //setup pins as PWM output
  pinMode(4, OUTPUT); //check with leds + resistance in pwm
  pinMode(5, OUTPUT); //check with leds + resistance in pwm
  pinMode(6, OUTPUT); //check with leds + resistance in pwm

  //setup udp socket
  Udp.begin(localPort);
}

void loop() {
  int packetSize = Udp.parsePacket();

  //FIXME: test/debug check
  //if(packetSize>art_net_header_size && packetSize<=max_packet_size)//check size to avoid unneeded checks
  if(packetSize) {
    Serial.print("Packet received! (size: ");
    Serial.print(packetSize);
    Serial.print(") \n");
    Serial.print(art_net_header_size);
    Serial.print("\n");
    Serial.print(max_packet_size);
    Serial.print("\n");

     IPAddress remoteIp = Udp.remoteIP();    
    remotePort = Udp.remotePort();
    Udp.read(packetBuffer, MaxSize);

    //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(packetBuffer[i])!=ArtNetHead[i]) {
        match_artnet=0;break;
      } 
    } 

     //if its an artnet header
    if(match_artnet==1) { 
        //artnet protocole revision, not really needed
        //is_artnet_version_1=packetBuffer[10]; 
        //is_artnet_version_2=packetBuffer[11];*/

        //sequence of data, to avoid lost packets on routeurs
        //seq_artnet=packetBuffer[12];*/

        //physical port of dmx N°
        //artnet_physical=packetBuffer[13];*/

      //operator code enables to know wich type of message Art-Net it is
      Opcode=bytes_to_short(packetBuffer[9],packetBuffer[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;
         //( we should normally reply to it, giving ip adress of the device)
      } 

      //if its DMX data we will read it now
      if(is_opcode_is_dmx ==1) {
         //if you need to filter DMX universes, uncomment next line to have the universe rceived
         //incoming_universe= bytes_to_short(packetBuffer[15],packetBuffer[14])

          //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=channel_position-1;i< number_of_channels;i++) {
            buffer_dmx[i]= byte(packetBuffer[i+17]);
          }
      }
    }//end of sniffing

    for(int k=6; k<9; k++) {
       Serial.print(buffer_dmx[k]);
       Serial.print(", ");  
    }
    Serial.println("");

    //stuff to do on PWM or whatever
    analogWrite(4,buffer_dmx[1]);  
    analogWrite(5,buffer_dmx[2]); 
    analogWrite(6,buffer_dmx[3]);      
  }  
}

```

@Jeff, It’s all done and you can try the code above.

Basically, just some simple typo and missing out the VAR name. Good job!

---

<div class="post-metadata">

**Author:** ![bko](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/bko/32/20704_2.png) [@bko](https://community.particle.io/u/bko)\
**Post date:** [April 24, 2014, 4:10pm UTC](https://community.particle.io/t/open-lighting-architecture-and-artnet-integration/4006/9 "2014-04-24T16:10:56Z")

</div>

IPAddress is a class (think of it like a type in this case) and it returned by remoteIP() so you could write:

```cpp
IPAddress rIP = Udp.remoteIP(); // rIP is the variable

```

---

<div class="post-metadata">

**Author:** ![Jeff](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/jeff/32/1206_2.png) [@Jeff](https://community.particle.io/u/Jeff)\
**Post date:** [April 24, 2014, 4:28pm UTC](https://community.particle.io/t/open-lighting-architecture-and-artnet-integration/4006/10 "2014-04-24T16:28:15Z")

</div>

@kennethlimcp & @bko – you guys are legends!

The code compiles! I will give it a go interfacing with the OLA server as soon as my :spark: arrives 😄 In the meantime I’ll try and clean it up a little. I’ve also posted the code to GitHub at [https://github.com/iJaffa/ArtNet-for-Spark-Core](https://github.com/iJaffa/ArtNet-for-Spark-Core)

* * *

One thing I wanted to ask as well: I’ve noticed that in the Arduino world scripts define the below code. I’m assuming that this is not necessary in the Spark world because of the built in networking functionality. Am I correct in assuming this, or will I need to define this in my script as well?

```
//MAC and IP of the ethernet shield
byte mac[] = {144, 162, 218, 00, 16, 96};
byte ip[] = {192, 168, 1, 177};
```

---

<div class="post-metadata">

**Author:** ![kennethlimcp](https://avatars.discourse-cdn.com/v4/letter/k/c0e974/32.png) [@kennethlimcp](https://community.particle.io/u/kennethlimcp)\
**Post date:** [April 24, 2014, 4:36pm UTC](https://community.particle.io/t/open-lighting-architecture-and-artnet-integration/4006/11 "2014-04-24T16:36:44Z")

</div>

You definitely can comment those out 😄

FYI, if you want to get more `Network` information from the :spark: core,

see [http://docs.spark.io/#/firmware/connection-management-network](http://docs.spark.io/#/firmware/connection-management-network)

That reminds me of `Network.ping()` that @bko worked on which has been merged and available on the WebIDE but yet to be documented.

Will work on the docs tomorrow morning 💛

---

<div class="post-metadata">

**Author:** ![bko](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/bko/32/20704_2.png) [@bko](https://community.particle.io/u/bko)\
**Post date:** [April 24, 2014, 4:41pm UTC](https://community.particle.io/t/open-lighting-architecture-and-artnet-integration/4006/12 "2014-04-24T16:41:58Z")

</div>

Hi @Jeff

Normally you would not need these, but if your code really needs to use these for something you want to do, you can **read** both the MAC and the IP address. You never need to set them.

The IP address can be useful to know if you are debugging, so I often print it out at setup time on my LCD display.

---

<div class="post-metadata">

**Author:** ![Jeff](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/jeff/32/1206_2.png) [@Jeff](https://community.particle.io/u/Jeff)\
**Post date:** [April 24, 2014, 5:10pm UTC](https://community.particle.io/t/open-lighting-architecture-and-artnet-integration/4006/13 "2014-04-24T17:10:25Z")

</div>

I thought as much 🙂

I’ve never been great at programming, and this is my first real go at the Arduino/Spark language, so thanks for your assistance.

I will update this thread once I have my :spark: in hand and have been able to do some real world testing of the code.

I’m hoping that I can just connect my LED strip via the [MOSFET design in my other post](https://community.spark.io/t/wiring-to-drive-an-rgb-led-strip/3888/7?u=jeff) and have it work 🙂

---

<div class="post-metadata">

**Author:** ![Jeff](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/jeff/32/1206_2.png) [@Jeff](https://community.particle.io/u/Jeff)\
**Post date:** [May 16, 2014, 8:09am UTC](https://community.particle.io/t/open-lighting-architecture-and-artnet-integration/4006/14 "2014-05-16T08:09:12Z")

</div>

OK, so I finally received my Spark Core today, and have managed to successfully send my code to it (although I had some real trouble trying to get it to connect to WiFi, the iOS app just did not work).

Problem is my :spark: goes into SOS mode followed by 8 blinks, so looks like it’s running out of memory.

Any reasons it’s doing this? This is the code I’m using: (also on [GitHub](https://github.com/iJaffa/ArtNet-for-Spark-Core))

```
/*
ArtNet-for-Spark-Core
=====================

A script to allow the Spark Core to listen for ArtNet DMX commands from an OLA server over Wi-Fi and output PWM values 
to selected pins. My hooking an RGB LED strip to three outputs it should be possible to control the strip RGB colour.

This project is a port of the Arduino based script originally written by Christoph Guillermet.

Thank you to the Spark Community for support in porting the code.
*/

#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) );

// variables set when a packet is received
byte remoteIp[4]; // holds originating IP
unsigned int remotePort;	// holds originating port

// channel 
const int number_of_channels = 512;	// amount of total channels
const int channel_position = 1; // start reading from this channel

// buffers
#define MaxSize 1024
char packetBuffer[MaxSize]; // store incoming data
byte buffer_dmx[number_of_channels+channel_position];	// store filetered DMX data

// artnet parameters
unsigned int localPort = 6454; // default artnet port is UDP 6454
const int art_net_header_size=17;
const int max_packet_size=576;
char ArtNetHead[8]="ArtNet";
char OpHbyteReceive=0;
char OpLbyteReceive=0;
short is_artnet_version_1=0;
short is_artnet_version_2=0;
short seq_artnet=0;
short artnet_physical=0;
short incoming_universe=0;
boolean is_opcode_is_dmx=0;
boolean is_opcode_is_artpoll=0;
boolean match_artnet=1;
short Opcode=0;
UDP Udp;

void setup() {
	//setup pins as PWM output
	pinMode(4, OUTPUT);	//check with leds + resistance in pwm
	pinMode(5, OUTPUT);	//check with leds + resistance in pwm
	pinMode(6, OUTPUT);	//check with leds + resistance in pwm
	
	//setup udp socket
	Udp.begin(localPort);
}

void loop() {
	int packetSize = Udp.parsePacket();
	
	//FIXME: test/debug check
	//if(packetSize>art_net_header_size && packetSize<=max_packet_size)//check size to avoid unneeded checks
	
	if(packetSize) {
		Serial.print("Packet received! (size: ");
		Serial.print(packetSize);
		Serial.print(") \n");
		Serial.print(art_net_header_size);
		Serial.print("\n");
		Serial.print(max_packet_size);
		Serial.print("\n");
		
		IPAddress remoteIp = Udp.remoteIP();
		remotePort = Udp.remotePort();
		Udp.read(packetBuffer, MaxSize);
		
		//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(packetBuffer[i])!=ArtNetHead[i]) {
				match_artnet=0;break;
			}
		}
		
		//if it's an artnet header
		if(match_artnet==1) {
			//artnet protocol revision, not really needed
			//is_artnet_version_1=packetBuffer[10]; 
			//is_artnet_version_2=packetBuffer[11];
			
			//sequence of data, to avoid lost packets on routers
			//seq_artnet=packetBuffer[12];
			
			//physical port of dmx N°
			//artnet_physical=packetBuffer[13];
			
			//operator code to know wich type of ArtNet message is received
			Opcode=bytes_to_short(packetBuffer[9],packetBuffer[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;
				//we should normally reply to it, giving ip adress of the device)
			}
			
			//if its DMX data we will read it now
			if(is_opcode_is_dmx=1) {
				//if you need to filter DMX universes, uncomment next line to have the universe received
				//incoming_universe= bytes_to_short(packetBuffer[15],packetBuffer[14])
				
				//getting data from a channel position on a precise amount of channels
				//do this to avoid to much operation if for example you only need a few channels
				//channel position
				for (int i=channel_position-1;i< number_of_channels;i++) {
					buffer_dmx[i]= byte(packetBuffer[i+17]);
				}
			}
		}
		//end of sniffing
		
		for (int k=6; k<9; k++) {
			Serial.print(buffer_dmx[k]);
			Serial.print(", ");
		}
		
		Serial.println("");
		
		//stuff to do on PWM or whatever
		analogWrite(4,buffer_dmx[1]);
		analogWrite(5,buffer_dmx[2]);
		analogWrite(6,buffer_dmx[3]);
	}
}

```

---

<div class="post-metadata">

**Author:** ![kennethlimcp](https://avatars.discourse-cdn.com/v4/letter/k/c0e974/32.png) [@kennethlimcp](https://community.particle.io/u/kennethlimcp)\
**Post date:** [May 18, 2014, 4:29pm UTC](https://community.particle.io/t/open-lighting-architecture-and-artnet-integration/4006/15 "2014-05-18T16:29:42Z")

</div>

Try lowering `MaxSize`.

---

<div class="post-metadata">

**Author:** ![Jeff](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/jeff/32/1206_2.png) [@Jeff](https://community.particle.io/u/Jeff)\
**Post date:** [May 18, 2014, 4:55pm UTC](https://community.particle.io/t/open-lighting-architecture-and-artnet-integration/4006/16 "2014-05-18T16:55:11Z")

</div>

Hey @kennethlimcp – thanks, should have updated the thread/post.

I’ve lowered maxsize, and the code runs, however for some reason it’s having trouble parsing the ArtNet data, and no matter what DMX data is being transmitted, the Spark will always read it as 0, 0, 0.

I’m trying to figure out if this is to do with the apparent issues with the UDP framework for Spark at the moment, maybe there is a better way of parsing the data. I’ve put together the following code to try and find out what the Spark is seeing from the OLA server:

```
unsigned int localPort = 6454; // local port to listen on

UDP Udp;

const int UDP_TX_PACKET_MAX_SIZE=24;
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet

void setup() {
  Udp.begin(localPort);
  Serial.begin(9600);
}

void loop() {
  int packetSize = Udp.parsePacket();
  if(packetSize > 12) {
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remote = Udp.remoteIP();
    for (int i =0; i < 4; i++) {
      Serial.print(remote[i], DEC);
      if (i < 3)
      {
        Serial.print(".");
      }
    }
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    // read the packet into packetBufffer
    Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE);
    Serial.println("Contents:");
    Serial.println(packetBuffer);
}
}

```

However, the only output I see in the console is:

```
Received packet of size 191
From 10.0.1.30, port 6454
Contents:
- ArtNet server
Received packet of size 167
From 10.0.1.30, port 6454
Contents:
 
Received packet of size 143
From 10.0.1.30, port 6454
Contents:
 
Received packet of size 119
From 10.0.1.30, port 6454
Contents:
A
Received packet of size 95
From 10.0.1.30, port 6454
Contents:
 
Received packet of size 71
From 10.0.1.30, port 6454
Contents:
 
Received packet of size 47
From 10.0.1.30, port 6454
Contents:
 
Received packet of size 23
From 10.0.1.30, port 6454
Contents:
 
Received packet of size 14
From 10.0.1.30, port 6454
Contents:
Art-Net

```

The raw packets being broadcast on the network look like this:

![](https://community.particle.io/uploads/particle/1364/2a54a6dc2335a79a.png)

I need to have the Spark pick out the packets coming in on port 6454 which have the blue highlighting and purple box in common (header of “Art-Net” and the Opcode “0x5000”) and pull out the red green and blue boxed values, convert to decimals, and apply this decimal to a PWM output.

@bko suggested I use `client.read()` instead, however I’m not sure how this works and how to use it to parse raw packet data…

---

<div class="post-metadata">

**Author:** ![bko](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/bko/32/20704_2.png) [@bko](https://community.particle.io/u/bko)\
**Post date:** [May 18, 2014, 4:59pm UTC](https://community.particle.io/t/open-lighting-architecture-and-artnet-integration/4006/17 "2014-05-18T16:59:38Z")

</div>

I put some starter code back in that other thread–hope it helps.

---

<div class="post-metadata">

**Author:** ![Jeff](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/jeff/32/1206_2.png) [@Jeff](https://community.particle.io/u/Jeff)\
**Post date:** [May 18, 2014, 5:11pm UTC](https://community.particle.io/t/open-lighting-architecture-and-artnet-integration/4006/18 "2014-05-18T17:11:47Z")

</div>

Thanks @bko - I will give it a go tomorrow. Very helpful indeed!

---

<div class="post-metadata">

**Author:** ![Jeff](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/jeff/32/1206_2.png) [@Jeff](https://community.particle.io/u/Jeff)\
**Post date:** [May 19, 2014, 5:25am UTC](https://community.particle.io/t/open-lighting-architecture-and-artnet-integration/4006/19 "2014-05-19T05:25:51Z")

</div>

I’ve worked on it somewhat today, and this is how far I have gotten:

```
unsigned int localPort = 6454;

const int MaxSize=32;
char databyte[MaxSize];

UDP Udp;

void setup() {
  Udp.begin(localPort);
  Serial.begin(9600);
}

void loop() {

const char prefix[] = { 'A','r','t','-','N','e','t', 0x0, 0x0, 0x50};
#define NSKIP 8

byte x; // three values to update
byte y;
byte z;

int prefixIdx = 0;
int skipCount = 0;
int readCount = 0;

//States
bool searching = true;
bool inPrefix = false;
bool skipping = false;
bool reading3 = false;

//...
int nbytes = Udp.parsePacket();

while (nbytes>16 && nbytes <=32) {
  Udp.read(databyte,1);
  nbytes--;
  
  if (searching) {
    if (databyte == prefix[prefixIdx]) {
      prefixIdx++;
      searching = false;
      inPrefix = true;
    }
  }
  
  else if (inPrefix) {
    if (databyte == prefix[prefixIdx]) {
      prefixIdx++;
      if (prefixIdx == sizeof(prefix)) { //done
        inPrefix = false;
        skipping = true;
	    skipCount = 0;
        prefixIdx = 0; // for next time
      } 
    } else { // stopped matching part way, see we start a new one
      prefixIdx = 0;
      if (databyte == prefix[prefixIdx]) {
        prefixIdx++;
      } else {
	inPrefix = false;
	searching = true;
      }
    }
  }
  
  else if (skipping) {
    if (skipCount++ == NSKIP) {
      reading3 = true;
      skipCount = 0;
      readCount = 0;
    }
  }
  
  else if (reading3) {
    switch (readCount) {
    case 0:
      x = databyte;
      break;
    case 1:
      y = databyte;
      break;
    case 2:
      z = databyte;
      reading3 = false;
      searching = true;
      break;
    default:
      reading3 = false;
      searching = true;
    }
    readCount++;
  }
  
  Serial.println("Data received:");
  Serial.println(x);
  Serial.println(y);
  Serial.println(z);
  
}
}

```

However I am getting the following compile errors:

```
> In file included from ../inc/spark_wiring.h:30:0,
> from ../inc/application.h:31,
> from /udp_parse.cpp:2:
> ../../core-common-lib/SPARK_Firmware_Driver/inc/config.h:12:2: warning: #warning "Defaulting to Release Build" [-Wcpp]
> /udp_parse.cpp:5:1: error: expected unqualified-id before 'else'
> /udp_parse.cpp:6:1: error: expected unqualified-id before 'else'
> /udp_parse.cpp:7:1: error: expected unqualified-id before 'else'
> /udp_parse.cpp: In function 'void loop()':
> /udp_parse.cpp:40:37: error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
> /udp_parse.cpp:48:37: error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
> /udp_parse.cpp:58:39: error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
> /udp_parse.cpp:78:11: error: invalid conversion from 'char*' to 'byte {aka unsigned char}' [-fpermissive]
> /udp_parse.cpp:81:11: error: invalid conversion from 'char*' to 'byte {aka unsigned char}' [-fpermissive]
> /udp_parse.cpp:84:11: error: invalid conversion from 'char*' to 'byte {aka unsigned char}' [-fpermissive]
> make: *** [/udp_parse.o] Error 1

```

I’ve tried byte conversion using `byte(databyte)` however have not had much luck. ☹

---

<div class="post-metadata">

**Author:** ![bko](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/bko/32/20704_2.png) [@bko](https://community.particle.io/u/bko)\
**Post date:** [May 19, 2014, 11:00am UTC](https://community.particle.io/t/open-lighting-architecture-and-artnet-integration/4006/20 "2014-05-19T11:00:37Z")

</div>

Hi @Jeff

Sorry–forgot how databyte was declared. We really only need one byte now, but I left your array and just lowered the size.

```cpp
unsigned int localPort = 6454;

const int MaxSize=2;
char databyte[MaxSize];

UDP Udp;

void setup() {
  Udp.begin(localPort);
  Serial.begin(9600);
}

void loop() {

const char prefix[] = { 'A','r','t','-','N','e','t', 0x0, 0x0, 0x50};
#define NSKIP 8

byte x; // three values to update
byte y;
byte z;

int prefixIdx = 0;
int skipCount = 0;
int readCount = 0;

//States
bool searching = true;
bool inPrefix = false;
bool skipping = false;
bool reading3 = false;

//...
int nbytes = Udp.parsePacket();

while (nbytes>16 && nbytes <=32) {
  Udp.read(databyte,1);
  nbytes--;

  if (searching) {
    if (databyte[0] == prefix[prefixIdx]) {
      prefixIdx++;
      searching = false;
      inPrefix = true;
    }
  }

  else if (inPrefix) {
    if (databyte[0] == prefix[prefixIdx]) {
      prefixIdx++;
      if (prefixIdx == sizeof(prefix)) { //done
        inPrefix = false;
        skipping = true;
	    skipCount = 0;
        prefixIdx = 0; // for next time
      } 
    } else { // stopped matching part way, see we start a new one
      prefixIdx = 0;
      if (databyte[0] == prefix[prefixIdx]) {
        prefixIdx++;
      } else {
	inPrefix = false;
	searching = true;
      }
    }
  }

  else if (skipping) {
    if (skipCount++ == NSKIP) {
      reading3 = true;
      skipCount = 0;
      readCount = 0;
    }
  }

  else if (reading3) {
    switch (readCount) {
    case 0:
      x = databyte[0];
      break;
    case 1:
      y = databyte[0];
      break;
    case 2:
      z = databyte[0];
      reading3 = false;
      searching = true;
      break;
    default:
      reading3 = false;
      searching = true;
    }
    readCount++;
  }

  Serial.println("Data received:");
  Serial.println(x);
  Serial.println(y);
  Serial.println(z);

}
}

```

[Next page](https://community.particle.io/t/open-lighting-architecture-and-artnet-integration/4006.md?page=2)
