The XCtrl story
There's a brilliant document written by 'FK' that basically reverse-engineered the XCtrl
protocol for when talking over a USB connection. I've been building on that work to speak to the desk over the network directly.
The main communication takes place on UDP
port 10111
, and uses the same messages as in the rest of the doc. What's most interesting though is that you can chain multiple messages into the same packet (size limiting of course). One of the limitations mentioned in that doc is that the meters can only be updated in turn, every ~1.2 seconds. But chaining 8 updates into the same packet, and they all update at once. This also applies to the other controls of the desk, so for getting feedback into the desk, you can pretty much spit an entire surface update at it as often as you like, without having to worry about individual changes.
For experimenting, I've been playing with a 'client' of sorts written in Ruby (what else). It's based around independent threads for sending and receiving, and a third worker thread to deal with things coming in.
@incoming_xctrl = Queue.new
@outgoing_xctrl = Queue.new
@xctrl = UDPSocket.new
@xctrl.bind('192.168.x.x', 10111)
# sender
Thread.new do
loop do
message = @outgoing_xctrl.pop(true) rescue next
@xctrl.send([0xf0, *message, 0xf7].pack('C*'), 0, '192.168.x.x', 10111)
end
end
# receiver
Thread.new do
loop do
message = @xctrl.recv(32) or next
@incoming_xctrl.push(message)
end
end
# processor
Thread.new do
packet = @incoming_xctrl.pop(true) rescue nil
next unless packet
# do something fun
end
The X-Touch maintains a heartbeat, to make sure it won't 'disconnect' from our client. This is really plainly built at the moment:
HEARTBEAT = [0x00, 0x00, 0x66, 0x14, 0x00]
message = packet.to_hex_string
case message
when "f0 00 20 32 58 54 00 f7" then @outgoing_xctrl << HEARTBEAT
end
It seems to keep the X-Touch happy, and means we can play with everything else that the desk can spit out. Next up, VBAN
.