I've been planning on trying this and have been able to get some success. In this example we are going to serve up temperature from the Raspberry Pi using Siemens S7 Protocol. I'm using Wonderware and their DAServer in my tests and will show images of the setup.
For this example in Modbus TCP see here
To use the Pi to communicate with a PLC see here
First From a fresh Raspbian Image:
For Raspberry Pi 2 B add the following to the bottom boot/config.txt
#device tree config
dtoverlay=w1-gpio,gpiopin=4
Add the following to the /etc/modules
w1-gpio
w1-therm
Install python pip:
sudo apt-get install python-pip #Download and build the latest snap7 library: wget http://iweb.dl.sourceforge.net/project/snap7/1.3.0/snap7-full-1.3.0.tar.gz tar -zxvf snap7-full-1.3.0.tar.gz cd snap7-full-1.2.1/build/unix
#if you have a Raspberry Pi 2 B use this command to compile:
#if you have a Raspberry B,B+,A,A+ then use this command to compile:
make –f arm_v7_linux.mk sudo cp ../bin/arm_v7-linux/libsnap7.so /usr/lib/ sudo ldconfig
#if you have a Raspberry B,B+,A,A+ then use this command to compile:
make –f arm_v6_linux.mk all sudo cp ../bin/arm_v6-linux/libsnap7.so /usr/lib/ sudo ldconfig
Download and install python-snap7
sudo pip install python-snap7
Now the Pi should be ready!
We are going to serve up temperature data from a DS18b20 probe connected to the pi. If you are unsure how to connected the probe see hereimport time,ctypes from ctypes import * import logging from threading import Thread import snap7 import snap7.snap7types import sys import os from time import sleep logging.basicConfig() logger = logging.getLogger() logger.setLevel(logging.INFO) globalData = (snap7.snap7types.wordlen_to_ctypes[snap7.snap7types.S7WLByte]*128)() digitalOutputs = (snap7.snap7types.wordlen_to_ctypes[snap7.snap7types.S7WLByte]*16)() digitalInputs = (snap7.snap7types.wordlen_to_ctypes[snap7.snap7types.S7WLByte]*128)() server = None class TempProbe(Thread): """ A class for getting the current temp of a DS18B20 """ def __init__(self, fileName='',tempChangeEvent=None): Thread.__init__(self) self.tempDir = '/sys/bus/w1/devices/' list = os.listdir(self.tempDir) if(list[0][:2]=="28"): fileName=list[0] self.fileName = fileName self.currentTemp = -999 self.correctionFactor = 1 self.enabled = True self.oldTemp = 0 self.temperatureChangeEvent=tempChangeEvent def run(self): while self.enabled: try: f = open(self.tempDir + self.fileName + "/w1_slave", 'r') lines = f.readlines() crcLine = lines[0] tempLine = lines[1] result_list = tempLine.split("=") temp = float(result_list[-1])/1000 # temp in Celsius temp += self.correctionFactor # correction factor # if you want to convert to Celsius, comment this line temp = (9.0/5.0)*temp + 32 if crcLine.find("NO") > -1: temp = -999 self.currentTemp = temp if self.currentTemp != self.oldTemp and self.temperatureChangeEvent: self.oldTemp = self.currentTemp self.temperatureChangeEvent(self.currentTemp) except IOError as e: print "Error: File " + self.tempDir + self.fileName + "/w1_slave" + " does not exist" sleep(5) pass sleep(1) # returns the current temp for the probe def getCurrentTemp(self): return self.currentTemp def setEnabled(self, enabled): self.enabled = enabled def isEnabled(self): return self.enabled temp_probe=None def mainloop(): server = snap7.server.Server() global globaldata server.register_area(snap7.snap7types.srvAreaPA, 0, digitalOutputs) # digital outputs server.register_area(snap7.snap7types.srvAreaMK, 0, globalData) # internal memory server.register_area(snap7.snap7types.srvAreaPE, 0, digitalInputs) # digital inputs server.start() global temp_probe temp_probe = TempProbe() temp_probe.start() # start getting temperature async while True: while True: event = server.pick_event() # write temperature to input memory Input Real 67 (IREAL67) snap7.util.set_real(digitalInputs, 67, temp_probe.getCurrentTemp()) # fires the following when an event happens (connecting clients, read requests...) if event: #logger.info(server.event_text(event)) # print server.event_text(event) print temp_probe.getCurrentTemp() else: break time.sleep(.01) server.stop() server.destroy() temp_probe.setEnabled(False) temp_probe.join() if __name__ == '__main__': if len(sys.argv) > 1: snap7.common.load_library(sys.argv[1]) mainloop() temp_probe.setEnabled(False) temp_probe.join()
Now run it!
Setting up your Wonderware and DAserver
Add a S7Cp device |
Put in the Ip Address of your Raspberry pi |
Create a device group. I called mine Pi |
Add your device items. In this example we are doing temperature at IREAL67 |
Create an Access Name in your wonderware. I called mine Pi |
Create a tagname and reference it to our Temperature item |
attach your tagname to a text field |
If you wish me to show anymore examples of how to write or read inputs or outputs in the pi using this protocol please let me know.