2011-12-01

Shooting Chrony and Linux kermit scripting

Shooting Chrony bullet velocity chronographs can be connected to a rs232 serial port to read velocities to a computer. For the serial protocol, see this page: nopLabs. To use the protocol in Linux, one simple way is to use Kermit to run a script. The script below gives the necessary commands and produces a file velocities.txt that is easy to parse for the data.

First install the kermit program. Then run the below script with it. As the serial speed is only 4800 bits/second, it will take about 5 seconds to read the stuff out of the Beta Chrony with 60 shot memory. If you are using a Gamma Chrony with larger memory, it will take considerably longer, I would guess 40 seconds.

You will need to adjust the script for the first line if you are not using an USB serial adapter, and the 50 second timeout after the X.GEE command if it takes longer to read out data. You'll need to add X.HXF commands to dump all of the Gamma Chrony memory. After the X.HXF commands you need to reset the device from power switch or issue X.HXB commands until you are on page zero if you want to do another hex dump.

set line /dev/ttyUSB0
set carrier-watch off
set flow-control none
set speed 4800
set serial 8N1
set input echo off

echo Entering command mode
output SYSX\13
input 1 rdy>
# If we already are in command mode,
# the above prompt will not be displayed,
# so ignore the result.
log session velocities.txt
echo Reading system information
output X.QRY
input 3 rdy>
if failure goto noconnection
echo Reading raw EEPROM
output X.HXD
input 4 rdy>
echo Reading velocities
output X.GEE
input 50 rdy>
echo Exiting command mode
output X.END
input 1 ok!\13
echo Done.
quit

:noconnection
echo No connection to Chrony
exit 1

Example output file:

{
Shooting Chrony, V6.03i,25/DEC/1999,0Me-003C-1
Len=12.000-in Fre=12.000-MHz OSt=98304
System: 10000000+00000000
FreeMem,    0000nm
Strings,    0006nm
Current,    0001nm
RecSize,    0010nm
}ok!
0:rdy>{
0000: 01 00 23 FF FF FF FF E0 44 8B 2C 8B F1 8B 14 8B
0010: 98 8C BD 8B 11 8C 24 8B CC 8A 21 8C 96 8B 8E 8B
0020: 08 8A D2 8B 99 8C E1 8B 43 8C CB 8A 31 8C 3D 8B
0030: 83 8A 01 8A 83 8B 1D 8B 61 8B FF FF 96 8C 34 A3
0040: 79 8C 35 A3 70 2B C4 2A B0 2A 09 2B 7B 2B F5 2A
0050: 8F 2B F1 2A 18 2B CC 2B 14 2C F4 2A EE 2A 65 2B
0060: E0 2A C3 2A C1 2A CD 2A 53 2B FF FF 13 2B 16 2B
0070: 98 2B 1F 2B 46 2B 56 2B 84 2B C6 2A 2F 2B 10 2B
0080: }ok!
0:rdy>{
,    0010nm
-01-,    0001nm,    83.27Vm
-02-,    0001nm,    83.45Vm
-03-,    0001nm,    81.99Vm
-04-,    0001nm,    83.64Vm
-05-,    0001nm,    80.79Vm
-06-,    0001nm,    82.37Vm
-07-,    0001nm,    81.76Vm
-08-,    0001nm,    83.52Vm
-09-,    0001nm,    84.19Vm
-10-,    0001nm,    81.64Vm

,    0010nm
-01-,    0002nm,    82.66Vm
-02-,    0002nm,    82.72Vm
-03-,    0002nm,    85.72Vm
-04-,    0002nm,    82.22Vm
-05-,    0002nm,    80.79Vm
-06-,    0002nm,    82.11Vm
-07-,    0002nm,    81.40Vm
-08-,    0002nm,    84.19Vm
-09-,    0002nm,    81.53Vm
-10-,    0002nm,    83.33Vm

,    0005nm
-01-,    0003nm,    84.75Vm
-02-,    0003nm,    85.78Vm
-03-,    0003nm,    82.80Vm
-04-,    0003nm,    83.57Vm
-05-,    0003nm,    83.06Vm

,    0010nm
-01-,    0004nm,   331.79Vm
-02-,    0004nm,   337.01Vm
-03-,    0004nm,   337.62Vm
-04-,    0004nm,   334.90Vm
-05-,    0004nm,   331.47Vm
-06-,    0004nm,   335.50Vm
-07-,    0004nm,   330.87Vm
-08-,    0004nm,   335.63Vm
-09-,    0004nm,   334.44Vm
-10-,    0004nm,   329.07Vm

,    0009nm
-01-,    0005nm,   326.97Vm
-02-,    0005nm,   335.54Vm
-03-,    0005nm,   335.72Vm
-04-,    0005nm,   332.12Vm
-05-,    0005nm,   336.15Vm
-06-,    0005nm,   337.04Vm
-07-,    0005nm,   337.10Vm
-08-,    0005nm,   336.73Vm
-09-,    0005nm,   332.66Vm

,    0010nm
-01-,    0006nm,   334.59Vm
-02-,    0006nm,   334.50Vm
-03-,    0006nm,   330.60Vm
-04-,    0006nm,   334.23Vm
-05-,    0006nm,   333.05Vm
-06-,    0006nm,   332.57Vm
-07-,    0006nm,   331.20Vm
-08-,    0006nm,   336.94Vm
-09-,    0006nm,   333.74Vm
-10-,    0006nm,   334.68Vm
}ok!
0:rdy>{}ok!

EEPROM encoding

If you use the X.HXD command to dump EEPROM contents, the values after an 8 byte header are the 2 byte little endian count of clock ticks between bullet shadow signal from sensors. The sensors should be 30.48 mm (one imperial foot) apart. My sensor windows are 30.6 mm apart, which would account for 0.3 % error in results. I cannot see if the sensors under the sensor opening are not in the same position in both sensors, so they might be 30.48 mm apart. The clock frequency is 12 MHz.

Values over 32768 are encoded so that the real value is 32768+4*(X-32768), where X is the EEPROM value. That is, the numbers stored increase only 1/4 of the real value increase after 32768.

The formula for converting these tick counts to m/s that I got from comparing given m/s (metric) values with tick values is: V=3689481/ticks. This is not exactly what comes from formula 12000000*0.3048 = 3657600 and not even from the length between the sensors I assume is correct 12000000*0.306 = 3672000, so maybe there is something experimental in it or something else going on with the computation in Chrony. Or it is an optimization for the division operator in the microcontroller program code. Or maybe the distance between sensors is 30.75 mm or the real clock frequency for the timer is 12.1 MHz.