Drawing of Trippy
  

Trippy PTZ Webcam

BT protocol, Board V 1.00, Firmware V 0.17

Part of the Trippy web pages
by Douglas W. Jones
THE UNIVERSITY OF IOWA Department of Computer Science

Copyright © 2000, Basic Telepresence Inc., revised, corrected and annotated, 2022, Douglas W. Jones.

Introduction

Communication with the Serial Trippy is over an asynchronous communications line. Commands to the Trippy are interpreted by an embedded microprocessor within the Trippy; this microprocessor interprets a very simple ASCII coded command language. All commands that are not understood or correctly received by the Trippy will be ignored, and the Trippy will never generate output except in response to a command.

The Serial Trippy interface operates at 9600 baud, 8-bit data, odd parity, one stop bit.

In developing the code, we investigated having the Trippy automatically detect the baud rate. The prefix BT on every Trippy command looks different at each baud rate and we figured out how we could take advantage of this, but I have no evidence we ever implemented this feature.

The command set for the Trippy is designed in anticipation of cabling systems that allow multiple Trippys to be connected to one communications line. For this reason, each Trippy may be programmed to respond to a different address.

While we did design an RS232 splitter board to allow this, I don't know that it was ever used.

BT Command Format

All commands to the Trippy begin with the command prefix BT, and the command language for the Trippy is frequently referred to as the BT command set. The prefix BT is always in upper case. The string BT never occurs in any Trippy command except as a command prefix, and wherever it occurs, even if dropped accidentally into the middle of some other command, the Trippy will interpret it as the prefix for a new command.

The space character never occurs in a BT command. Spaces are included in the syntax outlined here for readability. Angle brackets <> are used to set off metasymbols, square brackets [] are used to indicate that a syntactic element is optional, and curly braces {} are used to indicate that a syntactic element may occur zero or more times. These symbols do not occur in the BT command set itself, with the exception of the ] operator, and are used only to describe commands.

All commands have the following syntax:

   BT [ <address> ] { <operation> } <carriage return>

Addresses are decimal numbers, while variable names are mixed alphabetic and symbolic, and operations are symbolic and numeric. (The ASCII carriage return is coded 0D hex.) Thus, for example, the command

   BT?

is the shortest useful BT command. This has no address, specifies no variable, and has the ? operation, requesting a status report from any Trippy connected to the communications system. The more complex command

   BT66X?

asks for Trippy number 66 to operate on the internal variable X with the the ? operation, requesting a report of the value of the variable X.

BT commands terminate with the first character encountered that cannot be interpreted as a command. By convention, it is suggested that each BT command be followed by a line terminator such as CR or LF. Transmission errors (parity errors or overrun errors) will also terminate a BT command.

Addressing

Trippy addresses are decimal numbers:

   <address>   = <number>
   <number>    = { <numeral> } 

An address that is absent (containing no digits) is equivalent to address of zero.

On receiving a BT command, a Trippy will ignore that command if the address is nonzero and differs from the Trippy's own address. The Trippy's own address is a variable that may be set using a BT command, and commands with address zero will be interpreted by all Trippys that receive them.

It is anticipated that a cable or hub will be introduced for the Serial Trippy allowing multiple Trippys to be connected to one serial port. When this is done, each Trippy should be configured to respond to a different address.

As far as I can recall, we never used this feature.

Trippy coordinates and mechanical limitations

Trippy tilt and pan coordinates are measured in units of one step, where the step size depends on the gear ratio. Several gear ratios were anticipated to handle different payloads (cameras). Each Trippy should be labeled in variables S and T with its gear ratio. Gear backlash and other mechanical considerations will generally reduce the achievable mechanical resolution to around 1 degree.

Early versions of the Trippy included code to normalize all coordinates so that tilt and pan angles were in units of 1/32 degree, assuming that all Trippys were geared identically. Later, we realized that different gear ratios would be used in different models, so personality variables loaded from EEPROM memory were added so the Trippy could be informed of its gear ratio and work with raw one-step coordinates.

A Trippy is nominally able to pan over a 270 degree range, although the actual range depends on the setting of the optional mechanical tilt and pan stops.

BT Variables

The embedded microprocessor in each Trippy contains 96 variables, the first 27 of which are addressable by name. The named variables begin with @, followed by the 26 letters A to Z. These are stored in order in memory. These variables may be set, inspected or manipulated using the BT command set, and are used to control the behavior of the Trippy.

   <operation>     = <variable name>
   <variable name> = @ | <letter>

The following variables are likely to be frequently used during routine operation of the Trippy:

   X  -- goal x coordinate of the Trippy (rotate)
   Y  -- goal y coordinate of the Trippy (tilt)
   Z  -- goal z coordinate of the Trippy (zoom)
Adjustments to these variables are the usual way to move the Trippy. Thus, BT5X10+, causes Trippy 5 to increment X by 10, causing it to rotate 10 steps to the right. Assignments to X or Y that set these values outside the bounds set by M, N, O and P will produce unpredictable results!

The following variables must be initialized prior to use of the Trippy, but they are typically set only once at startup and then ignored:

   W  -- the configurable address of this Trippy
The command BTW593= sets the address of the Trippy to 593. After this, the Trippy will respond to commands beginning with the prefix BT593. It is anticipated that later releases of the Trippy will include provisions to make W read-only once it is set to a nonzero value.

   V  -- maximum allowed velocity for Trippy motion
This maximum applies to both tilt and rotate, and is measured in arbitrary units that depend on the structure of the acceleration table. Values of V at or above the size of the acceleration table or below 0 should be avoided.

   M  -- maximum x coordinate of the Trippy
   N  -- minimum x coordinate of the Trippy
   O  -- maximum y coordinate of the Trippy
   P  -- minimum y coordinate of the Trippy
   Q  -- maximum z coordinate of the Trippy
   R  -- minimum z coordinate of the Trippy
In addition to any hard stops for tilt and rotate provided by the Trippy mechanism, soft stops are included in the software that should be set to prevent the Trippy banging into the hard stops during high speed motion and to limit the field of view where this matters. Setting these variables so that I, J, X or Y are outside of these bounds can produce unpredictable results; setting M < N or O < P can produce unpredictable results.
   S  -- steps per 360° pan
   T  -- steps per 360° tilt

The variables S and T were never used by the Trippy firmware. Rather, when a Trippy was configured, these were set to reflect the gear ratios in that Trippy, and applications that work in degrees can read these variables to get the values needed to convert degrees or any other physical unit of angle into steps. This puts the burden of multiplication and division for scale factors on the host where this is easy instead of on the microcontroller where they are slow and difficult.

   L  -- power level (percent).
When the Trippy is idle, the power consumed by the motors can be reduced. If L is 0, the motors will be turned off when idle, so the only thing holding the Trippy in position will be friction. if L is 100, the motors will be fully powered, working to hold the Trippy in position.

Power was controlled using pulse-width modulation, done in software on the microcontroller. Because of the time taken by the interrupt service routines, power levels below something like 10 were equivalent to 0.

   I  -- current x coordinate of the Trippy (rotate)
   J  -- current y coordinate of the Trippy (tilt)
   K  -- current z coordinate of the Trippy (zoom)
When the Trippy is idle, I=X and J=Y. If assignments to variables cause one or both of these to become unequal, the Trippy will begin to tilt and or rotate. As the Trippy moves, I and J are adjusted to reflect the move. Assignment to I and J should be avoided except during initialization, and assignment of values outside the bounds set by M, N, O and P will produce unpredictable results!

Tilt and pan moves were done independently and could take place at the same time. Zoom, however, was done by generating 40kHz signals (for the infra-red zoom control) entirely in software, requiring interrupts to be disabled. As a result, the microcontroller only attempted to change the camera's zoom setting when motion was stopped.

   A  -- accessory control
The low byte gives access to pins of J5 and J6.

   B  -- block number in personality memory
Blocks 0 to 6 are automatically loaded into the control variables variables on startup, starting with A (so @ is uninitialized). Each block holds 15 consecutive 16-bit variables (plus a checksum). There are 256 available blocks in EEPROM. See the / and \ commands that that transfer data to and from EEPROM.

The following variables are used to configure the use of infrared output, used when various functions such as camera zoom are controlled by modulated infrared signals:

   C  -- microseconds per carrier cycle (10-127)
   D  -- High 8 bits: carrier cycles per 1; low 8 bits: cycles per 0
   48 -- Zoom out string: High 8 bits: length; low 8 bits: variable number
   49 -- Zoom in string:  High 8 bits: length; low 8 bits: variable number
These are typically configured at startup and remain fixed so long as a particular camera is in use. Zoom in and zoom out strings are loaded in high memory beyond the acceleration table and, on demand, are sent out on the IR port (J6 pin 5). For a 40kHz carrier, the most common case, C will be 25. While 40kHz is an industry standard, there appears to be no standard for encoding data on the 40kHz carrier, hence the provision for control of the encoding and transmission of arbitrary strings, both here and with the $ operator.

Variable numbers begin at @ which is 0, so A is 1. Addressing variables above Z was a bit ugly; see the , and ] (comma and index) operators, among others.

The following variables are also defined but are unlikely to be referenced by BT commands except for diagnostic purposes:

   @  -- the accumulator, used to accumulate numbers.
This is the default variable, set to zero when the prefix BT is encountered and re-zeroed whenever its value is combined with or assigned to a variable. Thus, BT? returns zero, and BTnnnn? returns the value nnnn, where nnnn is some decimal number.

   G  -- steps remaining until end of current pan move
   H  -- steps remaining until end of current tilt move
While the Trippy is in motion, these variables are used to count the number of steps remaining until the end of the move. They will be zero when the Trippy is not tilting or panning.

   F  -- contains 2 8-bit counters used to time the Trippy's moves
   E  -- contains 2 8-bit velocity indicators
if both are zero, the Trippy is not in motion.

At power-on and after sofware reset, the entire block of variables is loaded from the EEPROM. Generally, for any particular Trippy application, the variables will be set and then stored once in the EEPROM, which will never be changed until the application is changed.

The unnamed variables following Z are the acceleration table; this table contains 24 entries, 8 bits each, packed two per variable, most significant byte first. The acceleration table is used to configure the Trippy for the dynamic characteristics of the payload it carries. Acceleration table entries should be initialized at startup and should not be modified or inspected after this except for diagnostic purposes.

Variables beyond the acceleration table are available to hold zoom control strings and strings sent to the camera (or other device) using the $ operator.

BT NUMERIC INPUT

The operation set specifies values to be used and how these values are to be used:

   <operation> = <number>
   <number>    = { <numeral> } 

A sequence of decimal digits are allowed, specifying a decimal number. Numbers are accumulated in the 16 bit binary accumulator @, so values up to 65535 are allowed, however, most numbers are interpreted using 2's complement notation, so values above 32767 are interpreted as negative numbers and should generally be avoided! (The value 65535, for example, will be interpreted as -1, and it can be entered as 1-, using the - operator to negate the previously entered number.)

Attempts to enter numbers that cannot be represented in 16 bits will result in an error message and the abandonment of the remainder of the BT command sequence. Formally, whenever a digit is encountered, the accululator @ is multiplied by 10 and the value of the digit is added. Errors are detected if the multiplication or addition operations lead to a carry out of the high bit of the accumulator @.

The way numbers are accumulated means that 1-1 means ((-1)×10)+1. See the - operator. This might mean -9, except that -1 is the same as 65534 in the 16-bit 2's complement system, and 65534×10 produces an overflow, aborting the entire BT command.

BT Operators

   <operation> = <operator>

In general, operators apply to the most recently named variable and the most recently given number (stored in variable @). If no number was given, a value of zero is assumed. If no variable was given, the variable @ itself is assumed; the primary value of the latter is for diagnostics.

The most common operators are:

   =   assign @ to the variable, clears @, move to next variable.
   -   negate @
   +   add @ to the variable, clears @, move to next variable.
   ?   requests a the value of the variable, move to next variable.
   !   wait until Trippy idle before continue processing command.
For example, the command
   BT?

asks any trippy that is listening to report the value it holds for the variable a; all should simultaneously report zero! The command

   BT659?

asks for the Trippy with address 659 to give the value of @ (the accumulator), which is zero, while

   BTX659=

asks any Trippys that are listening to set variable X to 659.

Multiple operations may be combined in one BT command. Thus, for example

   BT1X320-=Y640=

asks Trippy 1 to move to X=-320 and Y=640, or 10 degrees down and 20 degrees right assuming 32 steps per degree. Because X and Y are consecutive variables, we can also accomplish the same goal with

   BT1X320-=640=

In the above, we've taken advantage of the fact that the = operator always advances the variable pointer with each use, allowing easy assignment to consecutive variables. The + operator also does this, so

   BT1X32+64-+

asks Trippy 1 to increment X by 32 (one degree) and decrement Y by 64 (2 degrees). The following two sequences ask any Trippy connected to the line for the values of X and Y; if more than one Trippy is connected, the result will likely be garbled:

   BTX?Y?
   BTX??

Note that, from the start, the Trippy had no difficulty with changes to X and Y during motion. Changing these merely changed the goal. The Trippy would smoothly accelerate, decelerate or change direction as needed by the new goal. A sequence like BTX10=X10-= would start a move toward X=10 and then immediately change the goal to X=-10, possibly reveresing the direction of motion. In contrast BTX10=!X10-= would complete the move to X=10 before moving to X=-10.

Less common operators, typically used only for configuration, are:

   ~   logical not @
   <   assign @ to high byte of variable, clear @, no move to next variable.
   &   and @ with variable, clear @ and move to next variable.
   |   logical or @ with variable, clear @ and move to next variable.
   ,   move to next variable.
   ]   index by interpreting @ as a variable number, then clear @.
   #   output firmware version number V0.17 and restart Trippy.
   .   silently terminate command without waiting for carriage return

The operators ~, & and | were added late during development after the variable A was committed to the accessory port(s) of the Trippy. Individual bits of this variable were attached to different pins of the accessory ports, so bit manipulation was needed to set or inspect these bits. This had to be done on the Trippy, not on the host computer, so a single bit on the port could be changed without creating glitches on other bits.

The , (comma) operator provides an alternate way to address named variables. For example, the following two commands are equivalent ways to request the value of the accumulator (both should return zero):

   BTA?
   BT@,?

Many operators increment the variable number in order to simplify use of consecutive variables, and variables beyond Z are typically loaded in blocks. To address variables beyond Z individually, use Z,,,, with the number of commas indicating how far beyond Z, or use the ] operator.

Assignment to and inspection of the acceleration table (the unnamed variables immediately following Z) is done by using the auto-increment features of the = and ? operators. So

   BTZ,????

skips over the variable Z and reports the values of the following 8 acceleration table entries, returned as 4 16-bit values. Note that it is unsafe to request reports on the values of more than about 8 consecutive variables.

Curiously, the limit of 8 consecutive variables is due to limits on the input queue size from the host computer, not a limit on the output queue size. For output to the host computer, the control firmware blocked awaiting space in the output queue, and the Trippy supported hardware flow control using the RS-232 RTS and CTS lines. The Trippy did not support flow control on the data channel from the host.

The ] (index) operator uses the accumulator @ as a variable number. It is an error if the value @ is greater than 95. After the variable number is taken from the accumulator, the accumulator is cleared. For example, the following commands all request the value of A:

   BTA?
   BT@,?
   BT@1]?
   BT]1]?

In the final two examples above, the first operator after the BT prefix (@ or ]) is required to end the address. Similarly, we can inspect the first word of the acceleration table with either of the following:

   BTZ,?
   BT]27]?

Both of the following assign identical values to the first 8 entries in the acceleration table:

   BTZ,64104=20291=15157=12590=
   BTZ,250<104+79<67+59<53+49<46+

The first example assigns these entries pairwise, while the second uses the < (shift) and + (add) operators to construct the entries in a more legible fashion.

Output may be sent to the IR port (J6 pin 5) using the following command:

   $   output command string starting at current variable, @ words.

Note that variables C and D control the carrier frequency and representation used for zeros and ones in the command string. Bits of the command string are sent most significant bit first and bytes of each variable are sent most significant byte first, with no framing between bytes. That is, any framing required by the IR receiver must be explicitly included in the data.

Later, when we supported the Sony brick camera, zoom was controlled by a serial data link from the Trippy microcontroller to the camera. Instead of sending strings to the camera by modulating a 40kHz IR LED, we sent the strings over the serial data line to the camera. Strings were specified the same way.

The EEPROM is accessed with the following commands:

   /   save from current variable, @ words, to block B.
   \   restore to current variable, @ words, from block B.

So, for example, BTB=A15/ will save variables A through O (15 variables) to block 0 of the EEPROM. From here on, when the Trippy powers up, it will restore the variables to these values so long as the checksums on all 96 variables are correct. Only one block may be saved or restored at one time.

On saving a block to EEPROM, a 16-bit checksum is appended to that block, and on restoring from EEPROM, this checksum is checked. The BT command will be aborted if a checksum error is encountered.

To reset the variables from EEPROM and report success, use a command like BTB=A15\@0?. The @0? will report back to the host computer on success, while it will be skipped if there is a checksum (or any other) error.

Note that, on startup the Trippy will attempt to initialize all 95 variables (except @) from EEPROM. If there is a checksum error in any of the 7 blocks involved, all of memory will be set to zero. On a Trippy board that had ever been used before, none of the checksums would be initialized, so start-up initialization would have a (1/65536)7 chance of not encountering a checksum error.

Result Codes

The Trippy will not respond in any way to text it receives prior to a BT command, nor will it respond to BT commands with incorrectly formed addresses or addresses it does not recognize.

On receipt of the carriage return following a correctly addressed BT command, the Trippy will respond with a linefeed (0A hex). Use of a period as a command terminator causes this response to be suppressed.

A carriage return following a period causes no response because it is ignored as being text prior to a BT command.

On encountering an error in a BT command (for example, numeric overflow, an unrecognized command, etc), the Trippy will respond with a question mark followed by a linefeed.

The ? command causes the Trippy to report back to the user the value of a single variable. All result reports are in the following form

   = [ - ] <number>

(with no intervening spaces). The number will conventionally represented, with the minus sign present if the number is negative and a value in the range 0 to 32768 (the anomolous 2's complement value -32768 is printed as such).

Acceleration Table

The Trippy measures time in units of 1/5000 of a second (0.2ms or 200μs); entries in the acceleration table give the time interval between successive steps during acceleration and deceleration of the Trippy around the pan axis. Thus, an acceleration table entry of 5 describes a (very high) speed of 1000 steps per second (125 degrees/second at 32 steps per degree), while an entry of 50 describes a modest speed of 100 steps per second (12.5 degrees/second) and 250 describes a low speed of 20 steps per second (2.5 degrees/second). Note that the second hand of a clock turns at 6 degrees per second.

The corresponding speeds and rates of acceleration available on the tilt axis are exactly half of the speeds quoted above.

This is a function of the gear ratio of the crown gear on the tilt platform and the bevel gear at the top of the Trippy shaft.

The torque available from the motors in a Trippy is insufficient to start a heavy payload rotating at high speed from a standing start. Therefore, the motors in the Trippy must be "ramped up to speed" gradually. The acceleration table loaded into the Trippy describes the plan the Trippy will use for acceleration, in terms of the delay to be used between consecutive steps during acceleration.

The maximum allowed velocity for Trippy motion, V, indicates the highest entry to be used in the acceleration table. Thus, V does not directly set the maximum velocity, but rather, it sets the highest acceleration table entry that will be used.

For constant acceleration, successive table entries should be in the following ratios; the example gives what is almost the lowest constant acceleration the the Trippy is able to handle:
Entry Ratio ticks/step deg/sec(pan)
0 1.000 x 250 2.5
1 0.414 x 104 6.0
2 0.318 x 79 7.9
3 0.268 x 67 9.3
4 0.236 x 59 10.6
5 0.213 x 53 11.7
6 0.196 x 49 12.7
7 0.183 x 46 13.5
8 0.172 x 43 14.5
9 0.162 x 41 15.2
10 0.154 x 39 16.0
11 0.147 x 37 16.8

In general, the ratio for each entry above the first is given by:

   ratio(i) = sqrt(i)-sqrt(i-1)
And, the number of degrees per second on the tilt and pan axes are:
   deg/sec(pan) = (5000 x 0.125)/(ticks/step) = 625/(ticks/step)
   deg/sec(tilt) = (5000 x 0.0625)/(ticks/step) = 312.5/(ticks/step)
The torque available from the motors in the Trippy falls off at high speed, so when crafting an acceleration table for a lightweight load to be moved at high speed, a constant rate of acceleration will not suffice. In general, acceleration tables must be crafted empirically, as the appropriate table depends not only on the mass of the payload but also on its shape, mass distribution and rigidity.

Initialization

In order to avoid causing unpredictable results, variables should be initialized in a carefully defined order. Assuming the Trippy has just been powered up with an uninitialized EEPROM, a checksum error will occur and all variables will be zero. The following sequence of operations should bring the variables into a reasonable order:

Step 1: Set the acceleration table and initial velocity limit.

   BTI==X==E====.
   BTZ,250<104+79<67+59<53+49<46+43<41+39<37+.
   BTV11=.
No Trippy commands that could initiate motion should be sent prior to configuring the acceleration table. Clearing I and X stops any pan that might be in progress, and clearing J and Y stops any tilt that might be in progress. Clearing E to H reinforces this. These clear steps are redundant if the EEPROM really did have a checksum error, but if nonsense was accidentally stored in EEPROM, they allow recovery.

The speed limit of 11 is set because there are only 12 initialized entries in this example acceleration table (indexed 0 to 11).

Step 2: Set the motion limits and power level

   BTM4320=4320-=1280=1280-=.
   BTL50=.
This example sets the limits to values appropriate for the nominal 270 by 80 degree motion range. If the mechanical stops are set for some other range, the initialization must account for these! Generally, idling the stepping motors at 50% power provides plenty of holding torque.

Step 3: Save state and restart

   BTB0=A15/
   BTB1=P15/
   BTB2=30]15/
   BTB3=45]15/
   BTB4=60]15/
   BTB5=75]15/
   BTB6=90]5/
   BT#
This saves all 95 variables to memory in 7 blocks. At this point the EEPROM will have correct checksums on these blocks, so there will be no checksum errors when the Trippy is restarted. The Trippy will not respond to a save or restore command until that command finishes. To avoid overrunning the input buffer, each line above should be entered into the Trippy only after the previous line has been acknowledged. The final command forces a restart.

When the Trippy restarts with a properly initialized acceleration table, it will automatically seek to home, using its internal position feedback sensors. After this seek operation, it will then seek whatever X and Y goal it finds in those variables.

Step 4: Set up zoom strings, motion bounds, etc

At this point, zoom strings, application specific motion bounds and an initial camera direction may all be set and then saved in EEPROM.

A C program is provided that will read diagnostic and initializaiton scripts, and check for the expected responses. This program greatly simplifies setup and diagnosis of Trippy pan-tilt-zoom platforms.


The bulk of the above text is from my files. The original was a plain text document (.txt format), so in tranferring it to the web, I converted to HTML and took the time to correct various errors and bring the documentation up to uniform standards.

Note that version 0.20 was the final firmware version, so the documentation here does not fully cover version used in the Trippy as it went to market.

I generally revised this protocol manual before revising the firmware, and always updated it before writing code to test any of the new features. When a product gets as complex as the Trippy, you need a manual even for what you designed. Of course, the manual was delivered to Basic Telepresence to help them develop the web-server code that actually ran the Trippy.