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.
 
 
No comments:
Post a Comment