Decoding the Daktronics Omnisport 2000
January 8, 2013
This is an extended version of the README on github.
This project came out of neccessity after a software-based attempt failed. I really wanted to avoid working with hardware on the system because it takes much longer than pure software, but in the end I had to for the sake of simplicity.
The timing console has three RS232 serial ports: one for the meet manager, one for a venus scoreboard, and another to connect to the PC control software. The PC software from daktronics costs a ton, so I didn't bother trying to work with that. The meet manager port is obviously used for the results, so I couldn't use that either. That left the RTD scoreboard port, which is what is used for this decoder.
The port is for a scoreboard, so logically it should at least have a running-time signal. After looking at it on a serial terminal, I figured out that it sends split times and place data as well.
Raw data from the console looks like this:
It looks like a mess, because it is. Actual data is embedded between keepalive signals, which are then contained within control characters. The periods in the example are not actually ASCII periods (0x2E), but rather control characters that cannot be rendered in the serial terminal. Browsers, however, can render them properly, and this is what a typical data packet looks like:
␖00000000␁0042100000␂ 4.0 ␄C0␗
The control characters are bolded. Everything between SYN (0x16) and STX (0x02) is irrelevant to the actual data, so it is dropped from the decoded signal. I still haven't figured out what the
0042100000 represents, but it might just be another sync signal like the string of zeroes after SYN. The
C0 is probably a checksum, but I didn't bother working it out.
\n and sequential sorting
The first stage of sorting applies these filters to all packets:
- Remove data between SYN and STX (inclusive)
- Remove data between EOT and ETB (inclusive)
- Trim leading and trailing whitespace
- Add a linefeed and carriage return to the end
The first stage of filtering returns these (names are starred out). Significantly better than the raw data, but still a lot of noise considering all I want is the running time and splits.
One more filter is applied after the first stage:
- Remove packets that do not have a period (ASCII 0x2E)
This cleans out everything except running times and splits.
Not a lot in terms of hardware for this one.
Out of the 9 pins from the console, only two are used: TX and ground. The signal is fed into the classic MAX232 to convert it down to TTL logic levels.
The latest version will always be on github.
There are two types of data packets: running time and splits. Each packet is composed of a prefix (t for running time and s for splits), the packet data, and a carriage return, which serves as the delimiting character.
Typical data packets would look like this:
t1:02.1 - pretty self explanatory
s3 1 1:11.63 2 - four data points, which are ordered as follows:
- Lane number
- Time (split times are accurate to a hundredth of a second)
- Laps of the pool completed
Decoded data is fed into Autobahn with python and then to the browser for graphic rendering. The websockets server and rendering engine is in the IASAS_swimming_2013 repository.
The decoder can be put into test mode by resetting with the split button set to the OFF position. This mode ignores data from the console and simulates a test race, which is useful for testing the rendering engine.