OPC Device Support

last Modified: by winkler
19.01.2012


Overview and Features
New in this version:
Directory structure
Install and Compile
iocShell Commands for OPC interface
opcIor: IO report
opcDbg: OPC browsing and debuging
asWriteLog: logging of channel access writes
Setup the OPC client
opcSetServer: Creates an OPC server instance
opcSetGroup: Creates a new OPC item group at current server
opcSetGroupRefresh: Forced refresh time for OPC groups
opcSetNames: Item name mapping
Set up a st.cmd for the ioc shell
Record related issues
Record scanning
Device types and data conversion
Timestamps
Known Problems
Application dies after some hours
Running many process variables in one iocShell
Out records: The value written by EPICS is ignored by the PLC

Author: Winkler, Kuner

Overview and Features

The OPC device driver provides direct access for EPICS records to items located on an OPC server. It has the following features:

• Data conversion for all integer and float data types.

Out-records become bidirectional In/Out-records. The EPICS Out-record will be updated if the OPC item is written by another device (e.g. PLC).

• Support for the following record types:

• The data conversion capabilities of the binary records (bi, bo, mbbi, mbbo, mbbiDirect, mbboDirect) are supported with two dtypes "opc" and "opcRaw" as described in the Record Reference Manual for the "Soft Channel" and "Raw Soft Channel" types.

• Timestamp is generated by OPC server or EPICS (source is determined by the record's TSE field).

• OPC quality is mapped to record's STAT/SEVR fields.

Setup the OPC client with special features:

• Available console commands for debugging purposes:

New in this version:


Read changeLog.txt for detailed information about this release.

Directory structure

The windows installable will install these files (full installation):

C:\Program Files\OpcIocShell\
   copyright_en.txt
   readme.html
   unins000.dat
   unins000.exe
   bin\
      asHost.dll
      asIoc.dll
      ca.dll
      ca_test.dll
      caget.exe
      cainfo.exe
      camonitor.exe
      caput.exe
      caRepeater.exe
      cas.dll
      Com.dll
      dbIoc.dll
      dbStaticHost.dll
      dbStaticIoc.dll
      dbtoolsIoc.dll
      gdd.dll
      iocLogServer.exe
      iocsh.dll
      miscIoc.dll
      opcIocShell.exe
      opcSupport.dll
      recIoc.dll
      registryIoc.dll
      rsrvIoc.dll
      SOCltad.DLL
      SOCmnad.DLL
      SODaCad.DLL
      softDevIoc.dll
      testDevIoc.dll
   dbd\
      opcIoc.dbd
   demo\
      DemoRecord1.db
      DemoRecord2.db
      st.cmd
      startDemo.bat
   src\
      res\
         icon3.ico
         OpcIocShell.ico
         uninstall.ico
      ait.h
      Checksum.cpp
      Checksum.h
      devOpc.c
      devOpc.h
      drvOpc.cpp
      drvOpc.h
      errDbg.c
      installationNotes.html
      iocShellMain.cpp
      logging.c
      Opc.cpp
      Opc.h
      opcApp.rc
      opcApp.sln
      opcApp.vcproj
      opcSupport.dbd
      opcSupport.sln
      opcSupport.vcproj
      opcToEpics.h
      recProp.h
      resource.h
      softing.h
   

Install and Compile

The opcIocShell_3_8_0_1.exe will install the compiled iocShell and its .dll's in a proper way.
The service opcEnum (needed for discovering of OPC servers) will be installed too.

For recompilation of the opcIocShell the OPC Toolkit from Softing is neccessary. We use OPC Toolkit version 3.01.

To run the demo example, OPC simulator should be installed. It's included in the setup.

iocShell Commands for OPC interface

opcIor: IO report

Create a report of all records that use OPC device support. Output format:

  epicsName, Record Type, Dtype, opcName, opcFullName

Syntax:

  opcIor

opcDbg: OPC browsing and debuging

Syntax:
opcDbg <n> [Filter]
  Argument n may be hexadecimal OR decimal value
        0x00000001      Show version of opc device driver
        0x00000002      Show read values
        0x00000004      Show write values
        0x00000008      Show bad values
        0x00000010      Show OPC init
        0x00000020      Show all OPC variables
        0x00000040      Show OPC-EPICS-MAPPING
        0x00000080      Show template processing
        0x00000100      Show OPC-group refreshing
        0x00000200      undefined
        0x00000400      undefined
        0x00000800      undefined
        0x00001000      undefined
        0x00002000      Show only ai(r) variables
        0x00004000      Show only aai variables
        0x00008000      Show only bi(r) variables
        0x00010000      Show only longin variables
        0x00020000      Show only mbbi(r) variables
        0x00040000      Show only mbbiDirect(r) variables
        0x00080000      Show only stringin variables
        0x00100000      Show only eventval variables
        0x00200000      Show only histogramval variables
        0x00300000      Show only ao(r) variables
        0x00800000      Show only aao variables
        0x01000000      Show only bo(r) variables
        0x02000000      Show only longout variables
        0x04000000      Show only mbbo(r) variables
        0x08000000      Show only mbboDirect(r) variables
        0x10000000      Show only stringout variables
        0x20000000      Show only waveformval variables
        0x40000000      Colored output
        0x80000000      undefined
        0xFFFFFFFF
           OR -1        Show available local OPC servers
                        and browse connected OPC servers for available OPC-items
       0xFFFFFFFE
           OR -2        Checks OPC variables whether being invalid
                        and offer to refresh variables or to restart OPC-server

   Optional parameter Filter is a substring to filter PV names

asWriteLog: logging of channel access writes

It starts logging of writing to epics variables via channel access.
Before you can do this you have to call "iocLogInit()" and "asSetFilename("./asFile.asf")".
In the file "asFile.asf;" are access security rules. To log any epics variable you have to set a rule as "RULE(0,WRITE,TRAPWRITE) {UAG(myGroup)}".
Syntax:
asWriteLog <n>
        * n=0 logging disabled
        * n=1 console output
        * n=2 iocLog output
        * n=3 console+iocLoc output
		

Setup the OPC client

There is a special way to add groups and items to an OPC server. The st.cmd file is more than the commands of the iocShell. It is also parsed by the opc interface routine! The idea is to have one file to setup the iocShell and also the opcClient. See the example:

Example : of an st.cmd that shows the OPC client setup:

iocShell_registerRecordDeviceDriver(pdbbase)
opcSetNames("../names.txt")
opcSetServer("localhost","MMIOPC.Simulator")
opcSetGroup("myGroup1","100")
dbLoadRecords("./DemoRecord1.db")
opcSetGroup("myGroup2","200")
dbLoadRecords("./DemoRecord2.db")
iocShell_registerRecordDeviceDriver(pdbbase)
iocInit()

opcSetServer: Creates an OPC server instance

Used only in st.cmd, not from the command line. It configures iocShell for connecting to OPC server.

It's possible to connect iocShell to miscellaneous OPC servers.

Syntax:

opcSetServer("hostName", "serverName")

Parameters:

opcSetGroup: Creates a new OPC item group at current server

Used only in st.cmd, not from the command line. It creates a new OPC item group at current OPC server. It's possible to create miscellaneous groups with several update rates at same server. According to the OPC "Data Access" specification it is mandatory to define at least one group.

Syntax:

opcSetGroup("groupName","n_scanRate")

Parameters:

opcSetGroupRefresh: Set refresh-cycle

Set refresh-cycle in ms for last defined Group. This forces a read from OPC server for all OPC items in appropriate group.

Syntax:

opcSetGroup("n_refreshRate")

Parameters:

opcSetNames: Item name mapping

Used only in st.cmd, not from the command line. It sets the file for name mapping.

The problem is that the record's INP or OUT fields have a limited length for the name of the OPC item. On the other hand, OPC servers can have huge name lengths for those items. So a map file may be defined to map the long OPC server names to short names suited for the record's link field.

The map file format is:

# allowed are comments and lines like this with leading spaces: epicsName = opcName
# don't forget a blank line at end of file

Syntax:

opcSetNames("fileName")

Parameters:

Set up a st.cmd for the ioc shell

This example shows how to set up an IOC

# debug mode to show OPC initialisation
# opcDbg("0x010")

# Make sure that the dbd contains the lines for "opc" and "opcRaw"
dbLoadDatabase("./iocShell.dbd",0,0)
iocShell_registerRecordDeviceDriver(pdbbase)

# following command initialise logger for channel access writes
# iocLogInit()

# following command sets file of access security rules (also for channel access writes)
# asSetFilename("./asFile.asf")

# Name mapping is not required here
# opcSetNames("../names.txt")
#
# This example uses an OPC server simulator at local host
opcSetServer("localhost","MMIOPC.Simulator")

# group1, scanning every 200 milliseconds
opcSetGroup("myGroup1","200")
dbLoadRecords("./DemoRecord1.db")
#
# group2, scanning every 100 milliseconds
opcSetGroup("myGroup2","100")
dbLoadRecords("./DemoRecord2.db")
#
iocInit()

# following command starts logger for channel access writes (console+iocLoc output)
# asWriteLog(3)

Record related issues

Record scanning

• In-records

The device support accepts all but "Passive". Due to the update facilities of the OPC group it is not reasonable to define a scan rate faster than the update rate of the group. To get the same scan rate for the record set SCAN="I/O Intr". To allow a slower than the update rate (for whatever reason) the fixed scan rates are supported: SCAN=".1 second" to SCAN="10 second".

• Out-records

As mentioned before out-records are now bidirectional in/out-records. They will be updated to the new value if it is changed on the OPC server by any other way (e.g. the PLC or another OPC client).

For out-records the SCAN field is ignored by the device support and should be set to "Passive". Nevertheless, if the OPC server gets a new value for the OPC item the record will be processed to update the value, send monitors, check for limits, set severities and process forward links.

Writing to the hardware from two sides (EPICS and the hardware covered by the OPC server) at the same time can cause problems.

For values that are frequently written by the PLC a write by the EPICS record will be overwritten in the opc-server by the PLC before it is sent to the PLC from the opc-server. In this case a caput will not be recognized by the PLC!

This is a behaviour due to the opc-server and PLC, no bug in the EPICS device support.

Also an EPICS write that follows immediately after a PLC write (very short time), may be discarded by the device support.

Device types and data conversion

There are two types available: DTYP="opc" for all records and the DTYP="opcRaw" for the binary records: bi, mbbo, mbbi, mbboDirect and mbbiDirect. The behaviour of the record is listed below and is according to the desccription of the raw data types in the Record Reference Manual.

For the analog records ai and ao the LINR field determines the data conversion.

Record DTYP Conversion
ai opc no conversion: LINR="NO CONVERSION" (record default)
ao opc no conversion: LINR="NO CONVERSION" (record default)
bi opc no conversion, VAL may be any value
bi opcRaw conversion: RVAL=0 -> VAL=0, RVAL>0 -> VAL=1
bo opc conversion: VAL=0 -> RVAL=0, VAL>0 -> RVAL=1 send RVAL to the hardware
mbbi opc for VAL=0..15 record is set to the according state. NOBT, SHFT ignored
mbbi opcRaw if RVAL=xxVL record is set to state xxST. NOBT, SHFT processed
mbbo opc ?
mbbo opcRaw ? further experimets will give new and exciting information,
mbbiDirect opc ? what this records does! See next version.
mbbiDirect opcRaw ? mbboDirect opc ?
longin opc no conversion
longout opc no conversion
stringin opc no conversion stringout opc no conversion
waveform opc no conversion

The multibit records (mbbo, mbbi, mbboDirect and mbbiDirect) have the fields NOBT and SHFT to select a special part of the 16 bit data input. This is also supported by the device support.

Timestamps

It is possible to choose the timestamp source. Default is the EPICS timestamp, but if the field TSE="-2" the timestamp of the OPC item will be used.

Known Problems

Application dies after some hours

If you run opcIocShell.exe at a hyperthreaded system, application dies after some hours with any system warning.
Solution: append /ONECPU in your boot.ini at [operating systems]

Running many process variables in one iocShell

If there are more than ca. 1800 PVs running on an iocShell following occures:

It seams to be a problem of the Windows task priorities.

Solution: Try more groups. - We reached best result with iocShell instances at several virtual machines.

Out records: The value written by EPICS is ignored by the PLC

see section "Record scanning" - Out Records