com.softplc
Class DataTable

java.lang.Object
  |
  +--com.softplc.DataTable
All Implemented Interfaces:
java.io.Serializable
Direct Known Subclasses:
RemoteDataTable

public class DataTable
extends java.lang.Object
implements java.io.Serializable

Class DataTable provides simple services for reading and writing words, and writing bits to the SoftPLC datatable.

A DataTable object represents a SoftPLC datatable. A DataTable is used to read or write to datatable words. The methods for datatable access reside in class DataTable rather than in class SPLC so that remote datatable access can be supported with little change to dependent code. For remote datatable access, see class RemoteDataTable, which you must create by invoking its constructor. For the local datatable, no constructor is needed since the Dealer runtime environment constructs the SPLC.dt member, which is the local DataTable.

The term datatable "file" shall be taken to mean datatable "section".

Most of the DataTable methods take a special argument called a "handle". A handle must be constructed by the DataTable itself from a file (section) number, element number, and optional word number. A handle is simply a Java long that is used for fast access to a datatable value. A handle is not a machine pointer, but is like a pointer. It always points to the same logical datatable location. The actual values of two different handles pointing to adjacent datatable values will differ by a fixed offset. That offset is subject to change from one release to another. Your code should not hard code dependencies on this offset. You may however, use the DataTable constants ELEM_UNIT, and WORD_UNIT in your calculations. You could use these values to scoot through a datatable file with an ascending handle value.

A good place to make handles is in the Modlet.init() method. The actual file, and elements to be used may even come from the configuration file. Once handles are made, they don't ever need to be remade again.

Although a handle can be created for any legal datatable address, the process of creating the handle makes no guarantee that the corresponding datatable address actually exists in the datatable. SoftPLC datatable may be expanded or contracted in PROGRAM mode, so the validity of a handle can change even during the lifetime of the Modlet. The method Modlet.setMode(int) can look for transitions to OPM_RUN mode and at that time re-verify all handles with isValid(). At this time you may even decide to deny the transition to RUN mode by throwing a ModletException.

Since memory allocation is expensive (somewhat slow) in Java, it is helpful for improved runtime performance if you can avoid creating new Java objects while in run mode. The DataTable class was designed consistent with this philosophy. Rather than returning new Java Objects, the DataTable methods either return a Java primitive, or will fill in or use an existing array Object. Array Objects should be re-used over and over again, rather than creating a new instance for each Datatable method invocation. Array Objects are always used in conjunction with a separate "count" argument, so that array Objects can be created on a worst case size basis, and then only a part of this array need be used as given by "count".

Since:
August 1996
See Also:
SPLC, Modlet#init(), Modlet.setMode(int), ModletException, RemoteDataTable, Serialized Form

Field Summary
static long ELEM_UNIT
          A value you can use to perform arithmetic on a handle to access the next or previous "element".
static int MAXELEM
          The maximum SoftPLC element number within a file.
static int MAXFILE
          The maximum datatable file number within the DataTable
static int MAXWORD
          The maximum word number within an element.
static long WORD_UNIT
          A value you can use to perform arithmetic on a handle to access the next or previous "word" of a TIMER, COUNTER, CONTROL, or any other multi-word element.
 
Constructor Summary
protected DataTable()
          Only the C++ MACHJ.TLM can make one of these.
 
Method Summary
 int getFileSize(long handle)
          Get the number of elements in the datatable section referenced by the given handle.
 int getFileType(long handle)
          Get the type of datatable section the given handle is referencing
 float getFloat(long handle)
          Fetch the current float value of a datatable word.
 int getInt(long handle)
          Fetch the current value of a datatable word.
 long handle(int file, int element)
          Make a handle for accessing the datatable word or element given by file:element.
 long handle(int file, int element, int word)
          Make a handle for accessing the datatable word or element given by file:element:word.
 long handle(java.lang.String address)
          Make a handle for accessing the datatable word or element given by a datatable address string such as I:000, N7:0, or T4:22.ACC.
 boolean isFloat(long handle)
          Determine if the datatable word referred to by a handle is a float.
 boolean isValid(long handle)
          Determine if the datatable memory referred to by a handle exists.
 void putBits(long handle, int andMask, int orMask)
          Do a read/modify/write operation on the given word.
 void putFloat(long handle, float value)
          Write a new value into the datatable word at handle.
 void putInt(long handle, int value)
          Write a new value into the datatable word at handle.
 void read(long handleOfFirst, int count, float[] block)
          Read a block of floats from a contiguous datatable block into the float array block.
 void read(long handleOfFirst, int count, int[] block)
          Read a block of ints from a contiguous datatable block into the int array block.
 void write(long handleOfFirst, int count, float[] block)
          Write a block of float words from array "block" into a given contiguous datatable region.
 void write(long handleOfFirst, int count, int[] block)
          Write a block of int words from array "block" into a given contiguous datatable region.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

MAXELEM

public static final int MAXELEM
The maximum SoftPLC element number within a file.

MAXFILE

public static final int MAXFILE
The maximum datatable file number within the DataTable

MAXWORD

public static final int MAXWORD
The maximum word number within an element. This limit pertains is dictated by the PID section.

ELEM_UNIT

public static final long ELEM_UNIT
A value you can use to perform arithmetic on a handle to access the next or previous "element".

WORD_UNIT

public static final long WORD_UNIT
A value you can use to perform arithmetic on a handle to access the next or previous "word" of a TIMER, COUNTER, CONTROL, or any other multi-word element. For timers, counters and controls, the word numbers are:
  • T*:*.CTL is word = 0
  • T*:*.PRE is word = 1
  • T*:*.ACC is word = 2
  • C*:*.CTL is word = 0
  • C*:*.PRE is word = 1
  • C*:*.ACC is word = 2
  • R*:*.CTL is word = 0
  • R*:*.LEN is word = 1
  • R*:*.POS is word = 2
For example

long hdlACC = handle( 4, 0, 2); // is the handle for T4:0.ACC long hdlPRE = hdlACC - DataTable.WORD_UNIT; // is the handle for T4:0.PRE

For PID elements, the word offsets are:

  • controlWord = 0
  • statusWord = 1
  • setpoint = 2
  • kp = 4
  • ki = 6
  • kd = 8
  • bias = 10
  • maxScale = 12
  • minScale = 14
  • deadBand = 16
  • setOutput = 18
  • maxOutput = 20
  • minOutput = 22
  • deltaT = 24
  • pv = 26
  • pvHiAlarm = 28
  • pvLoAlarm = 30
  • ErrPosAlarm = 32
  • ErrNegAlarm = 34
  • pvDBAlarm = 36
  • maxInput = 38
  • minInput = 40
  • tieback = 42
For example

long hBasePID = handle( 13, 0, 0 ); // PD13:0.0 (controlWord) long hPV = hBasePID + 26 * DataTable.WORD_UNIT; // PD13:0.PV (proc var)

WORD_UNIT arithmetic can NOT be used to compute a new handle for a word outside the current element. Use ELEM_UNIT for that.

Constructor Detail

DataTable

protected DataTable()
Only the C++ MACHJ.TLM can make one of these. This can't be done in Java.
Method Detail

handle

public long handle(int file,
                   int element)
            throws java.lang.ArrayIndexOutOfBoundsException
Make a handle for accessing the datatable word or element given by file:element. The resultant handle is good either for accessing the whole element or for accessing word 0 of the given element.
Parameters:
int - the datatable file number.
int - the datatable element number.
Returns:
long - the handle

handle

public long handle(int file,
                   int element,
                   int word)
            throws java.lang.ArrayIndexOutOfBoundsException
Make a handle for accessing the datatable word or element given by file:element:word. The resultant handle is good for accessing the given word within an element.
Parameters:
int - the datatable file number.
int - the datatable element number.
int - the datatable word number within a multi-word element.
Returns:
long - the handle

handle

public long handle(java.lang.String address)
            throws java.lang.ArrayIndexOutOfBoundsException,
                   java.text.ParseException
Make a handle for accessing the datatable word or element given by a datatable address string such as I:000, N7:0, or T4:22.ACC. The resultant handle is good for accessing the given word.
Parameters:
String - the memory address string of a PLC word.
Throws:
java.lang.ArrayIndexOutOfBoundsException - if the address does not exist.
java.text.ParseException - if the address String is improperly formated.

getFileType

public int getFileType(long handle)
                throws java.lang.ArrayIndexOutOfBoundsException
Get the type of datatable section the given handle is referencing
Parameters:
long - handle of any word in the datatable file.
Returns:
an element from interface DT
Throws:
java.lang.ArrayIndexOutOfBoundsException - if the referenced file does not exist.
See Also:
DT

getFileSize

public int getFileSize(long handle)
Get the number of elements in the datatable section referenced by the given handle. The returned size is in elements, not words.
Parameters:
long - handle of any word in the datatable file.
Returns:
int the number of elements in the entire file or zero if the file does not exist.

isValid

public boolean isValid(long handle)
Determine if the datatable memory referred to by a handle exists.
Parameters:
long - a handle.
Returns:
boolean - true if the associated memory exists, else false.

isFloat

public boolean isFloat(long handle)
Determine if the datatable word referred to by a handle is a float.
Parameters:
long - a handle.
Returns:
boolean - true if the associated memory is float, else false it is int.

getInt

public int getInt(long handle)
           throws java.lang.ArrayIndexOutOfBoundsException
Fetch the current value of a datatable word. A 16 bit SoftPLC integer value is sign extended to 32 bits. If the handle points to a float datatable word, then the float is converted to a 32 bit int as if it were cast to a Java int in Java.
Parameters:
long - a handle.
Returns:
int - the value of the datatable word.
Throws:
java.lang.ArrayIndexOutOfBoundsException - if the handle is not currently valid.
See Also:
getFloat(long), read(long, int, int[])

getFloat

public float getFloat(long handle)
               throws java.lang.ArrayIndexOutOfBoundsException
Fetch the current float value of a datatable word. If the hanlde points to short word, then it is sign extended to a 32 bit int and then converted to a Java float. So a value of -23 becomes -23.0. If instead the handle points to a float datatable word, then the float value is returned unchanged.
Parameters:
long - a handle.
Returns:
float - the value of the datatable word.
Throws:
java.lang.ArrayIndexOutOfBoundsException - if the handle is not currently valid.
See Also:
getInt(long), read(long, int, float[])

read

public void read(long handleOfFirst,
                 int count,
                 float[] block)
          throws java.lang.ArrayIndexOutOfBoundsException,
                 java.lang.NegativeArraySizeException
Read a block of floats from a contiguous datatable block into the float array block. The size of array block must be greater than or equal to count. If the count and/or the handleOfFirst cause a read to extend beyond the end of the actual datatable file, then throw an ArrayIndexOutOfBounds exception and read no words.

This method may be used to read from float datatable words or from int words. If the handle refers to an int file, then a conversion takes place as if each value were cast to float in Java, and this will be slightly slower as a result.

Parameters:
long - handle of first word to read. Contiguous words thereafter are read.
int - the number of words to read.
float[] - where to put the float words read.
Throws:
java.lang.ArrayIndexOutOfBoundsException - if the handle refers to datatable that does not have at least count words to the end of the file, or if the block array is not at least count elements in size.
java.lang.NegativeArraySizeException - if count < 0.
NullPointerException - if block is null.
See Also:
getFloat(long)

read

public void read(long handleOfFirst,
                 int count,
                 int[] block)
          throws java.lang.ArrayIndexOutOfBoundsException,
                 java.lang.NegativeArraySizeException
Read a block of ints from a contiguous datatable block into the int array block. The size of array block must be greater than or equal to count. If the count and/or the handleOfFirst cause a read to extend beyond the end of the actual datatable file, then an ArrayIndexOutOfBounds exception is thrown and no words are read. This method may be used to read from float datatable words or from int words. If the handle refers to an float file, then a conversion takes place as if the value were cast to int in Java, and this will be slightly slower as a result.
Parameters:
long - handle of first word to read. Contiguous words thereafter are read.
int - the number of words to read.
int[] - where to put the int words read.
Throws:
java.lang.ArrayIndexOutOfBoundsException - if the handle refers to datatable that does not have at least count words to the end of the file, or if the block array is not at least count elements in size.
java.lang.NegativeArraySizeException - if count < 0.
NullPointerException - if block is null.
See Also:
getInt(long)

putInt

public void putInt(long handle,
                   int value)
            throws java.lang.ArrayIndexOutOfBoundsException
Write a new value into the datatable word at handle. If the handle points to short word, then truncate the upper 16 bits of value. If the handle points to a float word, then first convert all 32 bits of value into a float. If the memory corresponding to handle does not exist, then throw an ArrayIndexOutOfBoundsException.
Parameters:
long - the handle of the datatable word to write to.
int - the value to write to the datatable word at handle.
Throws:
java.lang.ArrayIndexOutOfBoundsException - if the handle refers to datatable that does not exist.
See Also:
putFloat(long, float), write(long, int, int[])

putFloat

public void putFloat(long handle,
                     float value)
              throws java.lang.ArrayIndexOutOfBoundsException
Write a new value into the datatable word at handle. If the handle points to a short word, then first convert the float value to a Java int, and then the upper 16 bits of the value are truncated. Note that this conversion only works properly if
32767.0 >= value >= -32768.0. 
If the handle points to a float word, then simply copy the value unchanged. If the datatable memory corresponding to handle does not exist, then throw an ArrayIndexOutOfBoundsException.
Parameters:
long - the handle of the datatable word to write to.
int - the value to write to the datatable word at handle.
Throws:
java.lang.ArrayIndexOutOfBoundsException - if the handle refers to datatable that does not exist.

write

public void write(long handleOfFirst,
                  int count,
                  int[] block)
           throws java.lang.ArrayIndexOutOfBoundsException
Write a block of int words from array "block" into a given contiguous datatable region. The size of array block must be greater than or equal to "count". If the count and/or the handleOfFirst cause a write to extend beyond the end of the actual datatable section, then throw an ArrayIndexOutOfBounds exception and do not write any values.
Parameters:
long - the handle of the first word to copy.
int - how many words to copy
int[] - source of the word values. Values will be truncated to 16 bits as needed.
Throws:
java.lang.ArrayIndexOutOfBoundsException - if any part of the destination datatable does not exist or count is greater than the block array.
java.lang.NegativeArraySizeException - if count < 0.
See Also:
DataTable#putInt()

write

public void write(long handleOfFirst,
                  int count,
                  float[] block)
           throws java.lang.ArrayIndexOutOfBoundsException
Write a block of float words from array "block" into a given contiguous datatable region. The size of array block must be greater than or equal to "count". If the count and/or the handleOfFirst cause a write to extend beyond the end of the actual datatable section, then throw an ArrayIndexOutOfBounds exception and do not write any values.
Parameters:
long - the handle of the first word to copy.
int - how many words to copy
float[] - source of the word values. Values will be truncated to 16 bits as needed.
Throws:
java.lang.ArrayIndexOutOfBoundsException - if any part of the destination datatable does not exist or count is greater than the block array.
java.lang.NegativeArraySizeException - if count < 0.
See Also:
putFloat(long, float)

putBits

public void putBits(long handle,
                    int andMask,
                    int orMask)
             throws java.lang.ArrayIndexOutOfBoundsException
Do a read/modify/write operation on the given word. The datatable word is set to the following expression:
word = (word & andMask) | orMask;
Only the lower 16 bits are used. If the handle points to a non-existent datatable value or to a value of type float, then an ArrayIndexOutOfBoundsException is thrown.

Example. Assume you want to turn off bit 0 and at the same time set bit 1 of a SoftPLC short word.

try {
SPLC.dt.putBits( handle, 0xFFFE, 2 );
} catch ( Exception e ) {}
Parameters:
long - which word to fiddle on
int - an andMask of bits that are ANDed with the current value.
int - an orMask of bits that are ORed with the current value.
Throws:
java.lang.ArrayIndexOutOfBoundsException - if the handle refers to datatable that does not exist.