While working at the WE Global Learning Centre, one challenge that arose was the inability of the video switcher operator to directly control the PTZ cameras in the main production space. Although the board (a Ross Carbonite Black 2S) had an integrated joystick and native support for several PTZ camera models, the Vaddio RoboShot 30 cameras were not among those.
During shows, the director would either have to set up their shots in advance, or turn away from the switcher to use an onscreen interface through a Crestron XPanel terminal located behind them. Obviously, this wasn't ideal since it took longer, was less precise, and distracted the operator.
During one period of downtime at the GLC in early 2019, I decided to see what could be done to resolve this longstanding issue. Reading into the documentation, I noticed that the Ross board supported several Sony cameras using VISCA, a proprietary Sony protocol for camera control through a serial cable. On the other hand, the Vaddio cameras used a Telnet interface and required a login to be sent before each command.
Hardware
To translate between VISCA and Telnet, I took advantage of the fact that the Ross switcher was located in a rack beside a Crestron AV3 control processor with a free COM port, and the Vaddio cameras were already integrated with another AV3 on an upper floor of the building. A custom cable was needed to connect the RJ45 jack on the switcher with the Phoenix connector on the AV3, but that was pretty straightforward, and once that was done all the physical infrastructure was in place - just the programming left.
Software
The software was definitely the most complex part of this project. From start to finish, it took an entire work week, and 4 of those 5 days were spent programming. Due to the complexity of the integration, I decided early on to not bother with SIMPL (Crestron's visual, symbol-based programming language) and instead to finally learn SIMPL+, a more powerful text-based IDE based on C+ and tightly integrated with SIMPL.
The VISCA protocol is based around packets and addresses, and each command packet ends with the hexadecimal character 0xFF. The first step in the programming was to set up a serial input which scanned for this terminating character and used it to break the communication stream into discrete bytes, which could each be handled separately. VISCA addresses start at 0x80 and go up from there. I was dealing with four cameras, so the only step necessary to interpret the address byte was to XOR with 128, leaving just the last digit, which I then used as an index into an array of output signals. However, the switcher did occasionally try to send "Set Address" commands to the cameras. Rather than pass these along, I hardcoded a response at the top of the script which returns the correct response (the attempted address plus one).
The most important functions to get working with this implementation were a) movement, b) zoom, and c) memory store/recall. Movement was definitely the trickiest of the 3, since it required both stop and start messages, and also needed the tightest timing to ensure the operator could use the controls during a show. We found while testing that the latency from joystick to camera needed to be less than 0.5 seconds. VISCA divides movement into eight directions, including the four cardinal directions and the diagonals. However, the PTZ cameras needed pan and tilt to be controlled separately. In SIMPL+, I wrote a switch statement to look at incoming movement commands and identify which pan/tilt lines needed to be set high for a particular movement, keeping in mind that each motor (pan + tilt) actually needed two signals, one for movement in each direction.
Similarly, zoom commands were easy enough to handle, since zoom only had two possible directions - in and out. At this stage, I also repurposed the autofocus on/off VISCA command as a Hi/Lo speed switch for camera movement, allowing fast movement when necessary but also fine control.
One important note is the way movement works with both VISCA and the Vaddio Telnet interface. Rather than a stepper motor, where commands tell the motor to move a certain number of steps (equating to a known distance), movement commands tell the camera to start moving, with a separate "stop" command needed to stop the movement. In theory, if the network disconnected between the start and stop commands, the camera would keep moving until it hit its limits. This was an issue I ran into later, but not for network reasons (spoiler alert).
I also had to add a few lines of code to respond to query packets, which the controller (the Ross board, in this case) uses to make sure the camera is alive and working. Rather than tying this into the actual cameras, I just set it up to return blank data, which the controller seemed happy enough with.
Crestron
To tie these two systems together, I built a quick SIMPL (not SIMPL+) program that let the main floor and basement Crestron processors talk to each other over the network. Since the main Crestron processor upstairs already had signals and programming defined for dealing with the Telnet login and commands required to make the Vaddio cameras work, I just loaded this "shim" program into an empty slot on the basement AV3 and let it constantly stay active and connected to the main program.
Issues
After about two days of this programming work, I reached a point where the two processors could exchange the Crestron signals needed to move the cameras, but I was seeing incredibly high latency and unreliability. I could start a camera move, but it would take over a second to even react, and the system seemed to ignore stops entirely.
Finally, after about another day of troubleshooting, I realized that I had missed part of the VISCA protocol - acknowledgement. To make sure the camera is moving properly, and not damaged or disconnected, the controller waits for the camera to send an acknowledgement (ACK) when it receives a command, and another message when it completes the move. It turns out that if these query packets are not responded to, the controller will stop sending commands entirely, thinking it's overloaded the camera. This is what was causing all the frustration. The controller was happy to send the first command - which started the camera moving - but wanted the camera to acknowledge that command before it sent another. This meant that when the operator let go of the joystick, the "stop" command was never getting sent, and the camera never stopped moving. To solve this final issue took only two lines of code. As soon as a command was received, I sent an ACK and a "Complete" message in quick succession - this was far easier than tracking the camera's movement and generating genuine status updates. The controller didn't seem to care, and from that point on the solution worked perfectly.
Lessons Learned
I definitely learned a few lessons from this endeavor. First and foremost - published protocols and integration guides are a lifesaver. Even though VISCA is proprietary to Sony as far as I know, the fact that I was able to find a published spec sheet let me use the "language" to talk to any device I wanted. Second, from a live events perspective, I learned the value of having a physical controller for any remotely-controlled cameras in the production space. The increase in fine control and repeatability, as well as eliminating the need for the operator to turn around and use a completely different station, really enhanced our shows. Finally, cost-benefit analysis. On the one hand, I did save the $3000-5000 it would have cost to either buy a standalone Vaddio controller, or sell the old cameras and purchase new, compatible models. On the other hand, it took a week of my time, and there was no guarantee the project would turn out to be a success. In the end, I chalk this one up as a huge win. It was during a relatively slow period for events, and the skills I learned saved money for not just my employer at the time, but anywhere else I go in future.
If you're a Crestron programmer and you'd like to take a look at my SIMPL+ program for integrating VISCA with Crestron programs, please don't hesitate to drop me a line!