Python Snap7 OSError:异常:访问冲突读取0x00000000214119D0

时间:2018-12-13 11:33:03

标签: python eoserror snap7

im目前正在使用python-snap7进行项目。 为了执行我的脚本,我使用WinPython64-3.6.7.0Qt5和python-snap7(0.10)软件包以及Windows 10。

# -*- coding: utf-8 -*-
"""
Created on Fri Nov 24 13:41:00 2017
@author: Nils
"""

import snap7
import snap7.client as c
import time
import Neural_Network
from snap7.util import *
from snap7.snap7types import *
from pathlib import Path
import struct

def ReadMemory_E(plc,byte,bit,datatype):
    result = plc.read_area(areas['PE'],0,byte,datatype)
    if datatype==S7WLBit:
        return get_bool(result,0,1)
    elif datatype==S7WLByte or datatype==S7WLWord:
        return get_int(result,0)        
    elif datatype==S7WLReal:
        return get_real(result,0)   
    elif datatype==S7WLDWord:
        return get_dword(result,0)           
    else:
        return None

def ReadMemory_A(plc,byte,bit,datatype):
    result = plc.read_area(areas['PA'],0,byte,datatype)
    if datatype==S7WLBit:
        return get_bool(result,0,1)
    elif datatype==S7WLByte or datatype==S7WLWord:
        return get_int(result,0)        
    elif datatype==S7WLReal:
        return get_real(result,0)   
    elif datatype==S7WLDWord:
        return get_dword(result,0)           
    else:
        return None

#Umwandlung der negativen Bitzahlen in positive Bitzahlen    
def GetVar(EW):
    
    count_Bit = 15    
    EW_Bin = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
    
    if EW >= 0:
        while count_Bit >= 0:
            if EW/(2**count_Bit) >= 1:
                EW_Bin[count_Bit] = 1
                EW -= 2**count_Bit
                count_Bit = count_Bit - 1                
            else:
                EW_Bin[count_Bit] = 0
                count_Bit -= 1      
        return EW_Bin
    
    else:
        EW = EW  * (-1) -1
        while count_Bit >= 0:
            if EW/(2**count_Bit) >= 1:
                EW_Bin[count_Bit] = 0
                EW -= 2**count_Bit
                count_Bit -= 1                
            else:
                EW_Bin[count_Bit] = 1
                count_Bit -= 1      
        return EW_Bin
   
#Zeitüberwachung, einzelne Phase > 30s -> Fehler, Zeitüberschreitung
def Overtime(t_0, EW):
    
        #Zeit seit Start der Phase ermitteln
        t_1 = time.time()                
        total = t_1-t_0
        
        #Zeit > 30 Sekunden -> Zeitüberschreitung
        if((total) > 30):           
            return EW + 20     
        else:
            return EW
#PLC-Variablen auslesen bis gewünschtes Ereignis (Eingangswort, Bit, erwarteter Wert) 
#eingetreten ist
def ReadPLC_Int(EW,Bit,Ex,output):
    #Variable zur Überprüfung, ob das gewünschte Ereignis eingetreten ist    
    Trigger = 2
    #Eingangswörter Initialisieren
    E20_Word = ReadMemory_E(plc,20,0,S7WLByte)
    E21_Word = ReadMemory_E(plc,21,0,S7WLByte)
    E100_Word = ReadMemory_E(plc,100,0,S7WLByte)
    E101_Word = ReadMemory_E(plc,101,0,S7WLByte)
    
    #Eingangswörter werden als Bits in ein Array geschrieben
    E20 = GetVar(E20_Word)      
    E21 = GetVar(E21_Word)
    E100 = GetVar(E100_Word)
    E101 = GetVar(E101_Word)
    
    #Ausgabewörter Initialisieren
    A21_Word = ReadMemory_A(plc,21,0,S7WLByte)
    A21 = GetVar(A21_Word)
    
    #@Phase 4: Merken des letzten passierten Platzes
    if EW == 4:                     
        curent_position = 0      
    
    #Timer Starten zur Zeitüberwachung
    t_start = time.time()           
    
    #Werte überprüfen bis Trigger erreicht ist
    while Trigger != Ex:     
 
        #Auto-Schalter einlesen
        output[1] = E100[10]
        output[2] = E21[10]
        output[3] = E20[11]    
        #Stop-Schalter einlesen
        output[19] = E100[8]
        output[20] = E21[8]
        output[21] = E20[12]
        #Bei Aktivierung des zugehörigen Triggers wird die While-Schleife nach dem     
#aktuellen Durchlauf beendet:
        #Phase 1: Egal welcher Start-Taster gedrückt wurde.
        if EW == 1:                 
            if (E20[10]) | (E21[9]) | (E100[9]):
                Trigger = 1
                
        #Phase 2: Teil an Sensor        
        elif EW == 2:                 
            Trigger = E100[11]       
            
        #Phase 3: Teil an Bandanfang
        elif EW == 3:                 
            Trigger = E20[9]
            
        #Phase 4: Egal welcher Auswurfaktor ausgefahren ist    
        elif EW == 4: 
            if(A21[11] | A21[10] | A21[9]):
                Trigger = 1  
                 
        #Phase 5: Wenn alle Auswuraktor in Ausgangsposition        
        elif EW == 5:                 
            if ((A21[11]) | (A21[10]) | (A21[9]) == 0):
                Trigger = 1   
        
        #Fehlererkennung:
        
        #Fehler wenn Auto-Schalter auf 0    
        elif (E100[10] & E21[10] & E20[11]) == 0:                                     
            EW = 20    
            
        #Fehler wenn Stop-Schalter auf 0
        elif (E100[8] & E20[12] & E21[8]) == 0:       
            EW = 21                   
        
        #Zeit überprüfen (außer bei Phase 1)
        if EW != 1:                 
            EW = Overtime(t_start, EW)     
        #Fehlerüberprüfung: Bei einem auftretendem Fehler wird die While-Schleife sofort 
#unterbrochen               
        if ((EW == 20) | (EW == 21) | (EW == 22) | (EW == 23) | (EW == 24) | (EW == 25)): 
            break     
        
        #Delays in Phase 1 und in Phase 2        
        if Trigger == 1:
            
            #@Phase 1: Kurze Pause wenn sich Magazin nicht in Position "hinten" befindet
            if (EW == 1):
                if (E101[10] != 1):
                    time.sleep(1.5)
                
            #@Phase 2: Pause für Verzögerung des Induktiven-Sensors
            if EW == 2:                           
                time.sleep(1.0)
        #@Phase 4: Letzter Standpunkt des Zylinders auf TB aktuallisieren  
        if EW == 4:                                         
            if E20[13]:
                curent_position = 1
            elif E20[14]:
                curent_position = 2
            elif E20[15]:
                curent_position = 3
                 
        
        #Um Durchlaufzeit in Phase 4 zu minimieren werden nur die nötigen Daten 
#eingelesen
        if EW != 4:
            
            #Eingangswörter werden von der Sps geladen
            E21_Word = ReadMemory_E(plc,21,0,S7WLByte)
            E100_Word = ReadMemory_E(plc,100,0,S7WLByte)
            E101_Word = ReadMemory_E(plc,101,0,S7WLByte)
            
            #Eingangswörter werden als Bits in ein Array geschrieben
            E21 = GetVar(E21_Word)
            E100 = GetVar(E100_Word)
            E101 = GetVar(E101_Word)
        #Wörter werden von der Sps geladen
        E20_Word = ReadMemory_E(plc,20,0,S7WLByte)
        A21_Word = ReadMemory_A(plc,21,0,S7WLByte)
        #Wörter werden als Bits in ein Array geschrieben
        E20 = GetVar(E20_Word)
        A21 = GetVar(A21_Word)
    #Ausgabe Phase 1: Magazin Stellung 
    if EW == 1:                     
        output[0] = E101[10]
        
    #Ausgabe Phase 2: Auto-Schalter überprüfen    
    elif EW == 2:   
        
        #Induktiv -> Silber
        if E101[12] == 1:           
            output[4] = 0
            output[6] = 1
            output[8] = 0
            
        #Nicht induktiv + Hell -> Weiß
        elif E101[13] == 1:         
            output[4] = 0
            output[6] = 0
            output[8] = 1
            
        #Nicht induktiv + Dunkel -> Schwarz
        elif E101[13] == 0:         
            output[4] = 1
            output[6] = 0
            output[8] = 0   
            
    #Ausgabe Phase 3: Dreharm   
    elif EW == 3:
        output[17] = E101[8]        #MA Stoßer eingefahren
    
    #Ausgabe Phase 4: Einsortierung    
    elif EW == 4:                     
        if curent_position == 1:
            output[5] = 0
            output[7] = 0
            output[9] = 1
        elif curent_position == 2:
            output[5] = 1
            output[7] = 0
            output[9] = 0
        elif curent_position == 3:
            output[5] = 0
            output[7] = 1
            output[9] = 0   
            
    #Ausgabe Phase 5: Endstellungen        
    elif EW == 5:
        if A21[11] == 0:
            output[10] = 1
        else:
            Ausgabe[10] = 0
        if A21[10] == 0:
            output[11] = 1
        else:
            output[11] = 0
        if A21[9] == 0:
            output[12] = 1
        else:
            output[12] = 0
        if A21[14] == 0:
            output[15] = 1
        else:
            output[15] = 0
        if A21[13] == 0:
            output[16] = 1
        else:
            output[16] = 0
            
        output[13] = E21[12]        #DA Oben
        output[14] = E21[14]        #DA Start Pos
    
    
    #Ausgabe bei Fehlerfällen:
    
    #Auto-Schalter        
    elif EW == 20:                    
        output[1] = E100[10]
        output[2] = E21[10]
        output[3] = E20[11]    
        
    #Stop-Schalter    
    elif EW == 21:
        output[19] = E100[8]
        output[20] = E21[8]
        output[21] = E20[12]
        
    #Zeitüberschreitung MA    
    elif EW == 22:                     
        output = [0,0,0,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0]   
        
    #Zeitüberschreitung DA
    elif EW == 23:                     
        output = [0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0] 
        
    #Zeitüberschreitung TB
    elif ((EW == 24) | (EW == 25)):    
        output = [0,0,0,0,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0]  
    return output
    
#Fehlerüberprüfung zwischen den einzelnen Phasen
#def Fehler(output):
     
    #Auto-Schalter Fehler
    if (output[1] & output[2] & output[3]) != 1:     
        return 1     
    #Stop-Schalter Fehler    
    elif (output[19] & output[20] & output[21]) != 1:     
        return 1         
        
    #Zeitüberschreitung Fehler
    elif ((output == [0,0,0,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0]) | (output == 
[0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0])  |  (output == 
[0,0,0,0,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0])):
        return 1      
    
    else:
        return 0
    
    
#Entsprechend der Manuellen Eingabe zu Beginn des Programmes wird das ermittelte 
#Output-Array unter dem entsprechenden Dateien-Pfad abgespeichert
def Output_Data_txt(output, function):
    
    cout_data_ind = 0
    count_Bit = 0
    #Trainingsdaten
    if function == 1:
    
        #Ermittlung der nächst möglichen Bezeichnung    
        TD_file = Path("Trainingsdaten/TD_{0}.txt".format(cout_data_ind))
        
        while TD_file.is_file() == 1:
            cout_data_ind += 1
            TD_file = Path("Trainingsdaten/TD_{0}.txt".format(cout_data_ind))
        
        #Schreiben des Output-Arrays in entsprechende txt-Datei
        fobj_out = open('Trainingsdaten/TD_{0}.txt'.format(cout_data_ind),"w")
        
        while count_Bit < 22: 
            fobj_out.write('{}'.format(output[count_Bit]))
            fobj_out.write(";")
            count_Bit += 1
        fobj_out.close()
    
    #Automatisierter Professor
    elif function == 2:
        
        #Ermittlung der nächst möglichen Bezeichnung   
        TD_file = Path("Automatisierter_Professor/Uebergabedaten_{0}.txt".format(cout_data_ind))
        
        while TD_file.is_file() == 1:
            cout_data_ind += 1
            TD_file = Path("Automatisierter_Professor/Uebergabedaten_{0}.txt".format(cout_data_ind))
         
        #Schreiben des Output-Arrays in entsprechende txt-Datei 
        fobj_out = open("Automatisierter_Professor/Uebergabedaten_{0}.txt".format(cout_data_ind),"w")
        
        while count_Bit < 22: 
            fobj_out.write('{}'.format(output[count_Bit]))
            fobj_out.write(";")
            count_Bit += 1
        fobj_out.close()    
        
#Funktionseingabe durch manueller Eingabe ermitteln
def select_function():
    
    Input = input("Welche Funktion soll das Programm durchfuehren:\n\n1 -> Trainingsdaten\n2 -> Automatisierter Professor\n\nEingabe: ")
        
    if Input == 1:
        print ("\nGewählte Funktion: Trainingsdaten")
        return Input
    elif Input == 2:
        print ("\nGewählte Funktion: Automatisierter Professor")
        return Input  
    else:
        print ("\nFalsche Eingabe\n")
        select_function()
  
#Zylinderzahl durch manueller Eingabe ermitteln      
def select_number_cylinder():
    
    Input = input("\nAnzahl der Zylinder im Magazin? (1-12)\n\nEingabe: ")    
    print ("\nGewählte Anzahl: {0}".format(Input))        
    
    if (Input > 0) & (Input <= 12):
        return Input
    else:
        print ("Falsche Eingabe\n")
        select_number_cylinder()
    
    
if __name__=="__main__":
    Output = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]  
    
    #Verbindung mit Sps aufbauen
    plc = c.Client()
    plc.connect('192.168.1.1',0,1)
    #Eingabe der gewünschten Funktion
    function = select_function()
    #Eingabe der Anzahl an Zylindern im Magazin
    number_of_cylinders = select_number_cylinder()
    count_cylinders = number_of_cylinders
    
    while count_cylinders >= 1:
        print (count_cylinders)
        
        #Phase 1: Überprüfung der Startposition des Magazins, nur in erstem Durchlauf 
#vorgegeben
        if count_cylinders == number_of_cylinders:
            Output = ReadPLC_Int(1,0,1,Output)                                  
            print ("Phase 1")          
            print (Output)
        else:
            Output[0] = 1
            
        #Phase 2: Einlesen des Induktion- und Farb-Sensors
        if  Fehler(Output) == 0:
            Output = ReadPLC_Int(2,0,1,Output)                               
            print ("Phase 2")            
            print (Output)
        
        #Phase3: Zeitüberprüfung Dreaharm
        if Fehler(Output) == 0:                                            
            Output = ReadPLC_Int(3,0,1,Output)
            print ("Phase 3")  
            print (Output)
        
        #Phase 4: Einsortierung
        if Fehler(Output) == 0:
            Output = ReadPLC_Int(4,0,1,Output)                              
            print ("Phase 4")              
            print (Output)
        
        #Phase 5: Endstellungen überprüfen
        if Fehler(Output) == 0:                                             
            Output = ReadPLC_Int(5,0,1,Output)
            print ("Phase 5")  
            print (Output)
        
        #Phase 6: Überprüfung der Endposition des Magazins
        #Position nur in letztem Durchlauf vorgegeben
        if ((Fehler(Output) == 0) & (count_cylinders == 1)):                              
            Pos_MA = ReadMemory_E(plc,101,0,S7WLByte)
            Pos_MA = GetVar(Pos_MA)
            Output[18] = Pos_MA[11]
            print ("Phase 6")
        elif ((Fehler(Output) == 0) & (count_cylinders > 1)):
            Output[18] = 1
            print ("Phase 6")
        print (Output)
        #Ausgabe in txt-Format
        Output_Data_txt(Output, function)
        
        #Neuer Durchlauf, Hand- & Stopschalter auf 1
        Output = [0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1] 
        count_cylinders -= 1
        
        
    print ("\nEnde des Einleseprozesses\nNeuronales Netzt wird gestartet...\n")
    Neural_Network.start_neural_Network(number_of_cylinders)

我收到以下错误:

OSError:异常:读取0x00000000214119D0的访问冲突TypeError:byref()参数必须是ctypes实例,而不是'NoneType'。

Traceback (most recent call last):
  File "PLC.py", line 399, in <module>
    plc = c.Client()
  File "C:\Users\WAdmin\Documents\Projektarbeit_Grether_Schlindwein\WPy-3670\python-3.6.7.amd64\lib\site-packages\snap7\client.py", line 38, in __init__
    self.create()
  File "C:\Users\WAdmin\Documents\Projektarbeit_Grether_Schlindwein\WPy-3670\python-3.6.7.amd64\lib\site-packages\snap7\client.py", line 49, in create
    self.pointer = S7Object(self.library.Cli_Create())
OSError: exception: access violation reading 0x00000000214119D0
Exception ignored in: <bound method Client.__del__ of <snap7.client.Client object at 0x000001C024C89080>>
Traceback (most recent call last):
  File "C:\Users\WAdmin\Documents\Projektarbeit_Grether_Schlindwein\WPy-3670\python-3.6.7.amd64\lib\site-packages\snap7\client.py", line 41, in __del__
    self.destroy()
  File "C:\Users\WAdmin\Documents\Projektarbeit_Grether_Schlindwein\WPy-3670\python-3.6.7.amd64\lib\site-packages\snap7\client.py", line 57, in destroy
    return self.library.Cli_Destroy(byref(self.pointer))
TypeError: byref() argument must be a ctypes instance, not 'NoneType'

0 个答案:

没有答案