You are not registered yet. Please click here to register!


 
 
plc storereviewsdownloads
This board is for PLC Related Q&A ONLY. Please DON'T use it for advertising, etc.
 
Try our online PLC Simulator- FREE.  Click here now to try it.

New Here? Please read this important info!!!


Go Back   PLCS.net - Interactive Q & A > PLCS.net - Interactive Q & A > LIVE PLC Questions And Answers

Reply
 
Thread Tools Display Modes
Old February 19th, 2015, 12:34 PM   #1
strantor
Member
United States

strantor is offline
 
Join Date: Sep 2010
Location: katy tx
Posts: 331
Any idea how to access the Omron simulator?

I wrote the PLC & HMI program for a subsea tool that we have developed (similar to an ROV but much simpler), and also the user's manual and now working on the training program. We want to have a 3D simulator for operator training. I have no prior experience in 3D animation, but being so deeply ingrained in the operation of the tool, I was chosen as "the guy" to make it happen. For the past weeks I have struggled with a 3D animation suite called Blender, and finally I have created all the geometry and textures and made some animated functions. I have created a very basic 3D video game, starring our tool, using Blender.

Now I would like to incorporate the HMI as part of the simulation, using a touchscreen PC monitor (or NS HMI, if I must). Rather than re-programming all the functions of the PLC and all of the functions of the HMI in Python (the native language of Blender) and recreating all of the graphics, I would like to use what I have already created in CX-Programmer and/or CX-Designer.

I am considering the following possibilities:
Run CX-Programmer and CX-Designer both in simulation mode, linked together. Have Blender inject sensor values and read DMs to/from the link.

Run CX-Designer in simulation mode, linked to blender (I trick CX-Designer to into thinking that Blender is CX-Programmer).

I buy another NS touchscreen and CJ PLC, link them together, and use OmronCSCJEthernetControl OCX to interface Blender with the physical setup. <- I would like to avoid this option.

Any other ideas?
Any thoughts on how to accomplish any of these options, specifically accessing ("hacking") the Omron simulator link?
  Reply With Quote
Old March 12th, 2015, 02:54 PM   #2
strantor
Member
United States

strantor is offline
 
Join Date: Sep 2010
Location: katy tx
Posts: 331
UPDATE:
I have made some progress on this if anybody is interested. I have NOT found a way to hack the CX simulator or communicate with a simulated PLC by FINS commands. I am using an actual PLC and actual HMI (though I could simulate the HMI if wanted). I have created a video game in blender which reads from and writes to the PLC using FINS commands over TCP.

I started with this python 2 FINS code and converted it over to Python 3, which did not convert over gracefully. It took an unjustified amount of finagling to make it work.

Then I wrote an interface script to help it work with Blender. There are a few reasons why this interface script was necessary:

1. I'm a NOOB and couldn't figure out a sleeker way to do it.

2. Looping scripts cause Blender to crash, so the script must be run (repeated) each frame (@24FPS). BUT Blender runs a new instance of the script each time, so looping the original script over and over would result in a new socket connection 24 times per second, which causes the PLC to stop responding to FINS commands. So the original script must run in the background and connect only once, while a different script is executed @ 24FPS making calls to the original every frame.

3. The read/write functions provided in the original script [readMemC(), readFloat(), etc] are individual FINS commands and take about 40mS each to complete. So if you wanted to read 220 DMs, that's almost 9 seconds. In order to get fluid movements out of video game objects, ideally we want a position update every ONE frame, not every 200+ frames. So I wrote new read/write functions. The new read function reads all of memory-areas-of-interest as one single FINS command, and stores them in a library so that you can call them in any order anywhere in your script. The new write command gathers up all of your various "writes" within the script and arranges them into a single command frame and sends it at the end of the script. This cuts the comms time down from 8,800 mS to around 60mS (around every 3 frames - you won't notice it isn't fluid unless you're looking for it). That's 60mS for any number of memory areas up to 249.

4. The original script only allowed for read/write of 16bit UINTs and 32bit REALs. I added funtionality to read/write BCD(UNsigned, BIT signed, and DIGIT signed INTs, DINTs, and LINTs), BITs*, and 32bit and 64bit INTs (signed & unsigned). I may or may not add ASCII/String & HEX functions; I don't need them.

*my bit write function is a compromise. It writes as a word, not a single bit. Behind the scenes it reads a word in, modifies a single bit, and writes it back out. This method leaves room for unpleasant experience if writing a bit surrounded by other critical bits. Best to isolate bits written by python away from other bits used in PLC logic.

5. the original script had little error/exception handling. So errors were shown in cryptic python explanations on a crash screen. I have added a lot of error handling which points in logical directions for debugging.

Here is a sample Python script calling on functions in my Blender interface script (which calls on the original converted Python 2 FINS script):

Code:
import omrblend2

t0 = int(round(omrblend2.time.time() * 1000))
omrblend2.omron().connect("192.168.1.101",9600)

myplc_memD = omrblend2.MasterFetch()
myplc_memD.Fetch("d",300,1000)


#******************************BITS******************************
wbit = myplc_memD.writeBOOL
rbit = myplc_memD.readBOOL

#read/write Bits (16bit words)
MyBitX = "d437.1"
MyBitY = "D437.5"
MyBitZ = "D438.5"
x=rbit(MyBitX)
print("MyBitX ("+MyBitX+") read: " + str(x))
x =abs(1-x)
print("MyBitX ("+MyBitX+"), MyBitY ("+MyBitY+"), MyBitZ ("+MyBitZ+") written: " + str(x))
wbit(MyBitX, x)
wbit(MyBitY, x)
wbit(MyBitZ, x)


#******************************Float******************************
wf = myplc_memD.writeREAL
rf = myplc_memD.readREAL

#read/write FLOAT (32bit)
MyFloat = "d435"
x=rf(MyFloat)
print("MyFloat ("+MyFloat+") read: " + str(x))
x +=1
print("MyFloat ("+MyFloat+") written: " + str(x))
wf(MyFloat, x)



#******************************BCD******************************
wbcd = myplc_memD.writeINT_BCD
rbcd = myplc_memD.readINT_BCD

#read/write unsigned single BCD
MySingleUBCD = "d400"
x=rbcd(MySingleUBCD)
print("MySingleUBCD ("+MySingleUBCD+") read: " + str(x))
x +=1
print("MySingleUBCD ("+MySingleUBCD+") written: " + str(x))
wbcd(MySingleUBCD, x)

#read/write BIT signed single BCD
MySingleBSBCD = "d401"
x=rbcd(MySingleBSBCD,"b")
print("MySingleBSBCD ("+MySingleBSBCD+") read: " + str(x))
x +=1
print("MySingleBSBCD ("+MySingleBSBCD+") written: " + str(x))
wbcd(MySingleBSBCD, x,"b")

#read/write DIGIT signed single BCD
MySingleDSBCD = "d402"
x=rbcd(MySingleDSBCD,"d")
print("MySingleDSBCD ("+MySingleDSBCD+") read: " + str(x))
x +=1
print("MySingleDSBCD ("+MySingleDSBCD+") written: " + str(x))
wbcd(MySingleDSBCD, x,"d")

#read/write unsigned Double BCD
MyDoubleUBCD = "d403"
x=rbcd(MyDoubleUBCD, "u", length=2)
print("MyDoubleUBCD ("+MyDoubleUBCD+") read: " + str(x))
x +=1
print("MyDoubleUBCD ("+MyDoubleUBCD+") written: " + str(x))
wbcd(MyDoubleUBCD, x,"u",2)

#read/write BIT signed Double BCD
MyDoubleBSBCD = "d405"
x=rbcd(MyDoubleBSBCD, "b", 2)
print("MyDoubleBSBCD ("+MyDoubleBSBCD+") read: " + str(x))
x +=1
print("MyDoubleBSBCD ("+MyDoubleBSBCD+") written: " + str(x))
wbcd(MyDoubleBSBCD, x,"b",2)

#read/write DIGIT signed Double BCD
MyDoubleDSBCD = "d407"
x=rbcd(MyDoubleDSBCD, "d", 2)
print("MyDoubleDSBCD ("+MyDoubleDSBCD+") read: " + str(x))
x +=1
print("MyDoubleDSBCD ("+MyDoubleDSBCD+") written: " + str(x))
wbcd(MyDoubleDSBCD, x,"d",2)

#read/write unsigned Long BCD
MyLongUBCD = "d409"
x=rbcd(MyLongUBCD, "u", 4)
print("MyLongUBCD ("+MyLongUBCD+") read: " + str(x))
x +=1
print("MyLongUBCD ("+MyLongUBCD+") written: " + str(x))
wbcd(MyLongUBCD, x,"u",4)

#read/write BIT signed Long BCD
MyLongBSBCD = "d413"
x=rbcd(MyLongBSBCD, "b", 4)
print("MyLongBSBCD ("+MyLongBSBCD+") read: " + str(x))
x +=1
print("MyLongBSBCD ("+MyLongBSBCD+") written: " + str(x))
wbcd(MyLongBSBCD, x,"b",4)

#read/write DIGIT signed Long BCD
MyLongDSBCD = "d417"
x=rbcd(MyLongDSBCD, "d", 4)
print("MyLongDSBCD ("+MyLongDSBCD+") read: " + str(x))
x +=1
print("MyLongDSBCD ("+MyLongDSBCD+") written: " + str(x))
wbcd(MyLongDSBCD, x,"d",4)

#******************************INT******************************
wint = myplc_memD.writeINT
rint = myplc_memD.readINT

#read/write UNsigned single INT
MySingleUINT = "d421"
x=rint(MySingleUINT)
print("MySingleUINT ("+MySingleUINT+") read: " + str(x))
x +=1
print("MySingleUINT ("+MySingleUINT+") written: " + str(x))
wint(MySingleUINT, x)

#read/write signed single INT
MySingleSINT = "d422"
x=rint(MySingleSINT,"s")
print("MySingleSINT ("+MySingleSINT+") read: " + str(x))
x +=1
print("MySingleSINT ("+MySingleSINT+") written: " + str(x))
wint(MySingleSINT, x,"s")

#read/write UNsigned Double INT
MyDoubleUINT = "d423"
x=rint(MyDoubleUINT)
print("MyDoubleUINT ("+MyDoubleUINT+") read: " + str(x))
x +=1
print("MyDoubleUINT ("+MyDoubleUINT+") written: " + str(x))
wint(MyDoubleUINT, x, "u", 2)

#read/write signed Double INT
MyDoubleSINT = "d425"
x=rint(MyDoubleSINT,"s")
print("MyDoubleSINT ("+MyDoubleSINT+") read: " + str(x))
x +=1
print("MyDoubleSINT ("+MyDoubleSINT+") written: " + str(x))
wint(MyDoubleSINT, x,"s",2)

#read/write UNsigned Long INT
MyLongUINT = "d427"
x=rint(MyLongUINT)
print("MyLongUINT ("+MyLongUINT+") read: " + str(x))
x +=1
print("MyLongUINT ("+MyLongUINT+") written: " + str(x))
wint(MyLongUINT, x, "u", 4)

#read/write signed Long INT
MyLongSINT = "d431"
x=rint(MyLongSINT,"s")
print("MyLongSINT ("+MyLongSINT+") read: " + str(x))
x +=1
print("MyLongSINT ("+MyLongSINT+") written: " + str(x))
wint(MyLongSINT, x,"s",4)


myplc_memD.writeOutputValues()

t1 = int(round(omrblend2.time.time() * 1000))
tel = str(t1-t0)
print("time elapsed: " + tel + "mS")
and it outputs this:

Code:
D:\Python34\python.exe "D:/Users/chuck/My Documents/ANIMATION PROJECT/omron integrate/HMI test game/working as of 3.2.15/scratch3.py"
MyBitX (d437.1) read: 1
MyBitX (d437.1), MyBitY (D437.5), MyBitZ (D438.5) written: 0
MyFloat (d435) read: 16.0
MyFloat (d435) written: 17.0
MySingleUBCD (d400) read: 34
MySingleUBCD (d400) written: 35
MySingleBSBCD (d401) read: 34
MySingleBSBCD (d401) written: 35
MySingleDSBCD (d402) read: 34
MySingleDSBCD (d402) written: 35
MyDoubleUBCD (d403) read: 34
MyDoubleUBCD (d403) written: 35
MyDoubleBSBCD (d405) read: 34
MyDoubleBSBCD (d405) written: 35
MyDoubleDSBCD (d407) read: 34
MyDoubleDSBCD (d407) written: 35
MyLongUBCD (d409) read: 32
MyLongUBCD (d409) written: 33
MyLongBSBCD (d413) read: 32
MyLongBSBCD (d413) written: 33
MyLongDSBCD (d417) read: 32
MyLongDSBCD (d417) written: 33
MySingleUINT (d421) read: 24
MySingleUINT (d421) written: 25
MySingleSINT (d422) read: 23
MySingleSINT (d422) written: 24
MyDoubleUINT (d423) read: 22
MyDoubleUINT (d423) written: 23
MyDoubleSINT (d425) read: 22
MyDoubleSINT (d425) written: 23
MyLongUINT (d427) read: 19
MyLongUINT (d427) written: 20
MyLongSINT (d431) read: 19
MyLongSINT (d431) written: 20
Output string written: b'D400',[53, 53, 53, 53, 0, 53, 0, 53, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 25, 24, 23, 0, 23, 0, 20, 0, 0, 0, 20, 0, 0, 0, 0, 16776, 0, 0]
time elapsed: 66mS

Process finished with exit code 0
  Reply With Quote
Old March 12th, 2015, 02:54 PM   #3
strantor
Member
United States

strantor is offline
 
Join Date: Sep 2010
Location: katy tx
Posts: 331
I am willing to share my work, but it is a work in progress and is pretty embarrassing at the moment (I'm really fumbling along - I'm not a computer programmer and this is my first experience with Python) hence why I'm not attaching it here and making it a matter of eternal online permanent record. If anyone would like to contribute or would like to obtain it for their own use, feel free to PM me and I would be happy to send it you what I have.

EDIT:

I just realized that I didn't post anything about where this project could use contribution.
It needs some love from someone who actually knows what they're doing in python.

1. I'd still MUCH rather access the Omron simulator link than use a physical PLC and be limited by network traffic/transmit times.

2. All my data conversions are done by converting UINTs to bit strings and then formatting the bit strings back to the proper format. I'm sure there's a better way.

3. It would be cool if the script could read/write bits directly instead of by modifying bits in a word.

4. From what I've read in Omron docs, I should be able to read/write up to 1900 bytes in one command frame, but for some reason I can only get 498.

5. It would be nice to be able to skip words when writing; as it stands, I have to write every word between the two words that I care about.

6. If I can't get at the simulator link, then some way of speeding up the network comms would be nice.

7. The script could stand to have some string/ASCII & hex function.

8. The script itself could be revamped and made to run faster. general optimization.

9. Maybe the interface script and the original script could be consolidated to simplify things.

10. There is no way I can find to close the connection when the Blender game is finished. So far it hasn't been a problem, but it seems like it should be closed.

11. It would be cool if I could read/write to multiple addresses in multiple memory areas (ex: H101, D450, CIO10, and W53-W86) within a single command frame instead of being limited to an array of addresses in a single memory area as I am now (D305-D415). I'm not sure if that's possible or not given the protocol.

Last edited by strantor; March 12th, 2015 at 03:51 PM.
  Reply With Quote
Old March 12th, 2015, 04:10 PM   #4
BobB
Lifetime Supporting Member
Australia

BobB is offline
 
BobB's Avatar
 
Join Date: Jun 2002
Location: Sydney
Posts: 4,416
The two Omron simulators work with each other with a few exceptions. What seems to be the issue?
__________________
The Old Pfhaart

  Reply With Quote
Old March 12th, 2015, 04:18 PM   #5
strantor
Member
United States

strantor is offline
 
Join Date: Sep 2010
Location: katy tx
Posts: 331
Quote:
Originally Posted by BobB View Post
The two Omron simulators work with each other with a few exceptions. What seems to be the issue?
Oh yes, they work just fine together. The issue is that I want to get my python program into the mix and read/write to simulated PLC with it. I want to be able to access the simulated PLC in the same way that CX-Designer accesses the simulated PLC with its simulated HMI.
  Reply With Quote
Old March 12th, 2015, 04:33 PM   #6
Thomas_v2
Member
Germany

Thomas_v2 is offline
 
Join Date: Apr 2009
Location: Ger
Posts: 449
Hi,

I've made some simulations with Blender too, but with Simatic Plcsim as virtual plc.

In my first version each object has readout the data from the plc by itself.
I've made a new concept, in which each object which has to read out data from the plc, or has to write back data has a special property. Then at the beginning there is a background job, which makes a list, reads out the values from the plc and writes it into the property, where you can do whatever you want with it.

The hardware layer which for siemens is placed in a separate dll, should be easily possible to replace by another vendor.

So you can create the 3d simulation objects independent of the plc hardware.

I've attached a schematic of my concept.
Attached Images
File Type: jpg Blender-Plcsim-Neues-Konzept-Diagramm.jpg (28.4 KB, 42 views)
  Reply With Quote
Old March 13th, 2015, 12:36 PM   #7
strantor
Member
United States

strantor is offline
 
Join Date: Sep 2010
Location: katy tx
Posts: 331
Quote:
Originally Posted by Thomas_v2 View Post
Hi,

I've made some simulations with Blender too, but with Simatic Plcsim as virtual plc.

In my first version each object has readout the data from the plc by itself.
I've made a new concept, in which each object which has to read out data from the plc, or has to write back data has a special property. Then at the beginning there is a background job, which makes a list, reads out the values from the plc and writes it into the property, where you can do whatever you want with it.

The hardware layer which for siemens is placed in a separate dll, should be easily possible to replace by another vendor.

So you can create the 3d simulation objects independent of the plc hardware.

I've attached a schematic of my concept.
To make sure I got this correct.... Since you can't use Blender/Python to directly access the simulated PLC, and you can't use the proprietary Siemens Visual Studio OCX from Python, You make a program in Visual Studio employing the OCX, and this program feeds the sim data to a DLL. Then in python you write a program that accesses the DLL and feeds the data to another Python script running in Blender. Is that correct?
  Reply With Quote
Old March 13th, 2015, 01:53 PM   #8
Thomas_v2
Member
Germany

Thomas_v2 is offline
 
Join Date: Apr 2009
Location: Ger
Posts: 449
Quote:
Originally Posted by strantor View Post
To make sure I got this correct.... Since you can't use Blender/Python to directly access the simulated PLC, and you can't use the proprietary Siemens Visual Studio OCX from Python, You make a program in Visual Studio employing the OCX, and this program feeds the sim data to a DLL. Then in python you write a program that accesses the DLL and feeds the data to another Python script running in Blender. Is that correct?
Yes.
You can use an OCX direct from python, but then you need to install the PythonWin extensions for win32com. This does only work with a separate python installation with the corresponding version to the blender version you are using. You can't use the with blender delivered python dll any more.

Encapsulating the OCX stuff in a separate C-dll makes life much easier, when you think of sharing your project with other people. It all runs out of the box without any additional installations.

Furthermore the PythonWin can't handle all variant type specialities (and the S7 OCX has some flaws too), so I had to read an integer bitwise and assemble the bits in python to an integer - not so good. This is only a problem with the S7 Prosim OCX.


If you want to do some action when the blender game is quit, you can add an object which has a keyboard sensor for the "ESC" key, and add also a "QuitGame" actuator. In the script you do what you want when the ESC is pressed, and then call the QuitGame actuator.

Also you can realise many things in the destructor, if you are using python classes instead of only functions.
  Reply With Quote
Old March 13th, 2015, 05:21 PM   #9
lostcontrol
Lifetime Supporting Member
New Zealand

lostcontrol is offline
 
lostcontrol's Avatar
 
Join Date: May 2009
Location: NeverSayNever
Posts: 815
Are you using the simulator built into CX-P, or the independent simulator application?
We have used the application version for SCADA comms simulation, so should work with your Python scripting.
  Reply With Quote
Old March 13th, 2015, 07:01 PM   #10
strantor
Member
United States

strantor is offline
 
Join Date: Sep 2010
Location: katy tx
Posts: 331
Thank you for the information. I am going to call this issue SOLVED for now and barring any unforeseen bumps in the road, I won't need to simulate the PLC after all. Today i swapped out the CJ1M-CPU12-ETN that I was using for a CJ2M-CPU31. This allowed me to change the PLC <>HMI comms fron FINS to Ethernet/IP for improved comms time with PLC <>PC. Some minor changes to the Python script cut the new & improved comms time even more, by half. Now I'm cyclically reading & writing 498 DMs in under 20mS. Very acceptable for me, and the bonus is that with an actual PLC in the mix I will be able to utilize not only the real machine's HMI screens but also the real machine's physical operators (industrial joysticks, 30mm pushbuttons, etc) instead of cheesy PC gaming joysticks and USB keypad.
  Reply With Quote
Reply
Jump to Live PLC Question and Answer Forum

Bookmarks


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Topics
Thread Thread Starter Forum Replies Last Post
I/O access error, reading raj87 LIVE PLC Questions And Answers 11 October 6th, 2019 03:29 AM
Siemens or Omron? Gromit LIVE PLC Questions And Answers 35 November 14th, 2017 10:44 AM
Logixpro data table Rengas LIVE PLC Questions And Answers 68 April 24th, 2013 01:49 PM
Servo Axis Simulator - Hardware version Contr_Conn LIVE PLC Questions And Answers 26 September 16th, 2008 07:53 AM
access path of pc access!! subnet LIVE PLC Questions And Answers 2 June 19th, 2006 11:24 PM


All times are GMT -5. The time now is 05:55 AM.


.