After building a couple prototype lights, I thought it would be a good idea to test the reliability of the OSC transmission over Wifi. A quick test program was written that would blink the 3 LEDs on each light at some interval that I could set. Usually this was 50ms or so. It worked fine the majority of the time, but about 1-2% of the time, one of the lights wouldn’t light up, or they’d blink in the wrong order. This is indicative of packet loss and just the general behavior of UDP, especially when used over Wifi which is of questionable reliability.

UDP has no guarantee of delivery and packets can arrive out of order or not at all. You could build some error checking on top of UDP, like some multiplayer games use, but it’s far simpler and more reliable to use the already existing TCP.

TCP ensures the data sent over the stream arrives at the other destination and in the same order. There are some downsides to TCP like unpredictable latency, but that hasn’t been too much off a problem with my testing in this application. Thankfully the OSC 1.1 standard supports sending OSC over TCP with the use of SLIP encoding. SLIP simply adds a start and a stop byte to each packet of data, so you know where a message starts and ends.

The OSC library that I had been using unfortunately didn’t support TCP transmission. Fortunately it is MIT licensed so I can fork it and add support for it myself. This turned out to be easier than I expected, since I quickly found a SLIP library that I could use. The only code I really had to write was to handle setting up the TCP connection, and that was less than 200 lines.

During development, I also wrote some example programs and rewrote my the code for the cue lights to use TCP. These are all found under the examples directory in the github repo for now, but some will eventually get their own repositories.

  • rpilx This is the program that runs on the pi and controls the lights. It listens on TCP port 8765 for incoming OSC messages in the form of /led/1/low or /led/3/high. Once it receives one of those, it sets the given GPIO pin to a high/low state. This can be cross-compiled on a Mac or Windows computer for Raspbian, which is one of the great things about Go.
  • tcpclient This illustrates how to send messages over TCP and allows testing of the cue lights. The IP addresses of the cue lights are hardcoded right now, but I’ll add command line flag support in the next update. On startup, it’ll listen for keypresses for numbers 0-9 and turn on/off certain LEDs on each light. If you press escape, it’ll then start blinking the LEDs of each light in sequence every 200ms. This is useful to test sync of the lights and is a great visual way to see packet loss and other issues that may pop up.
  • route Ever used OSCRouter? This is like that. Because QLab can only send OSC messages over UDP when using network cues(the OSC API supports TCP otherwise), you need some way to convert those to TCP if you want reliable transmission to the cue lights. In addition to listening for QLab messages it also listens for messages coming from another app that I wrote that allows a Dualshock 4 controller to send OSC messages. Those messages are then sent to QLab to allow cue navigation and playback control via a DS4 controller.
  • ds4control A month or so ago I played around with a Dualshock 4 controller and had it sending OSC messages on button presses. I ported that over to support TCP and put it in the repo. This is mainly for fun, but a few people have asked about being able to use it to control moving lights. I do intend on making this a full fledged app with a config file to set the key mapping, so it should be possible to connect this to QLab or EOS and have a light do what you want. Right now it supports basic cue navigation for QLab with the arrow keys and allows cues to started/stopped/paused/resumed with the shape buttons.

The library and the examples accompanying it are currently in their early stages and are a bit messy. I’ll be doing some cleanup and adding configuration support to all the examples soon. The cue lights have proven to be pretty reliable as I’ve tested them over the past couple weeks. TCP has definitely been worthwhile to implement, as I’m no longer seeing visible packet loss and odd behavior as I did with UDP. There is the occasional extra latency when a packet is a dropped and it needs to be resent, but this isn’t too noticeable at all and happens very rarely. I don’t think this will pose much of a problem in practice.

I’ll keep working on the code and publishing these posts alongside it. I’m working on making a control pad with some Gateron keyswitches and an Arduino Pro Micro, so that’ll probably be my next update.