Overview
In this second example, we’ll write an incrementing integer value to the Scratch Pad area of the OptoMMP memory map.
The goals of this example are:
- The client will connect and attempt to reconnect if there are any errors.
- The write requests will trigger as often as possible. Once a request’s response has been processed, the next one will be triggered.
This example assumes you have basic familiarity with creating and running an application in the CODESYS Development System. It also assumes you’ve read the Hello, world! example.
Step 1 - Determine the OptoMMP Address to Use
The value will be written to Element 0 of the Scratch Pad 32-bit Integer area.
The OptoMMP memory map address can be determined in two ways.
- In the “Appendix A: SCRATCH PAD—READ/WRITE” section of the OptoMMP Protocol Guide (form 1465).
- With the MMP Calculator tool in groov Manage. From the Home page, click I/O > I/O Services > MMP Calculator.
The OptoMMP memory map address is 0xF0D81000.
Step 2 - Create and Prepare Project
- Create or open an application within the CODESYS Development System.
- Make sure the Opto 22 Library, version 3.0.0.0 or later, is added to the Library Manager.
- Create a new POU named
MMP_WRITE_INTEGER
with Continuous Function Chart (CFC) as the implementation language. - Add the new program to the Task Configuration.
-
Add the following variables to the Declaration area of the
MMP_WRITE_INTEGER
program.PROGRAM MMP_WRITE_INTEGER VAR mmpClient: OPTO.MmpClient; mmpWriteUDINT: OPTO.MmpClientWriteUDINT; udiVar : UDINT; END_VAR
- Drag out a Box onto the CFC editor and assign it the
ADD
function. -
Configure the inputs and outputs like this:
This will add 1 to
udiVar
every time the CFC program is called.
Step 3 - Initialize the MmpClient Instance
Often it’s desirable to keep a client connected as much as possible. This can be accomplished by taking the client’s xError
output, negating it, and then feeding it back into the xConnect
input.
- In the declaration editor, double-click the
mmpClient
variable and drag it into the implementation area. - Assign
'127.0.0.1'
tosAddress
. - Connect the
xError
output to thexConnect
input. - Deselect the new connecing line.
-
Right-click on the pin for
xError
and select Negate. This should add a small circle at the beginning of the connecting line leavingxError
. Make sure there’s not another circle at the other end of the connecting line.
Connecting xError
and xConnect
in this way will enable the following behavior:
- Initially,
xError
isFALSE
, which causesxConnect
to beTRUE
and begin the connection process. - While connecting,
xError
remainsFALSE
andxConnect
remainsTRUE
. - Once connected,
xConnected
becomesTRUE
,xError
remainsFALSE
, andxConnect
remainsTRUE
. - If there’s an error (either while connecting or once connected),
xError
becomesTRUE
which forcesxConnect
toFALSE
.- On the next cycle, the process begins again. Due to the state change on
xConnect
,xError
is cleared and goes back toFALSE
, sendingxConnect
toTRUE
again.
- On the next cycle, the process begins again. Due to the state change on
It may take one or more PLC cycles for any of the states changes to complete.
Step 4 - Initialize the MmpClientWriteUDINT Instance
- In the declaration editor, double-click the
mmpWriteUDINT
variable and drag it into the implementation area. - A few of the inputs need to be set.
- Assign
1000000
toudiTimeOut
. - Assign
16#F0D81000
toudiMmpAddress
.- This is the OptoMMP memory map address that was determined in Step 1.
- Assign
mmpClient
torClient
.- This is a reference to the client.
- Assign
As stated in the Overview for this example, we want to write the udiVar
value as often as possible. This can be accomplished by taking the MmpClientWriteUDINT block’s xBusy
output, negating it, and then feeding it back into the xExecute
input.
- Connect the
xBusy
output to thexExecute
input. - Deselect the new connecing line.
-
Right-click on the pin for
xBusy
and select Negate. This should add a small circle at the beginning of the connecting line leavingxError
. Make sure there’s not another circle at the other end of the connecting line.
Connecting xBusy
and xExecute
in this way will keep writing the value as often as possible.
- Initially,
xBusy
isFALSE
, which causesxExecute
to beTRUE
and begin the process. - While executing,
xBusy
becomes and staysTRUE
andxExecute
becomesFALSE
. This does not stop the current request from being processed. - Once the response is done being processed,
xBusy
becomesFALSE
, causingxExecute
to becomeTRUE
, thus starting the next request. - If there’s an error,
xError
becomesTRUE
andxBusy
becomesFALSE
, which forcesxExecute
toTRUE
, thus starting the next request.- Your real-world application might require more sophisticated error handling.
- A common error would be caused by the MmpClient not being connected, such as when first starting the program or during a networking issue. The request can still run as often as possible, but will quickly report an error and try again. Once the client is connected, the next request should succeed.
- Additional details are in the CODESYS help documentation for Edge Triggered Function Blocks of the Common Behaviour Model.
Finally, we need to feed th udiVar
variable into the write block. This can be done by directly assigning udiVar
to the udiData
input. Or, for a more visual approach, the ADD
block can be connected to the write block, like this:
The final program should look like this:
Step 5 - Run and View Results
Before running the application, use groov Manage to view the Scratch Pad value.
- In groov Manage, navigate to Home > I/O > I/O Services > Scratch Pad.
- For Data Type, select 32-bit Integer.
- For Index, enter 0.
- For Length, enter 1 or more.
Back in CODESYS:
- Go into Online mode.
- Run the application.
If all goes well, there should be a solid blue line between the client’s xError
output and xConnect
input. The write block’s xBusy
should be cycling between TRUE
and FALSE
, as each request is completed.
Back in the Scratch Pad page in groov Manage, the Scratch Pad element should be increasing.
Ladder Logic Version
This example in Ladder Logic (LD) is very similar. Here’s one way it could be written:
Structured Text Version
This example in Structure Text (ST) is very similar. Here’s one way it could be written:
Next Step
Continue on to the Reading an Integer Array example.