Open Lighting Architecture and ArtNet integration

Ah, I see. So does the array need to be there, or should it be removed?

Two more questions if I may. Firstly should I be trying to narrow down packets using the following:?

while (nbytes>16 && nbytes <=32) {

And secondly, I am getting these errors about the unqualified-id. I’ve looked at line 5 6 and 7 of the code, however this is just the UDP Udp; part. It looks like all of the ;'s are in place on each line, so I’m not sure what it’s referring to? I’ve tried changing the standalone if’s to else if’s, which doesn’t seem to fix the issue (in fact, it makes matters worse).

/udp_parser.cpp:5:1: error: expected unqualified-id before 'else'
/udp_parser.cpp:6:1: error: expected unqualified-id before 'else'
/udp_parser.cpp:7:1: error: expected unqualified-id before 'else'

Thanks for your help as well, I’ve learned a lot so far!

Hi @Jeff

This is the compiler being strict on boolean comparisons–try this, it compiled for me.

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 == true) {
    if (databyte[0] == prefix[prefixIdx]) {
      prefixIdx++;
      searching = false;
      inPrefix = true;
    }
  }

  else if (inPrefix == true) {
    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==true) {
    if (skipCount++ == NSKIP) {
      reading3 = true;
      skipCount = 0;
      readCount = 0;
    }
  }

  else if (reading3=true) {
    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);

}
}

Hi guys !
I just ordered my sparkcore and I will see if I can modify my teensy/arduino artnet library for the sparkcore.
Do you guys know if there’s a way programatically to know if we’re on the sparkcore or another board ?
here’s the link to the library:

2 Likes

Hi @nlecaude

There was a recent change to this #define–the details are here:

Hi @nlecaude – I actually came across your library on GitHub while trying to get my original code to work, but trying to port it to Spark was just way beyond me.

If you manage to port it over, I’ll be your #1 fan! :smiley:

Thanks @bko, it’s looking much more promising now. That code outputs values now. The weird thing is that it seems to always provide the same values, even when those bytes are changing (verified by packet sniffer).

x is always 536874920
y is always 536876605
z is always 536874688

The hex for these strings is 20000fa8, 2000163d, and 20000ec0 respectively, but I can’t find these in the packet, even if I take away the 2000 at the front.

Here is the packet sample sample (you can see in the fourth row the three ff bytes which are the values we want as x, y and z respectively, and should output as 255 after conversion from hex to integer:

My thinking is that it must be pulling more information than it should be and adding it together, but I don’t understand how…

Those look like memory addresses in the core memory. How are you printing them? Just Serial.println() as you show above or something else. There might be a pointer versus value confusion somewhere since x, y, and z should be 8-bits each. You probably want to print them in hex or something since a value 0x00 is not an easy ASCII character to see.

Yeah, just the Serial.println() a per the code. Would make sense if it’s a memory address, as only the last four characters printed change (although the output is the same even after reboots…)

Will have to look into printing them in hex tomorrow, and see how it goes from there.

I’ve been trying to figure it out, but just can’t figure out why the hex won’t convert to a decimal… I need to use a decimal to set a value on an analogue output, right?

Been following along hoping to maybe get a couple of sparks for this same purpose, I found https://gist.github.com/deftx/9377546 has anyone taken a look at that?

It looks like it's still referencing Arduino outputs, but I could change the outputs and give it a go over the next couple of days.

Hello,

I was able to make my library work however it seems that the UDP object in Sparkcore cannot read packets bigger than 512 bytes which is problematic because an Artnet frame is usually 530 bytes…

I’m hoping there will be an easier way to change this from the build IDE, but if you’re compiling locally ( https://github.com/spark/core-firmware ) then you could change the UDP buffer to be any size you like! :slight_smile:

It sounds like you’re already familiar with this, but in case you haven’t setup the local build, it’s fun to be able to change anything you want. Mohit made a great tutorial here: https://community.spark.io/t/the-spark-core-firmware/532

//here ->  https://github.com/spark/core-firmware/blob/master/inc/spark_wiring_udp.h

#define RX_BUF_MAX_SIZE	512

Thanks!
David

Hey!

I managed to get the Spark Core to receive DMX over ArtNet and transmit it over DMX using a MAX485.

I put the code and the schematics up on GitHub: https://github.com/KyotoFox/Spark-ArtNet-DMX

As mentioned you will have to compile it yourself as the buffer in Sparks UDP library is too small for ArtDMX-packages.

3 Likes

Wow great job! :smiley: :wink:

Does anyone know if the recent Spark Firmware update fixes the UDP buffer issue? I’ve been too busy to try on account of work and exams recently.

Is there any update on this?

Ive had a stab at getting Art-Net receiving working.

I’ve tried the code here https://github.com/KyotoFox/Spark-ArtNet-DMX and the Gist its’s based on here https://gist.github.com/deftx/9377546

It will work for a second or two and then will silently hang.

I’m compiling and flashing locally and have increased the RX_BUF_MAX_SIZE 576

So my test code is just setting the colour of the inbuilt RGB LED, it will work for a few seconds and then just halt.

Interested to hear of any other Art-Net successes or failures, did broadcast vs unicast make a difference etc…

UPDATE

Tried Unicast and it seemed exactly the same as broadcast.

Honestly, I gave up because of the lack of RAM available for the UDP buffer.

Instead I have utilised my Spark Core as a Smart Things node, and have turned to a Raspberry Pi with OLA for my ArtNet needs,

Perhaps the Spark Photon will provide a better platform for ArtNet networking with its increased memory.

Hi there,

I tried to compile the code using current firmware for photon but face some errors I cannot fix:

mkdir -p ../build/target/user/platform-6-m/applications/Spark-ArtNet-DMX/applications/Spark-ArtNet-DMX/
arm-none-eabi-gcc -DSTM32_DEVICE -DSTM32F2XX -DPLATFORM_THREADING=1 -DPLATFORM_ID=6 -DPLATFORM_NAME=photon -DUSBD_VID_SPARK=0x2B04 -DUSBD_PID_DFU=0xD006 -DUSBD_PID_CDC=0xC006 -DSPARK_PLATFORM -DINCLUDE_PLATFORM=1 -DPRODUCT_ID=6 -DPRODUCT_FIRMWARE_VERSION=65535 -DUSE_STDPERIPH_DRIVER -DDFU_BUILD_ENABLE -DSYSTEM_VERSION_STRING=0.4.6 -DRELEASE_BUILD -I./inc -I../wiring/inc -I../system/inc -I../services/inc -I../communication/src -I../communication/lib/tropicssl/include -I../hal/inc -I../hal/shared -I../hal/src/photon -I../hal/src/stm32f2xx -I../hal/src/stm32 -I../hal/src/photon/api -I../platform/shared/inc -I../platform/MCU/STM32F2xx/STM32_USB_Host_Driver/inc -I../platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc -I../platform/MCU/STM32F2xx/STM32_StdPeriph_Driver/inc -I../platform/MCU/STM32F2xx/STM32_USB_Device_Driver/inc -I../platform/MCU/STM32F2xx/SPARK_Firmware_Driver/inc -I../platform/MCU/shared/STM32/inc -I../platform/MCU/STM32F2xx/CMSIS/Include -I../platform/MCU/STM32F2xx/CMSIS/Device/ST/Include -I../dynalib/inc -I./applications/Spark-ArtNet-DMX -I./libraries -I. -MD -MP -MF ../build/target/user/platform-6-m/applications/Spark-ArtNet-DMX/applications/Spark-ArtNet-DMX/application.o.d -ffunction-sections -fdata-sections -Wall -Wno-switch -Wno-error=deprecated-declarations -fmessage-length=0 -fno-strict-aliasing -DSPARK=1 -DPARTICLE=1 -DSTART_DFU_FLASHER_SERIAL_SPEED=14400 -DSTART_YMODEM_FLASHER_SERIAL_SPEED=28800 -DSPARK_PLATFORM_NET=BCM9WCDUSI09 -fno-builtin-malloc -fno-builtin-free -fno-builtin-realloc  -DUSER_FIRMWARE_IMAGE_SIZE=0x20000 -DUSER_FIRMWARE_IMAGE_LOCATION=0x80A0000 -DMODULAR_FIRMWARE=1 -DMODULE_VERSION=3 -DMODULE_FUNCTION=5 -DMODULE_INDEX=1 -DMODULE_DEPENDENCY=4,2,7 -g3 -gdwarf-2 -Os -mcpu=cortex-m3 -mthumb -std=gnu++11  -fno-exceptions -fno-rtti -fcheck-new -c -o ../build/target/user/platform-6-m/applications/Spark-ArtNet-DMX/applications/Spark-ArtNet-DMX/application.o applications/Spark-ArtNet-DMX/application.cpp
applications/Spark-ArtNet-DMX/application.cpp: In function 'void setupDMX()':
applications/Spark-ArtNet-DMX/application.cpp:80:28: error: 'RCC_APB2Periph_GPIOA' was not declared in this scope
	 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
							^
applications/Spark-ArtNet-DMX/application.cpp:101:24: error: 'GPIO_Mode_AF_PP' was not declared in this scope
	 pinCfg.GPIO_Mode = GPIO_Mode_AF_PP;
						^
applications/Spark-ArtNet-DMX/application.cpp:106:24: error: 'GPIO_Mode_Out_PP' was not declared in this scope
	 pinCfg.GPIO_Mode = GPIO_Mode_Out_PP;
						^
applications/Spark-ArtNet-DMX/application.cpp: In function 'void setup()':
applications/Spark-ArtNet-DMX/application.cpp:160:36: warning: 'IPAddress spark::NetworkClass::localIP()' is deprecated (declared at ../wiring/inc/spark_wiring_network.h:44): Please use WiFi.localIP() instead [-Wdeprecated-declarations]
	 Serial.println(Network.localIP());
									^
applications/Spark-ArtNet-DMX/application.cpp: In function 'void Wiring_TIM3_Interrupt_Handler_override()':
applications/Spark-ArtNet-DMX/application.cpp:31:31: error: 'struct GPIO_TypeDef' has no member named 'CRL'
 #define set_pa2_gpio() GPIOA->CRL = 0x44334344 // Set TX to GPIO
							   ^
applications/Spark-ArtNet-DMX/application.cpp:234:9: note: in expansion of macro 'set_pa2_gpio'
		 set_pa2_gpio();
		 ^
applications/Spark-ArtNet-DMX/application.cpp:30:31: error: 'struct GPIO_TypeDef' has no member named 'CRL'
 #define set_pa2_uart() GPIOA->CRL = 0x44334B44 // Set TX to USART
							   ^
applications/Spark-ArtNet-DMX/application.cpp:244:9: note: in expansion of macro 'set_pa2_uart'
		 set_pa2_uart();
		 ^
../build/module.mk:209: recipe for target '../build/target/user/platform-6-m/applications/Spark-ArtNet-DMX/applications/Spark-ArtNet-DMX/application.o' failed
make[2]: *** [../build/target/user/platform-6-m/applications/Spark-ArtNet-DMX/applications/Spark-ArtNet-DMX/application.o] Error 1
make[2]: Leaving directory '~/firmware/user'
../../../build/recurse.mk:11: recipe for target 'user' failed
make[1]: *** [user] Error 2
make[1]: Leaving directory '~/firmware/modules/photon/user-part'
makefile:81: recipe for target '~/firmware/modules/photon/user-part/makefile' failed
make: *** [~/firmware/modules/photon/user-part/makefile] Error 2

Any ideas?

regards