OCW Language and Interpreter v1.00 coming soon! |
Will Grover |
wgrover@users.sourceforge.net |
This page: http://ocw.sourceforge.net |
OCW project page: http://sourceforge.net/projects/ocw |
My home page: http://www.ocf.berkeley.edu/~wgrover/ |
Revised: June 17, 2004 |
Introduction to the OCW language and interpreter
The OCW language
is a script-based language for controlling and
coordinating complex operations in microfluidic
valves and pumps, although it could be used to control any automation
project that uses TTL level inputs. The OCW interpreter was
written in Perl and uses common, inexpensive parallel ports to provide
TTL control of the circuits that actuate microfluidic valves and pumps. Collectively, OCW was
designed with a few goals in mind:
OCW Installation and Usage
Currently Linux is known to be supported and
Windows/Cygwin support
is in the works. To install, simply grab
the source,
uncompress, and
run
to make everything, optionally become root and
run
to install the ocw program, then use your favorite
text editor to write your own OCW
program
(un where OCW language commands and syntax All OCW programs must have a few fundamental
components. This
includes a main function that starts with
make
make install
armed
for now; see below) and run
ocw myprogram.ocw
myprogram.ocw
is the name of your OCW program.
When
you are ready to run your program and actually control parallel ports,
add the armed
keyword to the preamble of your OCW
program,
become root
(see below for reasons), and run your OCW program as shown above.
main
and
ends with end
, and at least one parallel port
address assignment function a
appearing in the
preable (the region before the main
function).
You'll probably want at least a few o
,
c
, and w
commands if you want
the program to actually do anything!
OCW command:
Command definition:
Additional comments:
o
nOpen valve n
Available valve numbers are 0 through 8n-1 where n is the number of
parallel ports available on the system. Valves 0 through 7 are
assigned to the first port address set, valves 8 through 15 are
assigned to the second port address set, and so on (see the
a
command below). If the valve is already open,
it will remain open.
c
nClose valve n
Available valve numbers are the same as for the
o
command. If the valve is already closed, it
will remain closed.
w
tWait t milliseconds.
The overall accuracy and precision of the wait command is system
dependent. If a wait shorter than the minimum possible wait is
specified, the program will still wait for the minimum possible wait
without
any obvious errors.
/
commentComment line
If a
/
is placed at the beginning of a line, all remaining text on
that line is ignored. In addition, comments within functions (either
main
or a subfunction) are printed on the screen during
execution. Place a comment before a stop
command
to tell the operator exactly what to do during that stop
.
stop
Stop program execution until user presses ENTER.
Any comments preceeding the
stop
command will
be printed on the
screen while the system awaits user input. Note that using the
ENTER key to exit a stop
command is different from using ENTER
to escape a repeating function call
.
main
Begin main function
Every program must have a
main
function;
programs lacking a main
function won't do
anything. The main function cannot be repeated
arbitrarially like subfunctions can. If find that you need to repeat
the entire main
function, place the contents of the main
function
in a subfunction and call
that subfunction using repeats as
necessary (see call
below).
end
End main program or a subfunction
The main function and all subfunctions are each terminated by an 'end'
command. The code lying between
main
and the main
function's
end
is the main function; code between a subfunctions declaration (see
below) and that subfunction's end
is that
subfunction's code.
sub
Begin the definition of the subfunction named sub.
Any line containing a single word that isn't another OCW function is
assumed to be the declaration of a subfunction. The name of the
subfunction marks the beginning of the subfunction's code, and the
end
command marks the end of the code.
call
sub
nCall subfunction sub n times, once if n is omitted.
When a subfunction is called, its code is executed as if the
subfunction's code
was actually inserted in the program at the
call
command. Adding an integer number n after the function name in
the
call
command will repeat that subfunction's code
n times; if the number is omitted the code is executed once. It
is possible to call (or actually recall) the main function
as a subfunction (call main
), or to call a
subfunction from
within that subfunction, or to have loops of subroutines that call
each other if necessary; programs using these constructs will run
forever and must be aborted using CTRL + C. Finally,
by specifying a large repeat number and pressing ENTER at
runtime to exit the loop, elements of OCW programs can be
controlled at runtime by the operator. See the "OCW interpreter
commands" below for more information.
a
nPreamble command to set parallel port address to n
The
a
command is called as many times as there
are parallel ports for use on your computer. The order in which the
ports are called is used to determine which set of 8 valves are
assigned to which parallel port. For example, the first parallel port
address set using a
will control valves 0 through
7, the second port address set with a
will control
valves 8 through 15, and so on for as many ports as you have.
Currently, the port address must be set using a decimal number,
even though we usually refer to these addresses using hexidecimal
numbers. I'll fix this eventually, but for now some common
parallel port hex addresses and their decimal equivalents are shown in
the "Addional application notes" section below.
armed
Preamble command to activate parallel ports
OCW code without an
armed
command somewhere in
the preamble will run without actually doing anything with the
parallel ports. This corresponds to a "safety" or "debug" mode in
which the program can be run without root priveleges and without
worrying about writing to incorrect memory addresses. Using this
feature, OCW programs can be written and debugged on one PC
before transferring the program to the actual valve control PC. When
ready to actually run the program, include the
armed
command in the preamble and become root,
then run the program.
negate
Preamble command to negate parallel port logic
In ordinary operation, the OCW program assumes that opening a
valve corresponds to energizing a solenoid valve (sending out a "high"
or "1" TTL voltage) and closing a valve corresponds to de-energizing a
solenoid valve (sending out a "low" or "0" TTL voltage. Depending on
the type of solenoid valve used and the construction of the system,
this assumption may need to be reversed. When the
negate
command is called once in the preamble of
an OCW program, an open valve corresponds to the de-energized state of
the solenoid valve and a closed valve corresponds to the energized state.
OCW interpreter commands:
A few commands may be issued while the OCW interpreter is running. These commands mostly affect the execution and flow of the OCW program being run.OCW command: | Command definition: | Additional comments: |
ENTER | Continue execution (after a stop command has halted program execution) |
Pressing ENTER during a repeating subfunction call serves a very different purpose; see below. |
ENTER | Escape the current repeating subfunction | This feature can be used to create "repeat until interrupted"
functions in an OCW program. To use, include a call
function with a huge repeat number like 1000000. When the code is run,
the called subfunction will be repeated until the user presses
ENTER (or a million repeats, whichever comes first). This turns
out to be very useful in situations in which the exact number of actions
required isn't known but will be determined by the operator at
runtime. |
CTRL + C | Quit current running program | Just the old classic way to quit a program. Of course, if the interpreter reaches the end of the OCW code being run, then the program will quit by itself. |
Sample OCW programs:
The inevitable and obligatory "hello world" program:
main /hello world end |
A slightly more complex program that simultaneously opens four
even-numbered valves
and closes four odd-numbered valves. The parallel port used by the program has hex address
0x378 (decimal equivalent 888). The command a888
sets the address of the port to use for controlling the three valves,
and the armed
command makes the program actually
control the port:
a888 armed main /open the even-numbered valves: o0 o2 o4 o6 /close the odd-numbered valves: c1 c3 c5 c7 end |
A full program for controlling microfluidic diaphragm pumps as described in Grover et al., Sensors and Actuators B 89, 3, 2003. The program uses one parallel port to control three logical lines which in turn are used to switch three solenoid valves. These valves control the flow of pressure or vacuum to the three monolithic membrane valves that form the diaphragm pump. The pump is actuated 100 times (perhaps pumping about 1 microliter in the process) before a graceful shutdown of the device.
The main
function has four steps.
First, a subfunction named close_all_valves
is
call
ed
once. A helpful note for the operator is printed on the screen—"Add
buffer to the reservoir"—and program execution stop
s until the user presses ENTER. Next a subfunction named
pump_forward
is call
ed 100 times.
Finally the close_all_valves
subfunction is called again,
then the program ends.
The remainder of the code consists of definitions of
the
subfunctions used in the main
function. The
close_all_valves
subfunction contains three
c
commands to close all three valves. The
pump_forward
subfunction contains the six
o
and c
steps necessary for
driving the diaphragm pump through a single cycle, interspersed with
calls to an additional subfunction, pump_wait
, that
provides a constant 100 millisecond w
ait time for
each of the six steps:
/Sample OCW program by Will Grover a888 armed main call close_all_valves /Add buffer to the reservoir stop call pump_forward 100 call close_all_valves end close_all_valves c0 c1 c2 end pump_forward o0 call pump_wait c2 call pump_wait o1 call pump_wait c0 call pump_wait o2 call pump_wait c1 call pump_wait end pump_wait w100 end |
Notice that the entire device operation is described in the five
lines of the main
function. Once a few useful
subfunctions have been designed, the main
part of
the program can become quite readable and easy to edit. Simple
subfunctions can also be treated like variables that are referred to
elsewhere in the program. Editing the single w
function in pump_wait
is much quicker than
changing six individual w
commands in the
pump_forward
subfunction.
OS-specific notes
Information about porting OCW to different operating systems:
Operating System: | Supported? | Make command: | Notes: |
Linux | Yes | make linux
| Uses the linux.c helper program, which in turn uses the Linux-specific commands ioperm() and outb() . These commands require root permissions to run without causing a segmentation fault, so you need to be root before you can run an armed OCW program on a Linux system. I hope to change this in a future version... |
Windows (Cygwin) | Under development | Under development | Under development |
Additional application notes:
Guide for wiring digital lines to the Centronics male end of a standard IEEE-1284 printer cable:0 1 2 3 4 5 6 7 G G | | | | | | | | | | v v v v v v v v v v ___________________________________________ \ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ / \ / \ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ / \_____________________________________/ ^ ^ ^ ^ ^ ^ ^ ^ | | | | | | | | G G G G G G G GThis is the end of the cable that usually connects to a printer; the other end is also male but has pins and connects to the parallel port on a PC. If this cable is attached to the first port address set in an OCW program (see the
a
command above), valves 0
through 7 will be controlled by this cable. The second and subsequent
port addresses declared will control valves 8 through 15, 16 through
23, and so on. Conductors marked "G" are grounded and should all be
connected with the signal ground on the circuit being controlled by
the TTL lines.
Common parallel port hex addresses and their decimal equivalents
for use in a
commands:
Hex address: | Decimal address: |
0x3BC | 956 |
0x378 | 888 |
0x278 | 632 |
0x368 | 872 |
0x268 | 616 |
0x358 | 856 |
0x258 | 600 |
The OCW language and interpreter are (c) 2003 by Will Grover (wgrover@users.sourceforge.net). Both are released under the GNU General Public License.