As far as a module is concerned, the MatPLC is a library. It provides various functions, of which only about five or seven are the most important. The others provide things like retrieving values from the config file - useful, but not vital.
This is the template for a classical-scan module:
#include <plc.h> int main(int argc,char *argv[]) { plc_init("modulename",argc,argv); /* initialization goes here */ while (1) { plc_scan_beg(); plc_update(); /* body of loop goes here */ plc_update(); plc_scan_end(); } }
One advantage is that the module doesn't need to keep track of which
points are read-only and which are read-write in the MatPLC; in the first
half, all points may be written, and in the second half all points may be
read. The plc_update()
discards values for which the module
lacks write permission.
This is the template for a data-interface module:
#include <plc.h> int main(int argc,char *argv[]) { plc_init("modulename",argc,argv); /* initialization goes here */ while (1) { plc_scan_beg(); /* process data going to MatPLC from the "other" */ plc_update(); /* process data coming from MatPLC to the "other" */ plc_scan_end(); } }
One of the main things you need to do here is to get handles to all the
points your program will access.
foo = plc_pt_by_name("foo");
bar = plc_pt_by_name("bar");
foo
and bar
should be declared as variables of
type plc_pt_t
. If you want to be safe, you should also check
that foo.valid
and bar.valid
are non-zero after
the above initialization.
Throughout the rest of the program, you will then use the variables
foo
and bar
to refer to those two points.
The two most important functions here:
plc_get(point)
plc_set(point,value)
These are used both for coils and for integer registers. When used for coils, 0 means OFF and 1 means ON.
When used for registers, value is treated as unsigned 32-bit integer
(MAT defines the type u32
for this purpose). Narrower points
can also be treated as unsigned integers - for instance, a plc_get() on an
8-bit point will return a number between 0 and 255.
As usual with PLC-style logic, points are read from outside the module
at the top of the loop and written to the outside at the bottom (that's
what the plc_update()
does). Last value written wins.
Remember that for plc_set()
, the module needs point
ownership in the matplc.conf
file. There is no warning if
you try to write to a point you don't own; the changes are simply discarded and the point value remains unchanged.
plc_get(pt_handle)
and
plc_set(pt_handle,new_value)
.
When processing data going from the MatPLC, you will only
use the first of these (plc_get()
); when processing data going
to the MatPLC, you will only use the second
(plc_set()
).
Other than this separation, the previous section applies.
The five most important functions are:
plc_init(module_name,argc,argv)
pt_handle = plc_pt_by_name(pt_name)
plc_get()
and
plc_set()
functions. The pt_name should be a string, while
pt_handle should be of type plc_pt_t
. The success or failure
of this function is indicated by pt_handle.valid
; non-zero
means OK. This function, like plc_init()
, should be called
before the time-critical part begins.
plc_update()
value = plc_get(pt_handle)
plc_update()
, or as changed by
this module), returning it as an unsigned 32-bit integer. A 32-bit float
version of this function is also available.
plc_set(pt_handle, new_value)
plc_update()
is called.
plc_pt_t
, which is used to declare the handles, and
u32
which is a simple 32-bit unsigned integer.
The two additional functions should be used if the module runs in a repeated scan, like a traditional PLC. They enable the MatPLC to enforce execution periods, sequencing of modules, RUN/STOP modes and the like. They take no arguments.
plc_scan_beg()
plc_update()
call, as shown in the templates.
plc_scan_end()
plc_update()
call, as shown in the templates.
These functions are explained in more detail in the general reference and GMM reference chapters.
conffile_
and are
described in detail in the conffile reference.
As noted, there are floating-point equivalents to plc_get() and plc_set(); they are called plc_get_f32() and plc_set_f32(), work with the type f32 instead of u32, but otherwise behave exactly like the integer versions.
plc_pt_by_name()
.
$Date: 2005/05/15 09:37:00 $