UPDATE 2: If you want to see communication with S7-200 go here
UPDATE 3: Video walkthrough on setup go here
I recently borrowed a S7-1200 PLC from work to see if I could get data from it using a Raspberry Pi. In my search for something I found that Snap7 was the best option.
Steps to getting it work
- Download and compile snap7 (http://sourceforge.net/projects/snap7/files/1.2.1/snap7-full-1.2.1.tar.gz/download)
- Download and install python library to use snap7 (https://pypi.python.org/pypi/python-snap7)
#download and compile snap7 for rpi wget http://sourceforge.net/projects/snap7/files/1.2.1/snap7-full-1.2.1.tar.gz/download tar -zxvf snap7-full-1.2.1.tar.gz cd snap7-full-1.2.1/build/unix sudo make –f arm_v6_linux.mk all #copy compiled library to your lib directories sudo cp ../bin/arm_v6-linux/libsnap7.so /usr/lib/libsnap7.so sudo cp ../bin/arm_v6-linux/libsnap7.so /usr/local/lib/libsnap7.so #install python pip if you don't have it: sudo apt-get install python-pip sudo pip install python-snap7You will need to edit the lib_location on common.py in the /usr/local/lib/python2.7/dist-packages/snap7/ directory
Add a line in the __init__ part of the Snap7Library class:
lib_location='/usr/local/lib/libsnap7.so'
example below:
class Snap7Library(object): """ Snap7 loader and encapsulator. We make this a singleton to make sure the library is loaded only once. """ _instance = None def __new__(cls, *args, **kwargs): if not cls._instance: cls._instance = object.__new__(cls) cls._instance.lib_location = None cls._instance.cdll = None return cls._instance def __init__(self, lib_location=None): lib_location='/usr/local/lib/libsnap7.so' # add this line here if self.cdll: return self.lib_location = lib_location or self.lib_location or find_library('snap7') if not self.lib_location: msg = "can't find snap7 library. If installed, try running ldconfig" raise Snap7Exception(msg) self.cdll = cdll.LoadLibrary(self.lib_location)
Now you can write your client code :-)
Here's an example on how to connect and read an output Q0.0:
from time import sleep import snap7 from snap7.util import * import struct plc = snap7.client.Client() plc.connect("192.168.12.73",0,1) area = 0x82 # area for Q memory start = 0 # location we are going to start the read length = 1 # length in bytes of the read bit = 0 # which bit in the Q memory byte we are reading byte = plc.read_area(area,0,start,length) print "Q0.0:",get_bool(mbyte,0,bit) plc.disconnect()
I created a helper class on my github here to make the syntax easier for people who are used to DAServer and Ladder:
https://github.com/SimplyAutomationized/raspberrypi/raw/master/S7-1200pi/S71200.py
Example on how to use it:
import S71200 from time import sleep import snap7 from snap7.util import * import struct plc = S71200.S71200("192.168.21.65") plc.writeMem('QX0.0',True) # write Q0.0 to be true, which will only turn on the output if it isn't connected to any rung in your ladder code print plc.getMem('MX0.1') # read memory bit M0.1 print plc.getMem('IX0.0') # read input bit I0.0 print plc.getMem("FREAL100") # read real from MD100 print plc.getMem("MW20") # read int word from MW20 print plc.getMem("MB24",254) # write to MB24 the value 254 plc.plc.disconnect()
Let me know if there are questions. Hope I can help :-)
Also let me know if you can help me clean up my S71200.py helper class. I know it looks messy.
Follow me to get updates on a Raspberry pi Sensor the DA or OPC server can get data using S7 protocol.
+Simply Automationized