solenoid A 22 23 14 solenoid B 24 25 15The first line defines A to be a solenoid and specifies that command 22 will open A, 23 will close it, and status bit 14 will report its state. Similarly, the second line associates B with commands 24 and 25 and status bit 15.
Next, we specify the time resolution we want:
resolution = 1/4Now we are ready to specify the solenoid cycles:
mode 0 { A: OOOO:OO__:____:__OO B: ____:_OOO:____:____ }This command defines the actual solenoid positions for mode 0. The character `O' represents an open solenoid valve and the character `_' represents a closed valve. Solenoid A starts out open and remains open for one and a half seconds, then stays closed for two seconds, when it reopens. B starts closed and opens 1/4 of a second before A closes, and then stays open for only 3/4 of a second. The length of the cycle is implicit in this definition. The format of the mode command is fairly flexible. If all the information doesn't fit on one line, it may be continued on another line simply by beginning the new line with the solenoid name and a colon. This continuation does not have to appear immediately after its predecessor, since the name makes it clear to which sequence the data belongs. Hence, we could add another four seconds to this mode with the command:
mode 0 { A: OOOO:OO__:____:__OO B: ____:_OOO:____:____ A: OOOO:OO__:___O:_O_O B: ____:_OOO:OOO_:O_O_ }It is also possible to change the characters which designate open and closed valves by using the commands:
open = '<open character>' close = '<close character>'The solenoids we have used so far are commanded by two strobed commands. In practice, these don't have to be solenoids at all, but any device which is commanded with two strobed commands. Although solenoids are a very common application, soldrv has been used to command heaters and other devices as well. Sometimes, however, cycling of devices which aren't controlled by strobed commands is desired. Soldrv has two additional features to support more complicated devices: set points and proxies. Analog set points are defined using the DtoA command. For example:
DtoA C 0E10 { L:50 M:1000 H:4000 }defines an analog control named `C' using the D/A channel at address 0E10 which has three values designated `L', `M' and `H'. When a particular set point is specified, the corresponding value is written out to the channel's address. These set points can be used in a mode just like `O' and `_' for solenoids:
mode 1 { C: LLLL:LLMM:MHHM:MMLL C: LLLL:LLMM:HMML:MLML }Proxies provide the most general control capability by allowing soldrv to communicate with other control programs. The syntax for proxy definitions is similar to that for DtoA definitions:
Proxy D { L:3 M:4 H:7 }The numbers associated with each state are proxy ID numbers. These must be unique for all proxy states in the file and must match the proxy IDs used by the associated control programs. At runtime, the associated control program contacts soldrv to register a proxy using the ID number (e.g. "Here's a proxy for ID 3"). Until the proxy is registered, cycling a proxy element will do nothing. Once the proxy is registered, a change in state specified in the mode definition (Changing from say `L' to `M') will cause soldrv to trigger the proxy associated with the new state.
Proxies are used on the ER-2 OH experiment to drive the laser on and off line. The laser is actually controlled by the indexer control program. That program must register the appropriate proxies with soldrv before the laser can be cycled.
There is one other significant character on a cycle definition line. This is the "switch character" which is permanently defined as the caret (^). The switch character is used to identify good points for mode changes. By carefully placing switch characters within your solenoid cycles, you can guarantee that each cycle will run to completion before an alternate mode is selected.
You may add any other characters as desired to make the text more readable. In the above examples, I used colons to designate whole seconds. The main limitation on the mode specification is that the cycles specified for each of the solenoids must be of the same length.
Solenoids which are not being cycled may be set to defined positions by use of the initialize command. If at the beginning of Mode 0 above we typed:
initialize A:Osolenoid A would be initialized to an open position whenever Mode 0 was selected.
There are an arbitrary number of possible modes. Each mode consists of initializations and/or cycle definitions. An undefined mode performs neither initializations nor cycles. Conversely, a mode that does neither is considered undefined. A mode with no cycle defined performs any specified initializations and then waits for another mode to be selected. Hence, initializations may be considered the "d.c. component" of a mode definition.
In addition to initializations and cycle definition lines, a mode may contain the command:
select <MODE-NUMBER>where <MODE-NUMBER> is the number of the desired mode. When the cycling program reaches this command, it will select the new mode as if that mode had been selected from the command line or a flight algorithm. The select command must be the last command in a mode. A mode that ends with this command does not actually cycle, but rather executes its instructions once and then selects the new mode.
solenoid <solenoid name> <open> <close>
<status>
DtoA <DtoA name> <address> { <Set
Points> }
Proxy <Proxy name> { <Set Points> }
open = '<open character>'
close = '<close character>'
status_bytes { <addresses> }
resolution = <number>/<number>
mode <number> { <mode defs> }
routine <routine name> { <valving defs> }
select <mode number>
The solenoid file consists of any number of commands:
commands : [ command ... ] command : solenoid <SOL-NAME> <NUMBER> <NUMBER> <NUMBER> : DtoA <SET-NAME> <ADDRESS> { Set-Point [ Set-Point ... ] } : Proxy <SET-NAME> { Set-Point [ Set-Point ... ] } : open = '<open-character>' : close = '<close-character>' : status_bytes { [ <ADDRESS> ... ] } : resolution = <NUMBER>/<NUMBER> : mode <MODE-NUMBER> { mode-defs } : routine <routine-name> { routine-defs } mode-defs : null : <routine-name> mode-defs : valving-def mode-defs : select <MODE-NUMBER> routine-defs : null : valving-def routine-defs : select <MODE-NUMBER> valving-def : initialize <SOL-NAME> : solenoid-character : initialize <SET-NAME> : set-character : <SOL-NAME> : [ solenoid-character ... ] : <SET-NAME> : [ set-character ... ] solenoid-character : <open-character> : <close-character> : <switch-character> : <fill-character> set-character : <set-point-character> : <switch-character> : <fill-character> Set-Point : <set-point-character> : <NUMBER>
int version; char command_set; int n_solenoids; struct { int open_cmd; int close_cmd; int status_addr; int status_mask; } solenoids[n_solenoids]; int n_set_points; struct { int address; int value; } set_points[n_set_points]; int n_proxies; unsigned char proxy_ids[n_proxies]; int n_modes; int mode_indices[n_modes]; int n_bytes; char mode_codes[n_bytes];
version
specifies the version of both the solfmt
program and the solenoid driver program in BCD. Version 2.0 is
designated by the hex value 0200. If the solenoid driver program
reads in a .sft file and finds that the version number is
different, an error should be reported. An exception might be
that between version 2.0 and 3.0 the n_proxies
was
added. Soldrv V3.0 should probably recognize V2.0 programs,
simply setting n_proxies
to 0.
n_solenoids
is the total number of solenoids that
have been defined.
For each defined solenoid, the open_cmd
,
close_cmd
, status_addr
, and
status_mask
are recorded. The open_cmd
and close_cmd
are the numbers for the discrete
commands that open and close the solenoid. The associated status
bit may be found by anding the status_mask
with the
contents of subbus address status_addr
.
n_set_points
is the total number of set points which
have been defined. Each set point is defined by a subbus address
and the value that should be written out to that address.
n_proxies
is the total number of proxies defined.
proxy_ids
contain the IDs for the proxies.
n_modes
is the maximum mode number defined plus one.
mode_indices
is an array of pointers into the
mode_codes array indicating where the program for that mode
begins.
n_bytes
determines the length of the
mode_codes
array. The mode_codes
array
itself is a simple compiled code for operating the solenoid
cycles. There are five command codes defined as follows:
SOL_STROBES
0: The following byte is the number of a
discrete command to be executed.
SOL_WAIT
1: Wait for a significant event triggered by the timer
(which has already been programmed.)
SOL_SET_TIME
2: The next two bytes are a count to be
written to the timer. The timer should be programmed using mode
three (square wave.)
SOL_GOTO
3: The next two bytes are the index of the
next instruction.
SOL_END_MODE
4: No action should be taken until a
new mode is selected. Equivalent to a Halt instruction.
SOL_WAITS
5: Wait for n significant events,
where n is the value of the next byte.
SOL_SELECT
6: Select mode number n, where
n is the value of the next byte.
SOL_MSWOK
7: Indicates that a mode switch is
allowable. If a mode switch is pending, it will occur at this
point.
SOL_DTOA
8: The following byte is a set point
index. The corresponding value should be written out to the
corresponding address.
SOL_PROXY
9: The following byte is a proxy index.
The index is not the proxy ID, but rather the
index into the array defined in the .SFT file. If the appropriate
proxy has been registered, it should be triggered.
SOL_MULT_STROBES
10: The remainder of this record
matches the format for the SCDC multi-strobe command, allowing
simultaneous switching of solenoids.
Throughout the .sft file, all integers are stored as two bytes with the least significant byte stored first.
last updated: Fri May 7 15:14:06 2004 | webmaster@huarp.harvard.edu |
Copyright 2004 by the President and Fellows of Harvard College |