Forest3 Software Suite

Project overview

While studying for my MFA at Arizona State University, I was a research assistant for Christian Ziegler. We were working on the next step in his research on matrix lighting systems started in his previous works, which consisted of statically hung neon lights arranged in a rectangular grid.

For the next iteration we wanted to build out the idea of lights arranged in a rectangular grid – however this time to have the lights be able to be moved vertically the full height of the space. Here is a video of a small scale test of the system.

Throughout this process I had to design various bits of software and system to ensure the project worked as envisioned. These software projects spanned between microcontroller programming, python services, and TouchDesigner control systems.


Device Firmware:

Chris Zlaket designed and produced the circuit and electronics that control the device. We are using a 16 Mhz Teensy-LC as the micro-controller driving a 12v DC motor and two 3.3v surface mount LEDs soldered back to back.

The unit reads Art-Net packets being sent on a ENC28J60 Ethernet Controller. The devices are set up just like a standard multi-channel DMX device where they are given an address will read a number of channels from that address in the packet. These channels correspond to attributes we would like to set on the device such as LED color or height. For our implementation we decided to run with 6 channels for each device:

  1. Height (coarse) – The coarse adjustment of height.
  2. Height (fine) – The fine adjustment of height.
  3. Red – The red component of the LED color.
  4. Green – The green component of the LED color.
  5. Blue – The blue component of the LED color.
  6. Opcode – A set of operational control codes.

Addressing the devices

In traditional DMX systems, the DMX address of a device is set on-board the device using dip switches or an LCD menu. Because we were using the Teensy and pinouts were at a premium, we decided against adding another component (such as a dip switch) that would eat into more pins. The idea was tossed around to hard code the DMX address into each device in order to get around this  – but the thought of changing the programming on each and every device was painful as a programmer who actually wants a life.

Instead I arrived at having the device request an address from a server running on the control machine.

When the device boots – it checks to make sure it has a MAC address (which is stored in EPPROM) and then starts the DHCP handshake with the router. Once its given an IP address, the device looks up the control computer on the local network and sends a TCP request with its MAC address. The server sends back its DMX address which is given the first time the device is brought online.

If this whole process looks familiar, it is. This is exactly how the DCHP protocol works – just altered a bit for DMX addresses. This process allows me to address the whole array of devices without reprogramming them or knowing/dealing with their IP addresses.

Driving the motor

The motor is driven by a PID controller which runs the motor between its current location and a setpoint as fast as possible. By using this control method, I can hook the height data that I am receiving from Art-Net directly to the motor setpoint. This allows me to use the streaming Art-Net data to control the speed of the movement. The motor controller does not have to worry about timing or figuring out speed. This saves on processing time.

The height channels in the Art-Net packet act as a 16 bit number which gives me super precise control over the motor as it moves. Each step on the coarse value is 256 steps of the fine value.


The Opcodes channel in the ArtNet packet correspond to special subroutines hard coded in the firmware. For example, if a value of 255 were passed in the Opcode channel the device would re-calibrate and re-zero itself. If 50 or 51 were passed, the device would jog up or down and stay there until cleared with an Opcode of 53. We can also use this channel to tell the device to lookup it’s address again – so we can readdress the system on the fly.

These codes are helpful for debugging purposes but could also be useful in show scenarios to set lights at heights and lock them there.

Address service:

This software runs on the computer that controls the system. It was written in python so it could be cross-platform between macOS, Windows, and Linux – depending on what software package you want to use to control the system (TouchDesigner, Max, ETCnomad…). This software acts much like a DHCP server, however instead of serving IP Addresses, it serves DMX addresses.

When a device check in with this system – it looks up the MAC address in a database and returns its DMX address which is then sent to the device so it can properly read Art-Net. This system allows for quickly re-addressing large sections of the matrix or setting up different configurations.

The service has a small UI which allows the user to readdress and lookup location and MAC address of any device in the system.


TouchDesigner Controller / VR Previsualizer:

This piece of the puzzle is one of the more exciting parts. It was originally written as a way to control the system but has evolved several times to be a previsualizer, an override controller, show control and a proxy to other programs to access the system.


In the early stage of this process we needed a way to pitch the project in order to receive more funding for it. I built this visualizer as a way to allow people to experience the final product and convince them that it was worth pursuing. The original .toe file had the option of a Oculus Rift hook up so the user could see the system as if the were in it.

The visualizer uses two images to drive the height and color of the 3D representation of the matrix. This image based control extends into how the system works today and allows it to be easily manipulated within many visual programming environments.

Override controller

This element of the software allows for a user to override and control sections of the system in order to sculpt the space. The override controls allow you to select devices based on position in the system and manipulate color, brightness, and height. The override control also allows the user to send opcodes to the devices to trigger their on-board subroutines.


Show control and Proxy

The final element is the ability to run various looks into the system from video files, .tox files, or streaming from another service. The sources can be triggered from the buttons on the top which show a preview of the source and will transition in a crossfade from an AB deck.

A user can make their own tox in TouchDesigner and drag a drop it into the spare panel which will load it as an asset the can use in the system. Any UI elements they have exposed in the tox will show up in the panel so they can control the system.

Lastly, a user can stream via RSTP protocol and input into the system. This allows for videos to be played from the internet or movie players like VLC.



Continuing forward:

We are currently building out the system in have 40 devices in a 5×8 grid.




Leave a Reply