; =============================================================================
; Programmname: Snap7-MinimalDemo
; Beschreibung: Liest zyklisch Daten aus DB1 (PLCsimulate) aus
;
; Erstellt am: 27.11.2016 - 18:25:09
; Autor: Andreas Schweitzer
; Version: 1.0
; Compiler: PureBasic 5.50 (Linux - x64)
; Compiler: PureBasic 5.50 (Windows - x86)
;{=============================================================================
; Compiler-Optionen
; [ ] InlineASM-Unterstützung einschalten
; [x] Unicode-Executable erstellen
; [ ] Thread-sicheres Executable erstellen
; [ ] OnError-Unterstützung einschalten
;
; Executable-Format: Linux
; Library Subsystem:
; Datei-Format: UTF-8
; =============================================================================
; Compiler-Optionen
; [ ] InlineASM-Unterstützung einschalten
; [x] Unicode-Executable erstellen
; [ ] Thread-sicheres Executable erstellen
; [ ] OnError-Unterstützung einschalten
; [x] Moderne Themen-Unterstützung aktivieren (für Windows XP und höher)
; [ ] Administrator-Modus für Windows Vista und höher anfordern
; [x] User-Modus für Windows Vista und höher anfordern (keine Virtualisierung)
;
; Executable-Format: Windows
; Library Subsystem:
; Datei-Format: ASCII
;}=============================================================================
EnableExplicit
; -----------------------------------------------------------------------------
; Hilfsfunktionen
; -----------------------------------------------------------------------------
Structure BLEC
Byte0.a
Byte1.a
Byte2.a
Byte3.a
EndStructure
Procedure BLEC16(*SWord.BLEC) ; Big-Little-Endian Konverter für 16-Bit Werte
Swap *SWord\Byte0, *SWord\Byte1
EndProcedure
;==================================================================================================
Procedure BLEC32(*DWord.BLEC) ; Big-Little-Endian Konverter für 32-Bit Werte
Swap *DWord\Byte0, *DWord\Byte3
Swap *DWord\Byte1, *DWord\Byte2
EndProcedure
;==================================================================================================
Procedure.i GetBit(*DatenByte, BitNummer.i) ; Prüfen ob das angegebene Bit 1 oder 0 ist
If Not (BitNummer < 0 Or BitNummer > 7)
ProcedureReturn PeekA(*DatenByte) >> BitNummer & 1
EndIf
EndProcedure
;==================================================================================================
; -----------------------------------------------------------------------------
; Einbindung Snap7-Bibliothek (Minimalkonfiguration, DB's lesen)
; -----------------------------------------------------------------------------
Global SNAP7_LIB.i
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Windows
If FileSize(GetPathPart(ProgramFilename()) + "libsnap7.dll") > -1 Or FileSize("libsnap7.dll") > -1
SNAP7_LIB = OpenLibrary(#PB_Any, GetPathPart(ProgramFilename()) + "libsnap7.dll")
If Not SNAP7_LIB : SNAP7_LIB = OpenLibrary(#PB_Any, "libsnap7.dll") : EndIf
EndIf
CompilerCase #PB_OS_Linux
If FileSize(GetPathPart(ProgramFilename()) + "/libsnap7.so") > -1 Or FileSize("libsnap7.so") > -1
SNAP7_LIB = OpenLibrary(#PB_Any, GetPathPart(ProgramFilename()) + "/libsnap7.so")
If Not SNAP7_LIB : SNAP7_LIB = OpenLibrary(#PB_Any, "libsnap7.so") : EndIf
EndIf
CompilerEndSelect
If SNAP7_LIB
; -----------------------------------------------------------------------------
; Snap7 Befehle einbinden (Funktion der Befehle siehe Snap7-Doku)
; -----------------------------------------------------------------------------
#S7AreaDB = $84
#S7WLByte = $02
Prototype Cli_Create()
Global Cli_Create.Cli_Create = GetFunction(SNAP7_LIB, "Cli_Create")
Prototype Cli_Destroy(*Client)
Global Cli_Destroy.Cli_Destroy = GetFunction(SNAP7_LIB, "Cli_Destroy")
Prototype Cli_ConnectTo(Client.i, *Address, Rack.l, Slot.l)
Global Cli_ConnectTo.Cli_ConnectTo = GetFunction(SNAP7_LIB, "Cli_ConnectTo")
Prototype Cli_Connect(Client.i)
Global Cli_Connect.Cli_Connect = GetFunction(SNAP7_LIB, "Cli_Connect")
Prototype Cli_ReadArea(Client.i, Area.l, DBNumber.l, Start.l, Amount.l, WordLen.l, *pUsrData)
Global Cli_ReadArea.Cli_ReadArea = GetFunction(SNAP7_LIB, "Cli_ReadArea")
EndIf
; -----------------------------------------------------------------------------
; Hauptprogramm
; -----------------------------------------------------------------------------
Define Event.i
Define Ausgabe$
Define ProgrammName$ = "Snap7-MinimalDemo"
Define Fehler.i = #True
Define ZyklusZeit.i = 1000 ; Zeitwert in Millisekunden, nach dem eine Leseoperation durchgeführt wird
Define TempZeit.i = ElapsedMilliseconds()
Define EditorSchrift.i = LoadFont(#PB_Any, "Courier New", 20, #PB_Font_Bold)
Define Client.i
Define *IpAdresse = Ascii("127.0.0.1") ; IP-Adresse des CP
Define Rack.i = 0 ; Baugruppenträger
Define Slot.i = 2 ; Steckplatz der CPU
Define *S7_Daten = AllocateMemory(50) ; Speicherbereich in den die Daten eingelesen werden (50 Byte)
If SNAP7_LIB
; -----------------------------------------------------------------------------
; Client erstellen und mit Station verbinden
; -----------------------------------------------------------------------------
Client = Cli_Create()
If Cli_ConnectTo(Client, *IpAdresse, Rack, Slot) = 0
; -----------------------------------------------------------------------------
; Fenster für Ausgabe öffnen
; -----------------------------------------------------------------------------
If OpenWindow(0, 0, 0, 800, 600, ProgrammName$, #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget)
EditorGadget(0, 0, 0, WindowWidth(0), WindowHeight(0), #PB_Editor_ReadOnly)
SetGadgetFont(0, FontID(EditorSchrift))
SetGadgetColor(0, #PB_Gadget_BackColor, $000000)
SetGadgetColor(0, #PB_Gadget_FrontColor, $00AA00)
Fehler = #False
; -----------------------------------------------------------------------------
; Hauptschleife
; -----------------------------------------------------------------------------
Repeat
Event = WaitWindowEvent(ZyklusZeit)
Select Event
Case #PB_Event_CloseWindow
Break
Default
; -----------------------------------------------------------------------------
; Daten aus S7 Station lesen
; -----------------------------------------------------------------------------
If ElapsedMilliseconds() - TempZeit >= ZyklusZeit
TempZeit = ElapsedMilliseconds()
If Cli_ReadArea(Client, #S7AreaDB, 1, 0, 50, #S7WLByte, *S7_Daten) = 0 ; der eigentliche Lesebefehl
BLEC32(*S7_Daten + 20) ; Datentypen größer 1 Byte müssen vom Big-Endian ins Little Endian Format konvertiert werden
BLEC32(*S7_Daten + 24)
; -----------------------------------------------------------------------------
; Ausgabe-String zusammenstellen und im Fenster anzeigen
; -----------------------------------------------------------------------------
Ausgabe$ = "Steuerung Ein " + Str(GetBit(*S7_Daten, 0)) + #CRLF$
Ausgabe$ + "Störung Quittieren " + Str(GetBit(*S7_Daten, 1)) + #CRLF$
Ausgabe$ + "Automatik " + Str(GetBit(*S7_Daten, 2)) + #CRLF$
Ausgabe$ + "Start " + Str(GetBit(*S7_Daten, 3)) + #CRLF$
Ausgabe$ + "Stopp " + Str(GetBit(*S7_Daten, 4)) + #CRLF$
Ausgabe$ + "Reset Stückzähler " + Str(GetBit(*S7_Daten, 5)) + #CRLF$
Ausgabe$ + "Steuerung Ein " + Str(GetBit(*S7_Daten + 2, 0)) + #CRLF$
Ausgabe$ + "Störung " + Str(GetBit(*S7_Daten + 2, 1)) + #CRLF$
Ausgabe$ + "Einzelhub " + Str(GetBit(*S7_Daten + 2, 2)) + #CRLF$
Ausgabe$ + "Automatik " + Str(GetBit(*S7_Daten + 2, 3)) + #CRLF$
Ausgabe$ + "Stückzahl erreicht " + Str(GetBit(*S7_Daten + 2, 5)) + #CRLF$
Ausgabe$ + "Hub Aktiv " + Str(GetBit(*S7_Daten + 2, 6)) + #CRLF$
Ausgabe$ + "Materialvorschub " + Str(GetBit(*S7_Daten + 2, 7)) + #CRLF$
Ausgabe$ + "Stößelweg: " + StrF(PeekF(*S7_Daten + 20), 2) + #CRLF$
Ausgabe$ + "Presskraft: " + StrF(PeekF(*S7_Daten + 24), 2) + #CRLF$
SetGadgetText(0, Ausgabe$)
Else
; -----------------------------------------------------------------------------
; Wenn Verbindung unterbrochen wurde (z.B. Kabel), versuchen neu zu verbinden
; -----------------------------------------------------------------------------
If Cli_Connect(Client) = 0
SetWindowTitle(0, ProgrammName$)
Else
SetWindowTitle(0, ProgrammName$ + " - Verbindung unterbrochen")
EndIf
EndIf
EndIf
EndSelect
ForEver
EndIf
EndIf
Cli_Destroy(@Client) ; Client sauber aus dem Speicher entfernen
CloseLibrary(SNAP7_LIB) ; Snap7-Bibliothek schließen
EndIf
; Reservierte Speicherbereiche wieder freigeben
FreeMemory(*IpAdresse)
FreeMemory(*S7_Daten)
; -----------------------------------------------------------------------------
; Wenn keine Verbindung möglich -> Fehler ausgeben
; -----------------------------------------------------------------------------
If Fehler
MessageRequester("Fehler", "Fehler bei Verbindung aufgetreten," + #CRLF$ + "Das Programm wird beendet.", #PB_MessageRequester_Error)
EndIf
End
;