Wednesday, December 28, 2016

Rasberry Pi - Tutorials - S7-1200 & Snap7 Python - Controlling the PLC Using Rpi GPIO


Long awaited video on how to use the Rpi GPIO to control aspects of the PLC.

Intro to controlling Raspberry Pi's GPIO using python:

Raspberry Pi - Tutorials - GPIOZero - Controlling LEDS Using Rpi GPIO



Using the snap7zero and gpiozero to control the S7-1200 PLC with the Raspberry Pi:

Rasberry Pi - Tutorials - S7-1200 & Snap7 Python - Controlling the PLC Using Rpi GPIO

Wednesday, May 11, 2016

snap7 reconnecting code snippet

In some cases your pi may lose connection with your PLC.. here's some helpful code to get it reconnected (I whipped this up pretty quick, and it's currently untested)
def connect(plc,ip):
    while True:
        #check connection
        if plc.get_connected():
            break
        try:
            #attempt connection
            plc.connect(ip,0,0)
        except:
            pass
        sleep(5)
        
plc = snap7.client.Client()
connect(plc,'10.10.55.109')
while True:    
    try:
        #do stuff 
                
    except Snap7Exception as e:
        connect(PLC)
        # break
connect(plc,ip) method puts your pi in an infinite loop till it is connected. make sure you wrap your methods with a try,except.

Monday, February 29, 2016

Raspberry Pi - Python Snap7 - Mapping and Reading Datablocks


import snap7.client
from snap7.snap7types import *
from snap7.util import *


class DBObject(object):
    pass


offsets = { "Bool":2,"Int": 2,"Real":4,"DInt":6,"String":256}

db=\
"""
Temperature Real 0.0
Cold Bool 4.0
RPis_to_Buy Int 6.0
Db_test_String String 8.0
"""

def DBRead(plc,db_num,length,dbitems):
    data = plc.read_area(areas['DB'],db_num,0,length)
    obj = DBObject()
    for item in dbitems:
        value = None
        offset = int(item['bytebit'].split('.')[0])

        if item['datatype']=='Real':
            value = get_real(data,offset)

        if item['datatype']=='Bool':
            bit =int(item['bytebit'].split('.')[1])
            value = get_bool(data,offset,bit)

        if item['datatype']=='Int':
            value = get_int(data, offset)

        if item['datatype']=='String':
            value = get_string(data, offset)

        obj.__setattr__(item['name'], value)

    return obj

def get_db_size(array,bytekey,datatypekey):
    seq,length = [x[bytekey] for x in array],[x[datatypekey] for x in array]
    idx = seq.index(max(seq))
    lastByte = int(max(seq).split('.')[0])+(offsets[length[idx]])
    return lastByte


if __name__ == "__main__":
    plc = snap7.client.Client()
    plc.connect('10.10.55.109',0,0)
    itemlist = filter(lambda a: a!='',db.split('\n'))
    deliminator='\t'
    items = [
        {
            "name":x.split(deliminator)[0],
            "datatype":x.split(deliminator)[1],
            "bytebit":x.split(deliminator)[2]
         } for x in itemlist
    ]
    #get length of datablock
    length = get_db_size(items,'bytebit','datatype')
    meh = DBRead(plc,10,length,items)
    print """
    Cold:\t\t\t{}
    Tempeature:\t\t{}
    RPis_to_Buy:\t{}
    Db_test_String:\t{}
    """.format(meh.Cold,meh.Temperature,meh.RPis_to_Buy,meh.Db_test_String)
    plc.disconnect();