RediGate POD Programming Manual
Table of Contents
- 1 Introduction
- 2 POD Programming
- 2.1 POD Configuration Structure
- 2.2 POD Object
- 2.2.1 Rules for Using the Result Addr
- 2.2.2 POD Editing Tips
- 2.2.3 POD Programming Tips
- 3 POD Programming Examples
- 4 POD Function List
- 4.1 Function Reference Chart
- 4.1.1 Mathematical Functions
- 4.1.2 Comparison functions
- 4.1.3 Logical/Boolean functions
- 4.1.4 String processing functions
- 4.1.5 Program control
- 4.1.6 Set or get registers, data conversion
- 4.1.7 RediGate system access
- 4.1.8 I/O board functions
- 4.1.9 File access functions
- 4.1.10 Communication functions
- 4.1.11 Specialty functions
- 4.2 Commonly Used Functions
- 4.2.1 + ADD Operand (Append Strings)
- 4.2.2 - SUBTRACT Operand (Remove Operand String occurrences from Source String)
- 4.2.3 * MULTIPLY Operand (Find Right Half of Operand String, Replace with Left Half)
- 4.2.4 / DIVIDE BY Operand (Return 1st N (Operand-Value) of Source String)
- 4.2.5 MODULO DIVIDE by Operand (Return Last N (Operand-Value) of Source String)
- 4.2.6 > GREATER THAN Operand? (Including String Compare)
- 4.2.7 < LESS THAN Operand? (Including String Compare)
- 4.2.8 == EQUAL TO Operand? (Including String Compare)
- 4.2.9 != NOT EQUAL TO Operand? (Including String Compare)
- 4.2.10 ASSIGN Operand to Result (Ignore Source Addr)
- 4.2.11 GOTO LABEL - Jump if Source value is TRUE/Non-Zero, Operand=”Matching Label”
- 4.2.12 NOT GOTO LABEL - Jump only if Source value is FALSE/Zero, Operand="Matching Label"
- 4.2.13 LABEL ONLY in Operand as a STRING (Src and Result ignored)
- 4.2.14 FOR_LOOP Src=Enbl Oprnd=5CfgRgs 0=Index, 1=Init&LoopVal, 2=Limit, 3=Stop@(0 '=', 1 '>', -1 '<'), 4=IncrmentVal (Label @ ENDLOOP[0-9])
- 4.2.15 REPEAT UNTIL Src=Enbl Oprnd=5CfgRgs 0=Index, 1=Init&LoopVal, 2=Limit, 3=Stop@(0 '=', 1 '>', -1 '<'), 4=IncrmentVal (Label @ ENDLOOP[0-9])
- 4.2.16 JUMP RELATIVE if Src is TRUE by Operand Rows (+/-)
- 4.2.17 GO_SUB_POD Subroutine If Src=Enable Operand=POD_Index to drop into POD Subroutine
- 4.2.18 EXIT Stop this POD processing if Source value is TRUE/Non-Zero
- 4.2.19 NOT EXIT Stop this POD processing if Source value is FALSE/Zero
- 4.2.20 RETURN If called by other POD then Return to Caller POD’s Row... Src=Enable
- 4.2.21 RUN POD(nnn) if SrcAddr=TRUE where Operand=POD_INDEX (1 to 9999). POD won’t return.
- 4.2.22 ** COMMENT ** ... 11 Chars in Operand. Not a LABEL (Src and Result Ignored)
- 4.3 Other Functions
- 4.3.1 ABSOLUTE VALUE Src=Value (Operand is ignored)
- 4.3.2 AGA3_1982 Src=Enbl, Oper=10PtrRgs-> 0=Pipe 1=Orif 2=Tb 3=Pb 4=SG 5=SH 6=DP 7=LT 8=LP 9=Fpv ==> SCFH
- 4.3.3 ARCCOS(x) Src=Real32-(-1 to +1) Operand=Ignored Returns REAL32 ArcCOS(x)
- 4.3.4 ARCSIN(x) Src=Real32-(-1 to +1) Operand=Ignored returns REAL32 ArcSIN(x)
- 4.3.5 ARCTAN(x) Src=Real32-(-oo to +oo) Operand=Ignored returns ArcTAN(x)
- 4.3.6 ARCREAD Src=Enbl Opernd(AdrOf5CfgRegs) [0]=NameAdr 1=Offst 2=Rtu 3=Rtdb 4=Cnt
- 4.3.7 ARCWRITE Src=Enbl Opernd(AdrOf5CfgRegs) [0]=NameAdr 1=Offst 2=Rtu 3=Rtdb 4=Cnt
- 4.3.8 ARCZERO Src=Enbl Opernd(AdrOf3CfgRegs) [0]=NameAdr 1=Offst 2=Cnt
- 4.3.9 ARCCHKSUM Src=Enbl Opernd(AdrOf3CfgRegs) [0]=NameAdr 1=Offst 2=Cnt
- 4.3.10 ASYNC-IN Src=Enbl Opernd=PtrAdr 5CfgRgs [0]=ComPort 1=MxLen 2=EndChr 3=TmOut 4=Demrk Result=TypeString
- 4.3.11 ASYNC-OUT (acscomm) Src=Enbl Opernd=PtrAdr 4CfgRgs [0]=ComPort [1]=SendLength [2]=StringAdr [3]=FlushInput...Result=Integer
- 4.3.12 BIT-AND Operand (Strings replace all "<~Or?>" in SrcString with Operand String)
- 4.3.13 BIT-OR Operand (Strings find all OperString in Src and replace with "<~Or?>")
- 4.3.14 BIT-PACK Src=>Start of Booleans Operand=1 to 16 bits to pack
- 4.3.15 BIT-UNPACK Src==>Integer Value Operand=1 to 16 bits to unpack to 1 or more Result Booleans.
- 4.3.16 BIT-XOR Operand (Strings find 1st OperString in Src and replace with "<~Or?>")
- 4.3.17 CENTI-SEC CLOCK Ignore Source and Operand. Free running centisecond Clock
- 4.3.18 CHANNEL CONTROL Source=Chann(0 to 15), Operand=0-Disable,NonZero-Enable : Return NewMode
- 4.3.19 CHECK HTTPPOST Src=Enable, Opernd=Ignored, Returns String Message
- 4.3.20 COPY_DATA_BLOCK Src=Enable, OprndCnst=> Rg[0]=Chn 1=Rtu 2=Rtdb 3=Cnt 4=Chn 5=Rtu 6=DstRtdb
- 4.3.21 COSINE(x) Src=Real32-Radians Operand=Ignored Returns REAL32 cosine(x)
- 4.3.22 DATA LOGGER Src=Enbl, Oprnd=PtrCfg-7 0=AddrStr256(Dir/File) 1=DataAddr 2=Count(Max=125) 3=MaxFiles 4=CSV? 5=w/HHMMss 6=Reserved
- 4.3.23 DB9-READ Src=ComPort(+128 if ttyS) Operand=None Result=Bit0=CTS 1=DCD 8=Error
- 4.3.24 DB9-WRITE Src=ComPort(+128 if ttyS) Operand=BitMask Bit0=RTS Bit1=DTR Result...0=OK else Fail
- 4.3.25 DELAY If Src=TRUE then sleep Operand data Milliseconds
- 4.3.26 DIAGLOG() Operand + Source Value as Strings
- 4.3.27 DNP_CRC Source=StrtUINT8, Operand=Count-UINT8 : Result=CRC (and into UINT8 buffer)
- 4.3.28 DNP_LOG Src=Enbl, Oper=2PtrRgs-> 0=EventBuf, 1=RtdbAdr, Result=0 Else Negative
- 4.3.29 DNP_PULSE_AT_RTDB SrcAddr=Ignored : Operand=RtdbAddress Associated with 1st Pulse Command : Rslt=Echo of Operand or -1 if error
- 4.3.30 DUMP SCRATCHPADS to /tmp/director/S_PADpp.rr.txt where 'pp' is PodNdx & 'rr' is Row if Src=Enable
- 4.3.31 EDGE DETECT Src=BoolInput, Operand=Instance(0 to 9 RisingEdge, -1 to -9 Falling Edge)
- 4.3.32 EXP(x) Src=Real32-InputValue Operand=Ignored Returns REAL32 'e to the x'
- 4.3.33 FORCE POD RTU STATUS Src=Enbl Oprnd=ThisRtuStateState (0=Good,2=Bad) Return:0=Ok, -1=Failed
- 4.3.34 FORCE REGs to VALUE : Source=Enable : Operand=CfgPtr[4] (0=RTU 1=StartOfRegs 2=AdrOfValue 3=Count-1000Max) : Return Integer (0=Success)
- 4.3.35 FORMAT Specifier 'C' Printf in Operand for SrcData, Result should be UINT16,STR-32,STR-256
- 4.3.36 GET CHANNEL NAME Src=Enable, Operand=ChannNumb(0-15), Result=ChanName(Max 15 Chars) else "NOT-READ"
- 4.3.37 GET COLUMN FROM POLL RECORD Src=Ignored : Operand=> 0=SrcChn 1=SrcRtu 2=SrcAdr 5=DestRTDB
- 4.3.38 GET RTU STATUS of Any RTU Src=Channel : Oprnd=RtuAddr : Result=(0=OK,-2=NoChan,2=Timeout,3=BadDat,4=FramErr,5=Stop,6=Trans,7=NoPoll)
- 4.3.39 GET TIME Src/Oprnd=Ignored Result> INT16[0-6]=YYYY,MM,DD,HH,MM,SS,ms INT32=1970+Secs STRING=YYYYMMDD-HHmmSS.ds
- 4.3.40 HTTPPOST Src=Enable Opernd=2PtrCfgs [0]=StartAdrOfStrings 1=CountofStrings
- 4.3.41 INDEXed GET : SourceAddr value is RegAddr used as SrcData=> ResultAdr : Operand Ignored
- 4.3.42 INDEXed SAVE : Src=Data2Save, Opernd=AddressOfSave, Result=Overidden by Operand
- 4.3.43 INTEGER to ASCII BYTE (Ignore Source Address, CHR$(Operand Value))
- 4.3.44 INVERT Bool=Not-Bool, IntBits=iNTbITS, Real=1.0/Real, String=gnirtS (SrcVal-Cast-to-ResultType) Ignore-Operand
- 4.3.45 LOG(x) Src=Real32-InputValue Operand=Ignored Returns REAL32 NaturalLog(x)
- 4.3.46 LONG to REAL Copies 32 bits from Source Value to 32 bits of a Real32 value.
- 4.3.47 MODBUS WRITE Src=Enable Opernd=>PtrAdr 5-CfgRgs [0]=SrcData 1=Cnt 2=DstChn 3=Rtu 4=DataAdr
- 4.3.48 MQtt SEND CMD Src=Enbl (2=MQ-X0,3=MQ-X1 else MQtt), Opernd=CfgReg-5 0=TopicAdr 1=DataAddr 2=DataCount 3=QOS 4=PRIority : Return Handle
- 4.3.49 MY RTU ADDRESS Returns INTEGER
- 4.3.50 NX_19_Fpv Src=Enable, Oprnd=5PtrReg-> 0=Temp 1=Press 2=SpGrv 3=%CO2 4=%N2 ==> Fpv
- 4.3.51 PACK TIME Src=Enbl Oprnd=PtrCfg-6 YY,DD,MM,HH,MM,SS : RETURN SecondFrom1970
- 4.3.52 PARSE MQtt RBE Data Src=Enbl, Opernd=CfgPtr3 0=CountTopics 1=TopicAddr 2=DstChan-Rtu-DataMin/MaxAddr-StatReg(X5) : Return Seq-Number
- 4.3.53 PC-104 DS-DMM-16-AT SrcAs5Addr=>Rg[0-4]=Ao(1-4)+DigOut8 : Operand=CardPortAdr : Rslt=Regs[0-21] DIs,AIs,CIs,Brd-ID
- 4.3.54 PC-104 IN-8 Src=Ignored Operand=CardPortAdr : Returns 8 Bit Packed Integer
- 4.3.55 PC-104 IN-16 Src=Ignored Operand=CardPortAdr : Returns 16 Bit Packed Integer
- 4.3.56 PC-104 MULTI-IO-16se SrcAs2Addr=>Rg[0]=Ao1 Rg[1]=Ao2 Operand=CardPortAdr Rslt=Regs[0-20]
- 4.3.57 PC-104 MULTI-IO-8-DIFF SrcAs2Addr=>Rg[0]=Ao1 Rg[1]=Ao2 Operand=CardPortAdr Rslt=Regs[0-12]
- 4.3.58 PC-104 OUT-8 Src=8-PackedBits Operand=CardPortAdr
- 4.3.59 PC-104 OUT-16 Src=16-PackedBits Operand=CardPortAdr
- 4.3.60 PC-104 TS-ADC16 SrcAs5Addr=>Rg[0-4]=Ao(1-4)+DigOut : Operand=CardPortAdr : Rslt=Regs[0-21] DIs,AIs,CIs,Brd-ID
- 4.3.61 PID-LOOP Src=Enbl, Oprnd=11Cfg-> 0=Ndx 1=(0=P,PI,PID,PIDp=3) 2=K.1% 3=T0(s/rpt) 4=T1 5=DirctAct 6=PV 7=SP 8=Man 9=Ovrd 10=MxErr =>0-4095
- 4.3.62 POWer (x^y) Src=Mantissa, Operand=Exponent Returns REAL32
- 4.3.63 PUBCONN Connection Status with MQtt Broker Src=Enbl(2=MQ-X0, 3=MQ-X1 else MQtt) : Return=(1=TryConnect, 2=Connected, 0=Disconnect)
- 4.3.64 PUBHOST Which Host Table Entry is being used SrcAddr=Enable(2=MQ-X0, 3=MQ-X1 else MQtt) : Return=(Int[0-N-row], String[Iface,IP@ -1])
- 4.3.65 PUBLISH Src=Enbl(2=MQ-X0, 3=MQ-X1) Oprnd(AdrOf-8) 0=AddrTopic256 1=QOS 2=Retain 3=Priority 4=Rtu 5=RtdbAdr 6=Count 7=BigEnd : Rtn=Handle
- 4.3.66 PUBNUMQ Number of Pending MQtt Messages Src=Enbl(2=MQ-X0, 3=MQ-X1)
- 4.3.67 PUBQUERY Check state of a message on the Q. Src=Enbl(2=MQ-X0, 3=MQ-X1) : Operand=QueHandle : Retrn=(-1[NotFound) to 7[GotPubACK])
- 4.3.68 PUBWALK Walk the MQtt-Broker Connection Table SrcAddr=Enable(2=MQ-X0, 3=MQ-X1)
- 4.3.69 PULSE FACTOR Src=RawCount, Oprnd=3PtrCfg-> [0]=K(Pls/Vol), 1=PrevRawCnt, 2=TotalVolume, Result=New Volume Increment
- 4.3.70 QUALITY ASSIGNMENT Src=RegWithQuality, Opernd=Address Of Reg To Assign : Returns 0 if Src Quality GOOD else -1 if BAD
- 4.3.71 RANDOM Number (Ignore Source) Operand=Seed (e.g. Time), Returns 0 to 2147483647
- 4.3.72 REAL to LONG Copies 32 bits from Source Value to 32 bits of an Int32 value
- 4.3.73 REVERSE [1,2,4] BYTE WORD Src=OriginalBits, Operand=1,2,4 Bytes-SrcData Rslt=Bits Reversed (Force to INTEGER)
- 4.3.74 RTU NAME SrcAddr=Channel : Operand=RtuAddr : Result is STRING
- 4.3.75 SCRAMBLE Src=Enbl Opernd=PtrAdr 3CfgRgs [0]=StringAdr 1=TextLen 2=Scramble? Result=Converted String
- 4.3.76 SEGRECV Src=Enable Operand=PtrAdr-7CfgRgs 0=ComPrt 1=RtdbStrt 2=Cnt 3=BigEndn? 4=CkSm(1=Sum,2=CRC,3=CRCrevrs) 5=TmOt 6=Dmrk: Retrn=NumByte(Negtiv=Err)
- 4.3.77 SEGSEND Src=Enable Opernd=7PtrCfgs [0]=ComPort 1=StrtAdr 2=Count 3=BigEndn 4=Check(1=Sum,2=CRC,3=CRCrevrs) 5=TmoutMsc 6=DemrkMsc : Return=NumByteSent
- 4.3.78 SEND BIRTH/DEATH CERTIFICATE Src=Enbl(2=MQ-X0, 3=MQ-X1 else MQtt) Oprnd=3CfgRgs[] 0=Chan 1=Rtu 2=(1=Birth,0=Death) Return:0=Ok -1=Fail
- 4.3.79 SET RTU STATUS Src=Enbl Oprnd=3CfgRgs[] 0=Chan 1=Rtu 2=State(0=Good,2=Fail) Return:0=Ok, -1=Failed
- 4.3.80 SINE(x) Src=Real32-Radians Operand=Ignored : Returns REAL32 SINE(x)
- 4.3.81 SQUARE ROOT of Source Value
- 4.3.82 STRING DROP PART Src=String, Oprnd=NumBytes (Negatv=Left: Positv=Right)
- 4.3.83 STRING GET PART Src=String, Oprnd=NumBytes (Negatv=Left: Positv=Right)
- 4.3.84 STRING HEADER Src=Original_String Operand=Delimiter : Result=String to Left of 1st Delimiter
- 4.3.85 STRING LENGTH of Src=String, Operand=Ignored, Result=Integer Length of String
- 4.3.86 STRING TO LOWER Convert SrcString to Lower case, Ignore Operand.
- 4.3.87 STRING TO UPPER Convert SrcString to Upper case, Ignore Operand.
- 4.3.88 STRING TRAILER Src=Original_String Operand=Delimiter : Result=String to Right of Last Delimiter
- 4.3.89 STRING VALUE of Src=String with Operand ignored, Result=Integer value of String
- 4.3.90 SUBSCRIBE TO TOPIC Src=Enable(2=MQ-X0,3=MQ-X1 else MQtt) : Opernd=TopicString-256 : Result=SubscribeQueIndex
- 4.3.91 SUBSCRIBED RECV'd DATA Src=Enable : Opernd=Cfgs[3] 0=AddrOfTopic 1=AddrOfUint8Data 2=Spare : Return=CntDataBytes
- 4.3.92 SYSTEM COMMAND Src=Shell_Script, Operand= Shell_Script_Parameters : Returns (Integer) 0 if Successful
- 4.3.93 TABLE-23B Src=Observd-Density(kg/m^3) : Opernd=Temp-degF : Result=Density @60degF
- 4.3.94 TANG(x) Src=Real32-Radians Operand=Ignored Returns REAL32 TANG(x)
- 4.3.95 TEXT FIND Src=SrchString, Operand=ResultBufSize(<256) : Returns up to BufSize bytes after Search-String
- 4.3.96 TEXT FLUSH Buffer
- 4.3.97 TEXT OPEN Src=FileName : Result is File Size, ignore Operand
- 4.3.98 TEXT READ Src=Delimiter(s) Operand=MaxBytes, Returns String before the Delimiter
- 4.3.99 TEXT REMAINING : Ignore Src/Oprnd. Number of Bytes Still unread remaining in Buffer
- 4.3.100 TTYsIN Src=Enbl Opernd=PtrAdr 5CfgRgs [0]=ComPort 1=MxLen 2=EndChr 3=TmOut 4=Demrk Result=TypeString
- 4.3.101 TTYSOUT Src=Enbl Opernd=PtrAdr 4CfgRgs [0]=ComPort [1]=SendLength [2]=StringAdr [3]=FlushInput
- 4.3.102 UNIT NAME from Apex System Object as from 'hostname'
- 4.3.103 XML GET COUNT Src=Enabl, Opernd=PtrReg-> 4CfgRgs [0]=ElemntName 1=Parent 2=Attrib1 3=Attrib2
- 4.3.104 XML GET FIELD Attributes Src=Enabl, Opernd=PtrReg-> 6CfgRgs [0]=ElemntName 1=Parent [2-5]=AttributeNames
- 4.3.105 XML NEXT FIELD Src=Element Name to Advance, Opernd=Ignored Returns INTEGER Number of bytes still in Buffer
- 4.3.106 ZERO All Scratchpad Elements (-1 to -40)
- 4.1 Function Reference Chart
Introduction
The RediGate is a multi-application remote data communications computer/data integration device. It provides a wide array of SCADA and other communication and logic processing functionality. In order to configure the operational characteristics of the RediGate, Elecsys provides the Advanced Configuration Environment (ACE) program.
The RediGate allows for programmable logic routines to be included in its ACE configuration, called PODs (for “Programming On Director”). This allows some reasonably complex operations to be performed during the RediGate’s operation, such as examining or changing contents of data registers, performing logical decisions or mathematical computations, publishing data, and a variety of other functions.
Unlike ISaGRAF, which requires a third-party software development environment and generates a reusable, multi-module logic program that is semi-autonomous from the RediGate configuration, the POD logic routines are small, individual programs built into each configuration and may be more easily customized for the needs of a specific device. Both ISaGRAF logic and POD routines may be used in the same RediGate, if desired. Refer to the RediGate Configuration Manual for more discussion on the differences between ISaGRAF and POD logic.
It is assumed that the user has already installed the ACE Editor and is familiar with the ACE configuration tools. Please refer to the ACE Operation Manual for more details on using ACE to configure basic RediGate features such as master or slave protocol communication.
POD Programming
Historically, the RediGate has supported the ISaGRAF programming environment for adding functional logic programs that provide a wide variety of powerful application development options. ISaGRAF provides a full-featured application development environment, allowing the RediGate to operate as a programmable logic controller (PLC) in addition to its built-in routing, protocol translator, and host data publishing capabilities.
However, some applications only require a small to moderate level of programmability, such as manipulating or making decisions on data stored in real-time databases (RTDBs). For these types of requirements, the RediGate now supports the POD (Programming On Director) capability. POD programming is similar in concept to Assembly Language programming, having a list of opcodes having one or more parameters.
There can be up to 9999 PODs per Internal Master Channel. The following sections describe how to program POD modules in the RediGate’s ACE configuration.
POD Configuration Structure
POD objects are executed by the Internal Master Channel, by calling an Internal Master Poll Table entry that references the POD definition. The Internal Master RTU object determines which POD will be executed and the Scan Table determines when it is called. More than one Field Unit in the Internal Channel can call the same POD.
To run a POD program, the following set of ACE objects need to be configured:
Internal Channel Configure Scan entry points to a Poll Record of an Internal Master field unit that’s configured to run a POD. The Scan Table entry is used like any other Scan Table entry (Unit Address and Poll Record point to the Internal Master Poll Table entry, and the Scan Period determines the frequency at which the POD will be executed, sequentially with other Scan Table entries in the list).
Null Circuit – Placeholder for Internal Master field unit
Internal Master – The Internal Master FieldUnit may contain other Poll Table entries for data transfers between RTDBs. One or more Poll Table entries may also be configured to point to a POD object, which will contain the programming instructions to be run. The normal Source/Destination fields of the Internal Master Poll Table have special uses when calling a POD program.
The Poll Table entry for a POD routine should contain:
Src Chan – The Source Channel column for a POD poll entry MUST be any valid Master Channel in the RediGate configuration. Otherwise, the Src Chan, Src RTU, Src Data, and Dest Data parameters are not used in the Poll Table entry and may typically be set to 0. However, these columns may be used to pass important information into the POD. There is a POD function ("GET COLUMN FROM POLL RECORD") which can read values from these fields of the Poll Table row that called the POD.
Src RTU – Unused for POD, but can be used for a configurable parameter (see note for “Src Chan”, above).
Src Data – Unused for POD, but can be used for a configurable parameter (see note for “Src Chan”, above).
Src Type – Select the “Run POD” option to use this poll record to call a POD function.
Src Count – This must be set to the instance number of the POD object in the ACE configuration.
Dest Data – Unused for POD, but can be used for a configurable parameter (see note for “Src Chan”, above).
The screen capture below shows an Internal Master unit with a regular poll in Poll Record 1 and a call to a POD function in Poll Record 2. Both polls would need to be scanned by the Internal Channel in order to operate, and a POD object with instance number 5 would also need to be configured with one or more program steps.
RTDB – All FieldUnits require an RTDB definition. The POD is associated with the RTDB for whichever instance of the Internal Master FieldUnit that triggered it. Programming instructions act on the RTDB registers associated with that Internal Master FieldUnit.
POD – Include one or more POD object with programming logic instructions. Configuration of the POD object and the available instruction types are described in the remainder of this manual.
POD programs may use RTDB registers for storing or using data during program execution. There is also a Scratchpad area containing 40 elements (numbered -1 to -40). The Scratchpad elements may use any of the following three data types:
32-Bit INTEGER. These are used for BOOLEAN (Zero=False, Non-Zero=True), CHAR, SHORT integer, and LONG integer data.
32-Bit REAL (Floating Point)
256-Byte STRING
When the RediGate restarts, the values in Scratchpad areas are all set to zero/empty and the type is set to INTEGER. Scratchpad elements are global to a Channel (shared in common among all PODs and devices on a Channel), but each Channel has its own set of numeric Scratchpad elements (-1 to -40). An element in the Scratchpad can have its value and type changed each time a POD program writes to it. Once written to, the element retains its value and type (INTEGER, REAL or STRING) until the next write, even between successive executions of different PODs.
For example, writing a REAL value (such as 3.14159) to element ‘-5’ makes that element into a REAL type, and the value can be accessed as the same. Later, a STRING value (such as “Hello, World”) can be written to element “-5”, which changes the element’s type to STRING. The next read of element ‘-5’ will return “Hello, World”. When POD programs need to use intermediate values in calculations, it is much faster to read or write Scratchpad elements than the read or write RTDB registers.
The POD maintains a row execution counter which is used to prevent infinite loops. If the POD Interpreter does not return to the normal Internal Master Scan Table within this limit, then the POD Interpreter routine is aborted.
POD Object
The POD object holds one set of programming instructions to be called by the Scan Table based on the Scan Period.
Attributes | Function |
|---|---|
Object Type | DirectorPod |
Parent(s) | System → Clients → Master Channels → Internal Channel |
Instance | Must be between 0 and 9999. The instance number is the POD number in the Poll Table ("Src Count" column) used for running the program. |
Properties | Values |
|---|---|
Row Delay | Enter the amount of delay (in milliseconds) to insert after each instruction in the list of Instructions is executed. Entering 0 will allow the POD to run as fast as possible. Inserting non-zero a delay will help debug a POD by slowing it while viewing diagnostics and enables more diagnostic messages from the POD interpreter. |
Max Instructions | Maximum number of instruction rows that can be executed per scan in the sequence of the POD program. This includes all instructions executed while inside a program loop. This parameter is designed to prevent the POD program getting into an infinite loop based on incorrect design of a POD program. Set this to 0 to disable loop testing. This might be used, for instance, with a POD routine that never needs to exit, or which loops through several hundreds of instruction lines. |
Instructions | Click the Edit Table button to enter the sequence of instructions of each POD program. The POD program instructions are executed top to bottom each time the POD is triggered using a Scan Table entry in the Internal Master. Enter the data in the columns of the table.
Source Addr – The Source Addr column either refers to the location of data in the Field Device RTDB, or values in one of the Scratchpad elements (-1 to -40). The type of data from the RTDB/Scratchpad sets the data type for the entire row to either INTEGER, REAL or STRING. (A Function can change the data type that will be saved to the Result Address). Some functions ignore the Source Addr parameter. Function – There are over 100 "Functions" available as POD programming instructions. Some functions only accept only one data type (Integer, Floating point, String), while others can accept two or all three data types. See POD Function List for a complete description of the available programming instructions. Operand Type and Operand – The Operand Type column determines how to interpret the 11-character string contained in the "Operand" entry. The Operand is normally used by the simpler functions (+,-,*,/, AND, OR, XOR, etc). Some Functions ignore the "Operand".
Result Addr – The Result Addr column can be either a register address in the RTDB of the Internal Master field unit, or one of the Scratchpad elements (-1 to -40). See Rules for Using the Result Addr for rules on how the Function output will be converted based on the destination type. Cast Result As – The Cast Result As column determines the output type of data, when the Function operates on a numeric value. The data type (Boolean, UINT32, FLOAT, STRING-32, etc.) must match the data type configured for the Result Addr register in the RTDB.
|
The following sections below describe some additional help in programming with PODs, the Functions used in the POD programming instructions, and some application examples using PODs.
Rules for Using the Result Addr
Here are some rules for the Result Addr parameter of the POD Instruction list, when storing a value.
Saving result to Scratchpad elements [-1 to -40].
When the Cast Result as is BOOLEAN, CHAR, SINT16, or SINT32 – The Scratchpad data is stored as INTEGER. If the original value was REAL, then the value is truncated at the decimal point before being stored. If the original data was STRING, then the atoi() function (Alpha to Integer) converts the string to an integer.
When the Cast Result as is REAL32 – The Scratchpad data is stored as REAL. If the original value was INTEGER, then the value is converted to a REAL. If the original value is a STRING, then the atof() function will convert the string to a floating point value.
When the Cast Result as is STRING-32 or STRING-256 – The Scratchpad data is stored as STRING. If the original value was INTEGER, then the “%d” C format is used to convert the integer to a string. If the original value was REAL, then the “%g” C format is used to convert the floating value to a string.
Saving result to RTDB registers of the following types using INTEGER functions.
Boolean register: Non-zero INTEGER stored as True, Zero stored as False.
UINT8 register: Least Significant Byte of INTEGER stored in register.
SINT16/UINT16 register: Least Significant Word of INTEGER stored in register.
SINT32/UINT32 register: Entire INTEGER result will be stored.
REAL32 register: INTEGER result will be converted to floating point and stored.
STRING-32/256 registers: INTEGER result stored as formatted string.
Saving result to RTDB registers of the following types from REAL functions.
Boolean register: Non-zero value stored as True, Zero stored as False.
UINT8 register: Least Significant Byte of the REAL value after it has been truncated to an Integer.
SINT16/UINT16 register: Least Significant Word of the REAL value after it has been truncated to an Integer.
SINT32/UINT32 register: REAL value will be truncated to an Integer and stored.
REAL32 register: REAL value stored directly.
STRING-32/256 registers: REAL result will be formatted using the “%g” C format.
Saving result to RTDB registers of the following types from STRING functions.
Boolean register: Non-zero STRING stored as True, Zero stored as False.
UINT8 register: Up to 256 registers will receive one corresponding byte from the STRING.
SINT16/UINT16 register: Up to 128 registers will receive two corresponding bytes from the STRING, with the first ASCII character in the least-significant byte.
SINT32/UINT32 register: Up to 64 registers will receive four corresponding bytes from the STRING with the first ASCII character in the least-significant byte.
STRING-32 register: First 32 characters of the STRING will be stored, the remainder will be truncated.
STRING-256 register: Entire STRING will be stored.
POD Editing Tips
The following tips will be helpful suggestions when creating the POD Instruction list.
Create a row with the Function set to **COMMENT**, with zeroes in all of the numeric columns, and “...” in the Operand Type column. Then select this row and press the “Insert Before...” button dozens of times to create dozens of new identical rows. Then modify these rows to write the POD routine.
If you know the first few letters of the ‘Function’ then move the cursor to that column and type a few characters and then press ALT-DOWN-ARROW. This will highlight the first matching entry from the list of 100+ Functions. If the exact Function that you want was highlighted, then you either need to LEFT CLICK on the entry or use DOWN ARROW followed by an UP ARROW and then press the ENTER key.
Labels may be easier to read by starting them with two hyphens (--) and then up to 9 more characters, entered in the Operand column. This label is used in the GOTO LABEL for ‘FOR LOOP’ Functions. Labels are case sensitive.
Integer values in the Operand column can start with a lower case ‘x’ to indicate the value is in hexadecimal. For example, 255 and x0ff are the same integer value.
POD Programming Tips
Here are some additional tips for programming techniques in writing POD program routines.
Use the DiagLog function to view intermediate values or determine flow of routine.
When designing a program, you can use RTDB registers to store the function's intermediate calculations/results, which will slow the execution speed, but allow you to more easily access the values to troubleshoot problems. Later, you can increase execution speed and reduce use of RTDB registers by converting the program to use ScratchPad elements for storing the intermediate results, if you choose.
A quick technique to pass a couple of configuration parameters to a POD routine is to use the Internal RTU’s Poll Table ‘Src Data’ column or ‘Dest Data’ which are not required for normal POD execution. The ‘GET COLUMN FROM POLL RECORD’ function will use a ‘2’ for ‘Src Data’ and ‘5’ for ‘Dest Data’.
The ‘DUMP SCRATCHPADS’ Function will dump the contents of all of the elements to the file /tmp/director/S_PADpp.rr.txt where ‘pp’ is the POD Index and ‘rr’ is Row Number used making the call.
A technique to implement an expiration timer is to call either the CENTI-SEC CLOCK or GET TIME functions and save the results to a 32 bit integer. Then add the number of 1/100s of seconds to the CENTI-SEC CLOCK value or whole seconds to the GET TIME value. Then compare the current CENTI-SEC CLOCK or GET TIME values to determine if a timer has expired.
It is handy to use the ‘PreInitRTDB.ODF’ object to setup groups of configuration parameters for functions such as MODBUS WRITE, COPY BLOCK, HTTPPOST or any other function that uses the Operand value as a reference to a start of a block of configuration parameters. Also use PreInitRTDB to setup longer strings (31 chars at a time) versus the 11 at a time max in the ‘Operand’ column.
String SEARCH and REPLACE can be implemented using the BIT_OR/XOR with BIT_AND functions. The ‘Source Addr’ data string is searched for all occurrences of Operand Strings and replaced with “<~Or?>” string(s) using the BIT_OR Function. Then you will call the BIT_AND which will search the ‘Source Addr’ data string for “<~Or?>” and replace all matches with the Operand String. The BIT_XOR will only search for the first occurrence of Operand String.
If you have some knowledge of writing Linux shell scripts then you can use SYSTEM CALL to echo text to an output file in /tmp/director/ and then call the script. You should output the results of shell scripts to something like /tmp/director/ResultXX.txt. You can use the OPEN_TEXT, FIND_TEXT, etc., to read the contents of these result files.
How to use XML functionality. If you need to work with XML formatted string data, you can use the following techniques.
Open XML text file with TEXT OPEN function call. This reads the file into an allocated memory buffer. Parent Sections must begin as <ThisParent> and terminate with </ThisParent>. Child Sub-sections must begin with <ThisChild> and terminate with </ThisChild>.
Get the count of Parent sections to read with XML GET COUNT. Set String-0 to the Parent/Major section name with a NULL string in String-1 and String-2. String-1 would normally be Parent Section name so setting it null indicates that there is not a Parent Section. A technique to place nulls into strings is to call INTEGER to ASCII with Constant 0 in Operand. The Major section name should be something like… <remote …or… <channel …as long as it begins with a Greater-than symbol.
Get the count of Child/sub-sections in current Parent/major section with String-0 as the Child/Sub-section name, String-1 as Parent Section name, and String-2,3 set to null.
Read the attributes of the Current Parent with XML GET FIELD using String-0 as Parent Name, String-1 set NULL (No parent of this field) and String-[2-9] as Attributes retrieved for this Parent. Strings[2-9] should be look like… address= …or… interface= …etc. The ‘Result Address’ for the XML GET FIELD function is actually used as a starting address of STRING-32 for values of associated Attributes found in Parent. Each Value String will have original Attribute string requested. Remove the original Attribute string (address=) with STRING TRAILER and associated Attribute for Value without attribute. Double quotes that can be removed with ‘- Subtract’, STRING as is, “ which will removed all double quotes. Lastly STRING VALUE can convert the ASCII Value string into an Integer.
Read attributes of each Child/Sub-section (String-0) with String-1 containing the Section’s Parent name. Strings[2-12] are the Attributes to be searched for this child. You can request more Attributes than might be found in the Child’s sub-section. Attributes can be like… lowlimit value= …or… normalstate value= …or… maximum delta= . The Attributes can be continuations of elements in the Child Declaration header or as their own <attrib=”content” /> entries before the </ThisChild> marker. Once the XML GET FIELD reads a Sub-section set of attributes it eliminates the marker starting this Child’s Sub-section. This prevents searching and finding this Child a second time.
After getting the field data for the last Child under the current parent you must call XML NEXT FIELD to eliminate this section’s Parent Marker so that the next Parent will be processed.
POD Programming Examples
This section gives some examples of POD programs to illustrate the POD programming methods. The sample ACE configurations for the programs illustrated here can be downloaded from https://ftp.elecsyscorp.com/ACE/PODDemoConfigurations.zip
See the RediGate Configuration Manual for a more complete explanation of the configuration properties of the individual ACE objects. This section will primarily focus on explaining how the POD logic works, with only minimal discussion on the other parts of the configuration.
Unlatch Relays Example
This example shows how to use a POD to monitor one or more digital registers for a transition from False to True. After the signal becomes true, a configurable timer is started. Once the timer expires, the POD clears the digital register back to a zero.
The background of this example is that a host system writes a Trip signal to the RediGate, which may be read or used by other processes. But the host only sets the Trip value to True and doesn’t clear it, requiring the RediGate to clear the point itself.
UnlatchRelays-PODdemo ACE Configuration
Open the example configuration in the ACE editor.
For purposes of this example, the data coming from a host system is simulated by writing into Virtual RTU 4 using a Custom Report. The Internal Master RTU 5, along with the POD 99, demonstrate the POD programming logic to read and clear the input data points after they are tripped.
This section provides an overview of the parts of the configuration that will be important for understanding this demo.
Virtual RTU 4 – Provides RTDB data location, simulating data that would be coming from the host computer. Registers 1, 3, and 9 are the digital points being written into with Trip signals and cleared by the POD logic.
Internal Master RTU 5 – The Internal Master RTU reads the data internally from RTU 4 into its own RTDB, then runs the POD logic for each of the monitored points (1, 3, and 9). The Internal Master’s Poll Table uses two rows per point to be monitored for Trip values. In each pair of registers, the first row copies the point value from the source RTDB (channel 14, RTU 4) to the Internal Master (RTU 5). The point number in the source and destination databases are the same, and the same number must also be used in the 2nd row of each pair for the Src Data column (this is read by the POD function).
Internal Channel 14 – The Internal Channel contains the Virtual and Internal Master RTUs, and its Scan Table continuously scans the six poll records of RTU 5.
PreInit Data (RTU 5) – The Pre-Initialized Data object stores some default values into the RTU 5 database on startup of the RediGate. These values will be explained in more detail in a later section. The most important of these points is the first, register 41099. This is set to a value of 10, which is the number of seconds for the timer.
POD – The POD program exists as a child object under the Internal Channel (arbrarily set to instance #99 in this example). The details of each step in the POD logic will be explained in more detail in a later section.
Custom Report – A Custom Report is used to give an easy user interface for entering simulated data and seeing the results of the POD activity.
Using the UnlatchRelays Example
If necessary, modify the Ethernet address in the example and download the configuration to a RediGate. After restarting with this configuration, log in to the RediGate’s user menu and go to the Diagnostics menu. Select option 535, View Custom Reports.
Enter ‘99’ for the custom report number, and ‘1’ for the refresh rate. In the custom report, the “DO1”, “DO3”, and/or “DO9” entries will be written to a value of 1 to simulate incoming data from a host system. Once any of these signals goes to ‘ON’, the “PO1”, “PO3”, and/or “PO9” will also be set to ‘ON’. These are registers in the Internal Master RTU 5 used to keep track of the current state of the input. After 10 seconds, both of these values will be reset to ‘OFF’ by the POD logic.
With the Custom Report pointer on the DO1 value, enter ‘C’ to change a value. Enter a value of ‘1’ for DO1, then Enter again to return to the Custom Report screen. The “DO1” and “PO1” should be ‘ON’ for about 10 seconds, then both switch back to ‘OFF’. The same can be done with “DO3” and “DO9”, but changing “DO2”, “DO4”, or “DO5” will not have the same effect, because the configuration is not set up to monitor those points.
Understanding the UnlatchRelays POD Logic
This section gives a detailed explanation of the POD program for the UnlatchRelays example. For more general information about each instruction type in the POD program, see the POD Function List.
Open the Instructions table for the POD in the example program. The following paragraphs describe what each instruction does.
Row | Source Addr | Function | Operand Type | Operand | Result Addr | Cast Result As |
1 | 0 | ** COMMENT ** ... 11 Chars in Operand. Not a LABEL (Src and Result Ignored) | STRING as is (Eleven Characters) | ..SETUP | 0 | SINT32 |
This instruction is just a comment. Comments are used throughout the POD to provide a brief description of what follows (“SETUP”), but also to break up the POD into sections as a visual aid when analyzing the program’s function.
2 | 0 | ASSIGN Operand to Result (Ignore Source Addr) | Constant (Integer or Floating Point) | 0 OFF | -30 | SINT32 |
3 | 0 | ASSIGN Operand to Result (Ignore Source Addr) | Constant (Integer or Floating Point) | 1 ON | -31 | SINT32 |
These rows define the POD’s Scratchpad registers [-30] and [-31] to be constant values of 0 and 1, respectively (everything after the space is ignored and treated as a comment). The ASSIGN function assigns the constant value contained in the Operand column to the Scratchpad register given in the Result Addr column.
4 | -40 | GET COLUMN FROM POLL RECORD Src=Ignored : Operand=> 0=SrcChn 1=SrcRtu 2=SrcAdr | Constant (Integer or Floating Point) | 2 Coil Adr | -32 | SINT32 |
5 | -40 | GET COLUMN FROM POLL RECORD Src=Ignored : Operand=> 0=SrcChn 1=SrcRtu 2=SrcAdr | Constant (Integer or Floating Point) | 5 GrpIndx | -33 | SINT32 |
These rows get a value from the Poll Record of the Internal Master of RTU 5. This instruction refers to the Poll Table record that called this execution of the POD function. The Operand column contains a constant pointing to the column (starting from 0). For example, the 4th row in the Poll Table has the following entries:
Src Chan | Src Rtu | Src Data | Src Type | Src Count | Dest Data |
14 | 5 | 3 | Run POD | 99 | 1 |
The two POD rows read column 2 (Src Data) into Scratchpad register [-32], and column 5 (Dest Data) into Scratchpad register [-33]. These values represent the RTDB register number of the point to be examined, and the POD’s index number for this point, respectively. The index number is a consecutive number starting from 0, used to keep track of each point and their timers individually.
Row | Source Addr | Function | Operand Type | Operand | Result Addr | Cast Result As | ||
6 | -33 | + ADD Operand (Append Strings) | Constant (Integer or Floating Point) | 41001 | -34 | SINT32 | ||
This row adds the value in Scratchpad [-33] (index number) to the constant 41001, and stores the result into Scratchpad [-34]. This will be the register holding the timestamp for each point whenever the Trip value occurs. Registers 41001 through 410xx are required to exist in the RTU 5 database, depending on the highest index number used.
7 | -32 | INDEXed GET : SourceAddr value is RegAddr used as SrcData=> ResultAdr : Operand Ignored | Constant (Integer or Floating Point) | 0 Current | 10097 | SINT32 |
This row does an Indexed Get (indirect read of an RTDB register). The value in Scratchpad [-32] contains a number of the RTDB register of the data point. The value stored in that register is read into register 10097 in the Internal Master. Note that this the Internal Master Poll table must have already polled the data from its original location into the RTU 5 database before this function is called. As an example, the 3rd row in the Poll Table reads register 3 (Channel 14, Unit 4) into RTU 5 at register 3. This is the “Current” value of the point.
Src Chan | Src Rtu | Src Data | Src Type | Src Count | Dest Data |
14 | 4 | 3 | Boolean | 1 | 3 |
8 | -32 | + ADD Operand (Append Strings) | Constant (Integer or Floating Point) | 10000 Last | -35 | SINT32 |
9 | -35 | INDEXed GET : SourceAddr value is RegAddr used as SrcData=> ResultAdr : Operand Ignored | Constant (Integer or Floating Point) | 0 Prev | 10098 | SINT32 |
These rows add 10000 to the Scratchpad [-32] and stores the result into Scratchpad [-35]. This will create a value pointing to a 100xx register in RTU 5. Then an Indexed Get takes the value from the 100xx register snd stores it into register 10098. This is the “Previous” value of the point. The Current and Previous values of the point will be compared below.
10 | 0 | ** COMMENT ** ... 11 Chars in Operand. Not a LABEL (Src and Result Ignored) | STRING as is (Eleven Characters) | ... | 0 | SINT32 |
11 | 0 | ** COMMENT ** ... 11 Chars in Operand. Not a LABEL (Src and Result Ignored) | STRING as is (Eleven Characters) | ..COMPARE | 0 | SINT32 |
12 | 10097 | == EQUAL TO Operand? (Including String Compare) | Constant (Integer or Floating Point) | 0 OFF | -36 | SINT32 |
13 | -36 | EXIT Stop this POD processing Src=Enable | STRING as is (Eleven Characters) | DONE | -40 | SINT32 |
Row 12 performs a comparison between register 10097 (Current) and the constant of 0 in the Operand column. The result is stored into Scratchpad [-36], which is checked in the next row – a True indicates that register 10097=0 (current value of register is not tripped), which triggers the EXIT function in the POD, returning control back to the Internal Master Channel. No further instructions are run on this execution of the POD.
Row | Source Addr | Function | Operand Type | Operand | Result Addr | Cast Result As | ||
14 | 0 | ** COMMENT ** ... 11 Chars in Operand. Not a LABEL (Src and Result Ignored) | RTDB Address (or Scratch-Pad[-1 to -40]) | ... | 0 | SINT32 | ||
15 | 10098 | GOTO LABEL if Src is TRUE/Non-Zero, Operand="Matching Label" | STRING as is (Eleven Characters) | --CHKLIMIT | -40 | SINT32 | ||
Row 15 checks register 10098, and if true (previous value of coil is ON), jump to the POD instruction with the label “--CHKLIMIT” (Row 24). When the original coil is first set to ON, this GOTO statement doesn’t occur, but does happen on subsequent executions of the POD, until the timer expires.
Rows 16 through 22 are only executed when the point value goes from OFF to ON.
16 | 0 | ** COMMENT ** ... 11 Chars in Operand. Not a LABEL (Src and Result Ignored) | RTDB Address (or Scratch-Pad[-1 to -40]) | ... | 0 | SINT32 |
17 | 10097 |