OPC-Helper DLL für PB (Beta)

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
mk-soft
Beiträge: 3691
Registriert: 24.11.2004 13:12
Wohnort: Germany

OPC-Helper DLL für PB (Beta)

Beitrag von mk-soft »

Hi,

Um mit OPC einfacher arbeiten zu können habe ich nun die erste DLL am laufen. Als LIB kann ich diese leider nicht liefern da Tailbite den Code mit der komplexen DCOM Schnitstelle (OPC Costumer Interface) nicht erfolgreich kompilieren kann.

Kurzbeschreibung PBOPC.HTML

DLL und Includes Pack OpcPack.zip

Update v2.4
- Fixed: Speicherleck bei Items löschen.
- Neu: Das ShutdownObject ist jetzt ein Teil des ServerObject und es wird allen Shutdown-Funktionen das ServerObject angegeben.
- Neu: OpcRelease(...) beendet jetzt auch automatisch das ShutdownObject.


Beispiel mit Inat OPC Server

Code: Alles auswählen

;- TOP

; Komment   : OPC Test 
; Version   : v2.2
; Erstellt  : 15.05.2009
; Geändert  : 
; Author    : Michael Kastner (mk-soft)

; Compiler  : Unicode

; *********************************************************************************************************

IncludeFile "PBOPC.pbi"
IncludeFile "PBOPC_Help.pbi"

; *********************************************************************************************************

#OPC_QUALITY_BAD = $00
#OPC_QUALITY_UNCERTAIN = $40
#OPC_QUALITY_GOOD = $C0
#OPC_QUALITY_CONFIG_ERROR = $04
#OPC_QUALITY_NOT_CONNECTED = $08
#OPC_QUALITY_DEVICE_FAILURE = $0c
#OPC_QUALITY_SENSOR_FAILURE = $10
#OPC_QUALITY_LAST_KNOWN = $14
#OPC_QUALITY_COMM_FAILURE = $18
#OPC_QUALITY_OUT_OF_SERVICE = $1C
#OPC_QUALITY_LAST_USABLE = $44
#OPC_QUALITY_SENSOR_CAL = $50
#OPC_QUALITY_EGU_EXCEEDED = $54
#OPC_QUALITY_SUB_NORMAL = $58
#OPC_QUALITY_LOCAL_OVERRIDE = $D8

; *********************************************************************************************************

Procedure test()
; OPC Server verbinden
  Debug "OPC Server verbinden"
  *Server = OpcConnect("INAT TCPIPH1 OPC Server", "")
  Debug GetErrorString(*Server, OpcGetLastError())
  If *Server = 0
    ProcedureReturn 0
  EndIf
  Debug "Fertig."
  ; Gruppe anlegen
  Debug "Gruppe anlegen"
  *Group = OpcAddGroup(*Server, "Test")
  Debug GetErrorString(*Server, OpcGetLastError())
  If *Group = 0
    ProcedureReturn 0
  EndIf
  ; Items anlegen
  Debug "Items anlegen"
  *item1 = OpcAddItem(*Group, "", "Labor.mw80")
  *item2 = OpcAddItem(*Group, "", "Labor.mreal82")
  *item3 = OpcAddItem(*Group, "", "Labor.mstring90.20")
  *item4 = OpcAddItem(*Group, "", "Labor.mx86,1")
  Debug "Fertig."
  
  ; wait for plc
  Debug "PLC Verbinung püfen"
  value1.l
  quality.l
  Repeat
    r1 = OpcReadWord(*item1, @value1, @quality)
    If r1
      Debug GetErrorString(*Server, r1)
      OpcRelease(*server)
      End
    EndIf
    If quality = #OPC_QUALITY_GOOD
      Break
    Else
      count + 1
      If count > 10
        OpcRelease(*Server)
        Debug "PLC Offline"
        End
      EndIf
    EndIf
  ForEver
  Debug "Fertig."
  ; Items schreiben
  r1 = OpcWriteWord(*item1, 100)
  If r1
    Debug GetErrorString(*Server, r1)
  Else
    Debug "Item 1 geschieben. Variant Type: " + Str(OpcGetItemDataType(*item1))
  EndIf  
  set2.f = 11.5
  r1 = OpcWriteFloat(*item2, set2)
  If r1
    Debug GetErrorString(*Server, r1)
  Else
    Debug "Item 2 geschieben. Variant Type: " + Str(OpcGetItemDataType(*item2))
  EndIf
  r1 = OpcWriteString(*item3, "Hallo Welt")
  If r1
    Debug GetErrorString(*Server, r1)
  Else
    Debug "Item 3 geschieben. Variant Type: " + Str(OpcGetItemDataType(*item3))
  EndIf
  Delay(1000)  
  r1 = OpcWriteBool(*item4, #True)
  If r1
    Debug GetErrorString(*Server, r1)
  Else
    Debug "Item 4 geschieben. Variant Type: " + Str(OpcGetItemDataType(*item4))
  EndIf
  Delay(1000)  
  ; item lesen
  value1.l
  quality.l
  r1 = OpcReadWord(*item1, @value1, @quality)
  If r1
    Debug GetErrorString(*Server, r1)
  Else
    Debug "Item 1 gelesen: " + Str(value1) + " Qulity: " + GetQualityText(quality)
  EndIf
  
  value2.f
  r1 = OpcReadFloat(*item2, @value2, @quality)
  If r1
    Debug GetErrorString(*Server, r1)
  Else
    Debug "Item 2 gelesen: " + StrF(value2) + " Qulity: " + GetQualityText(quality)
  EndIf
  
  text.s = Space(100) ; Nur in Unicode
  r1 = OpcReadString(*item3, @text, 100, @quality)
  If r1
    Debug GetErrorString(*Server, r1)
  Else
    Debug "Item 3 gelesen: " + text + " Qulity: " + GetQualityText(quality)
  EndIf
  
  value4.l = 0
  r1 = OpcReadBool(*item4, @value4, @quality)
  If r1
    Debug GetErrorString(*Server, r1)
  Else
    Debug "Item 4 gelesen: " + Str(value4) + " Qulity: " + GetQualityText(quality)
  EndIf
  
  ; Server beenden - Intern werden automatisch die Gruppen gelöscht (OpcRemoveGroup(...))
  Debug "Beenden Server"
  hResult = OpcRelease(*Server)
  Debug "Fertig"
  
EndProcedure

test()
FF :wink:

P.S. Beispiel überarbeitet
Zuletzt geändert von mk-soft am 20.01.2019 13:56, insgesamt 6-mal geändert.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
mk-soft
Beiträge: 3691
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag von mk-soft »

Update v2.21

- Automatische Typenanpassung beim lesen und schreiben der Items
- Server Shutdown Callback eingebunden. MyCallback(*szReason) Beispiel im OpcPack.

FF :allright:
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
nicolaus
Moderator
Beiträge: 1175
Registriert: 11.09.2004 13:09
Kontaktdaten:

Beitrag von nicolaus »

Dumme Frage was ist OPC und für was kann man das gebrauchen?
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Die Frage ist nicht Dumm (können Fragen überhaupt Dumm sein?)!

Ich denke mal, alle die es gebrauchen können werden Wissen was es ist,
aber ein paar Infos für alle anderen wären doch angebracht.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
DarkDragon
Beiträge: 6264
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Beitrag von DarkDragon »

nicolaus hat geschrieben:Dumme Frage was ist OPC und für was kann man das gebrauchen?
http://www.opel-opc.com/

Vielleicht meint er aber auch das hier:

http://de.wikipedia.org/wiki/OLE_for_Process_Control
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Benutzeravatar
mk-soft
Beiträge: 3691
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag von mk-soft »

DarkDragon hat es getroffen

OLE_for_Process_Control

wer mit Automation zu tun hat weiss wo für man es brauchen kann :allright:

War ne heiden Arbeit die DCOM Schnittstelle zum laufen zu bekommen. Ca 3000 Zeilen Code und Deklarationen.

P.S. Tailbite steigt mit ASM Error aus.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
mk-soft
Beiträge: 3691
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag von mk-soft »

Update v2.22

Added
- OpcReadItems
- OpcWriteItems
- VariantHelper_Include v2.08

Mehrere Items auf einmal lesen oder schreiben geht schneller da diese als Block übertragen werden.

Die Items müssen sich aber in der gleichen Gruppe befinden.

FF :wink:
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
mk-soft
Beiträge: 3691
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag von mk-soft »

Update v2.23

Bugfix
- OpcWriteItems(...) - Speicherleck und IMA
- VariantHelper_Include.pb - Macros SafeArray

Added
- DateTime korrektur INAT OPC Server VT_DATE <> VT_BSTR

Info:
Bei den Funktionen OpcReadVariant(...) und OpcWriteVariant(...) werden keine Typenanpassung durchgeführt.
Alle Variant Variablen mit Safearray werden auch keine Typenanpassung durchgeführt.

FF :wink:
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
- chris -
Beiträge: 195
Registriert: 24.08.2005 19:52
Wohnort: Stadtallendorf

Beitrag von - chris - »

Erstmal klasse Arbeit, der Zugriff über OPC (Softing, Deltalogic)
auf S5 und S7-Steuerungen funktioniert prima.

Ich habe hier einen OPC-Server von ABB (Roboter):

Code: Alles auswählen

  ; OPC Server verbinden
    Debug "OPC Server verbinden"
    *Server = OpcConnect("ABB.IRC5.OPC.Server.DA", "")
    Debug GetErrorString(*Server, OpcGetLastError())
    If *Server = 0
      OPCDatenTH = 0
      ProcedureReturn 0
    EndIf
    Debug "Fertig."
    
    ; Gruppe anlegen
    Debug "Gruppe anlegen"
    *Group = OpcAddGroup(*Server, "Test")
    Debug GetErrorString(*Server, OpcGetLastError())
    If *Group = 0
      OPCDatenTH = 0
      ProcedureReturn 0
    EndIf
    Debug "Fertig."          
      
    ; Items anlegen 
    Debug "Items anlegen"   
    *item1 = OpcAddItem(*Group, "", "W2K3_System2.RAPID.T_BEW1.MV_Bewegung.nSatzX")
    *item2 = OpcAddItem(*Group, "", "W2K3_System2.RAPID.T_BEW1.MV_Bewegung.nSatzY")
    *item3 = OpcAddItem(*Group, "", "W2K3_System2.SystemName")
    *item4 = OpcAddItem(*Group, "", "W2K3_System2.RAPID.T_BEW1.MV_Bewegung.tLuftstecher")
    *item5 = OpcAddItem(*Group, "", "W2K3_System2.SystemClock")   
    Debug "Fertig."



      ; item lesen
      r1 = OpcReadWord(*item1, @value1, @quality)
      If r1      
        Debug GetErrorString(*Server, r1)
      Else
        ;Debug "Item 1: " + Str(value1) + " Quality: " + PeekUnicode(OpcGetQualityText(quality))
        SetGadgetText(#String_0, Str(value1) + " : " + PeekUnicode(OpcGetQualityText(quality)))
      EndIf

Funktioniert soweit ohne Probleme:

; OPC Server verbinden
; Gruppe anlegen
; Items anlegen

Beim 'items lesen' wird kein Fehler gemeldet, aber quality zeigt den
Wert '32 (UNKNOWN ERROR)'.

Wenn ich jetzt aber einen anderen OPC-Client (zb.: Softing OPC Demo Client) nehme und die selben Items anzeigen lasse, werden in diesem
Moment auch die Items in meinem Programm richtig angezeigt.

Was kann man da machen?
Benutzeravatar
mk-soft
Beiträge: 3691
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag von mk-soft »

Hi Chris,

vielleicht die Items mehrmals lesen. Habe diese verhalten auch bei INAT OPC festgestellt. Allerdings mit der Quality #OPC_QUALITY_UNCERTAIN

In den Beispielen verwende ich eine schleife bis max 10 durch läufe. dauert wo möglich manchal etwas bis der Server die Verbindung zur Steuerung aufgebaut hat.

FF :allright:
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Antworten