Tipp für Übersetzung aus VB in PB

Anfängerfragen zum Programmieren mit PureBasic.
Ralf
Beiträge: 5
Registriert: 04.04.2006 17:52

Tipp für Übersetzung aus VB in PB

Beitrag von Ralf »

Hallo

Als Anfänger eine gewagte Aktion, aber ich habe einen Vellemann USB-Datenlogger mit DLL für eigene Entwicklungen. Die Beispiele im Handbuch sind natürlich nur in VB und Delphi.
Das Abfragen der Speicheradressen der DLL-Funktionen klappt soweit. Ich weiss nur nicht, wie ich die Datenabfrage mit der Funktion readdata in Purebasic realisieren, bzw. aus VB nach PB übertragen soll. Hat jemand einen Tipp für mich?
Gruß
Ralf

Visual Basic Beispielprogramm

Code: Alles auswählen

Option Explicit
'Declare use of the DLL
'K8047D.DLL interface
'GENERAL PROCEDURES
Private Declare Sub StartDevice Lib "k8047d.dll" ()
Private Declare Sub StopDevice Lib "k8047d.dll" ()
Private Declare Sub LEDon Lib "k8047d.dll" ()
Private Declare Sub LEDoff Lib "k8047d.dll" ()
'INPUT PROCEDURE
Private Declare Sub ReadData Lib "k8047d.dll" (Array_Pointer As Long)
'OUTPUT PROCEDURE
Private Declare Sub SetGain Lib "k8047d.dll" (ByVal Channel_no As Long, ByVal Gain As Long)
'Declare variables
Dim DataBuffer(0 To 7) As Long
Private Sub Check1_Click()
If Check1.Value = 1 Then LEDon Else LEDoff
End Sub
Private Sub Form_Load()
StartDevice
End Sub
Private Sub Form_Terminate()
StopDevice
End Sub
Private Sub Command1_Click()
Dim i As Integer
Dim s As String
ReadData DataBuffer(0)
s = ""
For i = 0 To 5
s = s + Str(DataBuffer(i)) + Chr(9)
Next i
List1.AddItem s
End Sub
Private Sub Option1_Click(Index As Integer)
SetGain 1, Index
End Sub
Private Sub Option2_Click(Index As Integer)
SetGain 2, Index
End Sub
Private Sub Option3_Click(Index As Integer)
SetGain 3, Index
End Sub
Private Sub Option4_Click(Index As Integer)
SetGain 4, Index
End Sub
und hier mein Programmschnipsel in Purebasic

Code: Alles auswählen

If OpenLibrary(0, "K8047D.DLL") 
ledoff=IsFunction(0, "LEDoff")
ledon=IsFunction(0, "LEDon")
readdata=IsFunction(0, "ReadData")
setgain=IsFunction(0, "SetGain")
start=IsFunction(0, "StartDevice")
stop=IsFunction(0, "StopDevice")
Debug ledoff
Debug ledon
Debug setgain
Debug readdata
Debug start
Debug stop
EndIf
CloseLibrary(0) 
End
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 »

Erstmal die DLL-Funktionen und erforderliche Variablen:

Code: Alles auswählen

Global DLL.l
DLL = OpenLibrary(#PB_Any, "k8047d.dll")

Dim DataBuffer(7)

Procedure StartDevice()
  ProcedureReturn CallFunction(DLL, "StartDevice")
EndProcedure
 
Procedure StopDevice()
  ProcedureReturn CallFunction(DLL, "StopDevice")
EndProcedure

Procedure LEDon()
  ProcedureReturn CallFunction(DLL, "LEDon")
EndProcedure

Procedure LEDoff()
  ProcedureReturn CallFunction(DLL, "LEDoff")
EndProcedure

Procedure ReadData_(*Array_Pointer.l)
  ProcedureReturn CallFunction(DLL, "ReadData", *Array_Pointer)
EndProcedure

Procedure SetGain(Channel.l, Gain.l)
  ProcedureReturn CallFunction(DLL, "SetGain", Channel.l, Gain.l)
EndProcedure
Jetzt kannste ja in der Hilfe noch ein bissel lesen und dann nochmal
gezielt fragen :wink:

PS: ReadData kannste auch so deklarieren:

Code: Alles auswählen

Procedure ReadData_()
  ProcedureReturn CallFunction(DLL, "ReadData", @DataBuffer())
EndProcedure
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
Ralf
Beiträge: 5
Registriert: 04.04.2006 17:52

Beitrag von Ralf »

Danke erstmal für die schnelle Antwort. Nach rund 2 Stunden rumprobieren muss ich nochmal dumm fragen.
Das ist ein Datensatz, der vom Logger (mit dem VB-Programm) ausgelesen wurde. " 128 75 0 0 0 15 " Wie kann ich mit PB die Daten abholen? Das kann sich doch nur hier abspielen - oder?

Code: Alles auswählen

Procedure ReadData_(*Array_Pointer.l) 
  ProcedureReturn CallFunction(DLL, "ReadData", *Array_Pointer) 
EndProcedure
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 »

Code: Alles auswählen

Procedure ReadData_(*Array_Pointer.l)
  ProcedureReturn CallFunction(DLL, "ReadData", *Array_Pointer)
EndProcedure

ReadData_(@DataBuffer())
For I = 0 To 7
  Debug DataBuffer(I)
Next
Sollte gehen, oder eben die andere Funktion ohne Parameter nehmen, da das Array sowieso Global ist.
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
Ralf
Beiträge: 5
Registriert: 04.04.2006 17:52

Beitrag von Ralf »

Es funktioniert!! Vielen Dank. Wenn man die Lösung sieht, sieht das immer so einfach aus - nur man kommt nicht drauf - oder Tage später......
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 »

Der VB Code sah für mich im ersten Moment genauso schlimm aus :mrgreen:
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
Ralf
Beiträge: 5
Registriert: 04.04.2006 17:52

Beitrag von Ralf »

Hallo

Da bin ich leider schon wieder. Nachdem das Programm für den USB-Logger fertig war, stellte sich heraus, dass der Logger zu langsam ist. Also habe ich mir einen schnelleren gekauft. AK-Modulbus SERAI812 (8 analoge Eingänge, 12BIT, A/D Wandler =Max186, serieller Anschluss).

Wie das so ist, sind die Beispielprogramme entweder für mittlerweile uralte Sprachen, oder aber VB oder VBA. Ich habe bisher erfolglos versucht das VBA-Beispiel, welches mit einer DLL arbeitet, mit MVCOM umzusetzen. Hier ein kurzer Auszug aus der Beschreibung des Interfaces:

". Die Datenübertragung zum und vom Wandler erfolgt durch direkte Steuerung der Handshakeleitungen der seriellen Schnittstelle.
Der PC stellt an DTR Taktimpulse bereit, mit denen über RTS Daten seriell in den Wandler getaktet werden. Serielle Daten des ICs werden über CTS eingelesen. Der Eingang DSR der Schnittstelle liest den Statusausgang SSTRB des Wandlers, um das Ende einer Wandlung erkennen zu können..... Die Stromversorgung erfolgt über die hochgesetzte TXD-Leitung (BREAK-Zustand)."

Wie muss ich den Wandler ansprechen, bzw. was fehlt um die Daten für die 8 Kanäle zu erhalten?
Egal was ich probiere - ich erhalte keine Daten - der Wandler läuft mit der beiliegenden Demo allerdings wunderbar - die kann ich aber für meine Zwecke leider nicht gebrauchen.

Das VBA-Beispiel

Code: Alles auswählen

Declare Sub OPENCOM Lib "RSAPI.DLL" (ByVal Parameter$)
Declare Sub CLOSECOM Lib "RSAPI.DLL" ()
Declare Sub DTR Lib "RSAPI.DLL" (ByVal Pegel%)
Declare Sub RTS Lib "RSAPI.DLL" (ByVal Pegel%)
Declare Sub TxD Lib "RSAPI.DLL" (ByVal Pegel%)
Declare Function CTS Lib "RSAPI.DLL" () As Integer
Declare Function DSR Lib "RSAPI.DLL" () As Integer
Declare Sub Delay Lib "RSAPI.DLL" (ByVal ms%)

Dim mode(8)

Sub MAIN()
  mode(8) = 142 + 0 * 16: mode(7) = 142 + 4 * 16
  mode(6) = 142 + 1 * 16: mode(5) = 142 + 5 * 16
  mode(4) = 142 + 2 * 16: mode(3) = 142 + 6 * 16
  mode(2) = 142 + 3 * 16: mode(1) = 142 + 7 * 16
  Sheets("Tabelle1").Select
  Columns("A:K").Select
  Selection.ClearContents
  OPENCOM "COM2,19200,n,8,1"
  TxD 1: Rem TXD einschalten
  Delay 100
  DTR 0: Rem  SCL=0
  RTS 0: Rem  DIN=0
  For N = 1 To 1000
   For K = 1 To 8
      Dummy = Shift8(mode(K)): Rem Kanal K, unipolar
      Delay 1
      Highbyte = Shift8(0)
      Lowbyte = Shift8(0)
      Cells(N, K).Value = (16 * Highbyte + Lowbyte / 16)
      Cells(K, 10).Value = (16 * Highbyte + Lowbyte / 16)
   Next K
  Next N
End Sub

Function Shift8(Kommando)
  Bit = 128
  Lesen = 0
  For N = 1 To 8
    If (Kommando And Bit) = 0 Then RTS 0 Else RTS 1
    DTR 1
    DTR 0
    If CTS = 1 Then Lesen = Lesen + Bit
    Bit = Bit / 2
  Next N
  Shift8 = Lesen
  RTS 0
End Function

und hier mein Versuch:

Code: Alles auswählen

Com.s = "Com1: baud=19200 parity=N data=8 stop=1"
HCom.l
HCom = ComOpen(Com,0,255,255)

If HCom>1
ComSetTXD(HCom,1);TXD einschalten
Delay(30)
ComSetDTR(HCom,0);SCL=0
ComSetRTS(HCom,0);DIN=0
EndIf

bit = 128
lesen = 0
For N = 1 To 8
 If Bit = 0: ComSetRTS(HCom,0):Else: ComSetRTS(HCom,1):EndIf
    ComSetDTR(HCom,1)  
    ComSetDTR(HCom,0) 
 If ComGetCTS(hcom)=1:lesen=lesen+bit:EndIf 
    bit=bit/2
    Debug lesen
    Next 

ComSetTXD(HCom,0);TXD ausschalten
Delay(30)
ComSetDTR(HCom,0);SCL=0
ComSetRTS(HCom,0);DIN=0
ComClose(hcom)
End
Gruß
Ralf
Benutzeravatar
FGK
Beiträge: 249
Registriert: 09.01.2005 14:02
Computerausstattung: i5-4430 CPU / 8GB RAM
GeForce GT630
Windows 10 Home / 64-bit
Wohnort: Augsburg

Beitrag von FGK »

@Ralf

Du hast deine DLL ja in deinem Beispiel ja noch nicht geöffnet
und die Funtionen der DLL nicht aufgerufen.
Eigentlich ist das hier das selbe Prinzip wie mit deiner alten
DLL. Lies dir den Post von TS-Soft durch wo er die Lib öffnet
und Wrapper-Funktionen für die DLL-Funktionen schreibt.
Den Codeschnipsel den du da hast ist VBA für Excel denn
die Daten werden da in Zellen der Tabelle abgelegt, das
wirst du also so in PB nicht 1:1 umsetzen können aber
mit Sicherheit ganz ähnlich komfortabel

Gruß FGK
Ralf
Beiträge: 5
Registriert: 04.04.2006 17:52

Beitrag von Ralf »

Ich bin davon ausgegangen, dass wenn man mvcom benutzt die DLL nicht braucht. Da lag ich wohl falsch.

Gruß
Ralf
Antworten