Gerätetreiber von C nach VB.NET übersetzen

  • VB.NET

Es gibt 5 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Gerätetreiber von C nach VB.NET übersetzen

    Servus,

    ich habe einen Gerätetreiber, geschrieben in VB.net welcher im Rahmen eines Prüfstandes für eine einzelnen Prozeduren die Treiber-Aufrufe der spezifischen Hardware steuert (Compiler: MS Visual Studio 2013).
    Das zentrale Steuergerät, welches auch die externe Hardware anspricht, wurde gegen ein neueres getauscht, welches auch einen neuen Treiber hat. Leider liegt mir der Treiber des zentralen Steuergerätes in c vor, und beinhaltet auch für die externe Hardware icludierte Header.
    Mein Vorhaben ist, den in C geschriebenen Gerätetreiber nach Vb.net umzuschreiben, und in die VB.net Projektdatei zu implementieren. Wie aber greife ich auf die in C geschriebenen Header-Dateien zu? <DllImport()>-Attribut (Imports System.InteropServices) ?
    Hier mal ein Auszug aus den C-Code und meine bisherigen VB.net Übersetzung:
    Spoiler anzeigen

    C-Quellcode

    1. /* Include files */
    2. /* ----------------------------------------------------------------- */
    3. #include "stdafx.h"
    4. #include "cem.h"
    5. #include "key.h"
    6. #include "wcem_main.h"
    7. #include "common.h"
    8. #include "error.h"
    9. #include "tats_util.h"
    10. #include "basicdrv.h"
    11. #include "TraceDefs.h"
    12. #include "pcmdrv.h"
    13. #include "pcm.h"
    14. /* Defines */
    15. /* ----------------------------------------------------------------- */
    16. #define TEXTWND // show pressure during waiting for Vent
    17. #ifdef TEXTWND
    18. #include <TextWndC.h>
    19. #endif
    20. #define PCM_MPS56_READ_BFLEN 50 // Number of Character for ReadBuffer
    21. #define PCM_MPS56_WRT_BFLEN 50 // Number of Character for WriteBuffer
    22. /*
    23. | Bit | Value | Meaning
    24. +-----+-------+-------------------------------------
    25. | 0 | 1 | Ps commanded value reached
    26. | 1 | 2 | Ps operation in progress,
    27. | | | value not reached yet
    28. | 2 | 4 | Pt commanded value reached
    29. | 3 | 8 | Pt operation in progress,
    30. | | | value not reached yet
    31. | 4 | 16 | Not used
    32. | 5 | 32 | Ps and Pt commanded values reached and
    33. | | | stabilized for more than 15 seconds
    34. | 6 | 64 | Ambient pressure reached
    35. | 7 | 128 | Ps and Pt operation in progress
    36. */
    37. #define MPS56_PS_READY 1
    38. #define MPS56_PT_READY 4
    39. #define MPS56_AMBIENT_REACHED 64
    40. #define MPS56_PS_PT_IN_PROGRESS 128
    41. #define MPS56_AMBIENT_REACHED 64
    42. #define MPS56_STABILIZE_TIME 10000 // ensure measure mode is stabilized after activiatinfg MEAS mode
    43. // (Recommendation Arrigo Marchiori 2015-07-07) 10SEC!!
    44. #define MPS56_NEGQC_THRESHHOLD -16.0 // Threshhold for negative QC protection
    45. #define PCM_WAITING_TEXT "Das AIR DATA TEST SET MPS56-BW wird entlüftet. Bitte warten!"
    46. // Device Table Macros
    47. #define SetPCMSendBuf(a,b) TatsDevTabSetModValueDig(a, b, DevTabPCM, DT_PCM_SendBuf)
    48. #define SetPCMReadBuf(a,b) TatsDevTabSetModValueDig(a, b, DevTabPCM, DT_PCM_ReadBuf)
    49. #define SetPCMSendBufTxt(a) TatsDevTabSetModValueChr(a, DevTabPCM, DT_PCM_SendBufTxt)
    50. #define SetPCMReadBufTxt(a) TatsDevTabSetModValueChr(a, DevTabPCM, DT_PCM_ReadBufTxt)
    51. /* ----------------------------------------------------------------- */
    52. /* Modulinterne Datentypen & Enumerationen */
    53. /* ----------------------------------------------------------------- */
    54. typedef enum {
    55. PCM_TYPE_UNDEF = 0,
    56. PCM_TYPE_KOLLSMANNN,
    57. PCM_TYPE_DMA_MPS56,
    58. PCM_TYPE_UNKNOWN
    59. } t_pcmType;
    60. // Statische Variable
    61. // ------------------------------------
    62. char cBufErrMsg[200];
    63. #ifndef TATS_DLL_DUMMY
    64. // *************** Device Table **************
    65. static double sPRESS_A_PS; // PRESS-A Wert für PS-Kanal
    66. static double sPRESS_A_PT; // PRESS-A Wert für PT-Kanal
    67. static double sSLEW_RATE_PS; // SLEW-RATE Wert für PS-Kanal
    68. static double sSLEW_RATE_PT; // SLEW-RATE Wert für PT-Kanal
    69. static short sPSControlMode; // Mode Indikator für PS-Kanal
    70. static short sPTControlMode; // Mode Indikator für PT-Kanal
    71. static short sNeqQC; // Negativer QC Schutz
    72. static short sMachUnit = FALSE; // PRESS-A Wert in [Mach] oder [MB]
    73. static double sPS_Channel; // PS-Kanal Anzeige
    74. static double sPT_Channel; // PT-Kanal Anzeige
    75. static double sPS1_Snapshot; // Snapshot Wort 1 vom PS-Kanal
    76. static double sPS2_Snapshot; // Snapshot Wort 2 vom PS-Kanal
    77. static double sPT1_Snapshot; // Snapshot Wort 1 vom PT-Kanal
    78. static double sPT2_Snapshot; // Snapshot Wort 2 vom PT-Kanal
    79. static double sPT_Mach; // Mach-Wert PT-Kanal
    80. static double sPS_Mach; // Mach-Wert P2-Kanal
    81. #ifdef TEXTWND
    82. static HWND hWndPCM = 0;
    83. static const int PCM_TXT_X_OFFSET = 4;
    84. extern PCM_DLL_API int PCMDRV_openWindow(HWND *pHwnd);
    85. extern PCM_DLL_API int PCMDRV_closeWindow();
    86. #endif
    87. // These initialisation-commands will be sent to the MPS56-Bw upon the first access to the instrument
    88. // see procedure "PCMDRV_CheckInitPcm"
    89. static char *initPcm[] = { // Table/List of initialisation commands:
    90. "ALPR 2" // Change Display: ALtitude to Pressure
    91. , "UNPR 2" // Unit for Pressure: hectoPascal
    92. , "QCPT 2" // PT-Mode: Change QC display to PT
    93. , "SPPR 2" // pressure control instead of airspeed
    94. , "ULRD 1100" // set upper limit for slew rate (PT)
    95. , "ULRS 1100" // set upper limit for slew rate (PS)
    96. , "ULPT 2600" // set upper limit for PT
    97. , "ULPS 1400" // set upper limit for PS
    98. , "LLPT 30" // set lower limit for PT
    99. , "LLPS 30" // set lower limit for PS
    100. , "MNQC -16" // turn on "negative QC protection"
    101. , "MEAS" // set Measure mode
    102. , "" // empty string marks end of list
    103. };
    104. PCM_DLL_API int PCMDRVFetch (char *cDevName,
    105. short iSnapshot1,
    106. short iSnapshot2,
    107. double *dPressA_p)
    108. {
    109. int iRtn = OK;
    110. #ifndef TATS_DLL_DUMMY
    111. int iDevID = PCM_ID;
    112. char cReadHead[PCM_MPS56_READ_BFLEN];
    113. char cCmDBuf[PCM_MPS56_READ_BFLEN];
    114. char cmdResponse[PCM_MPS56_READ_BFLEN];
    115. char cTxtMach[15];
    116. int iLen = PCM_MPS56_READ_BFLEN;
    117. double dFactor;
    118. int i, iStrLen;
    119. double *dDevTabPressure;
    120. sprintf_s(cTxtTrace, sizeof(cTxtTrace) - 1, "Procedure starts; Device: %s", cDevName);
    121. TatsUTL_DispMsgS(TRCS_DRV, iDevID, __FILE__, __FUNCTION__, cTxtTrace, EC_MSG);
    122. if (NOT_OK == (iRtn = PCMDRV_CheckInitPcm()))
    123. {
    124. return iRtn;
    125. }
    126. // ATLAS-Geraetestatus merken
    127. TatsUTL_StoreDevState (iDevID, TATS_DEV_FETCH);
    128. // Überprüfe SW-Gerätename
    129. if (
    130. (strcmp (cDevName, PS101) != 0) &&
    131. (strcmp (cDevName, PT101) != 0)
    132. )
    133. {
    134. // Ungültiger Gerätename
    135. sprintf_s(cBufErrMsg, sizeof(cBufErrMsg) - 1,
    136. "Ungültiger Gerätename (Dev-Name: %s)", cDevName);
    137. PCM_Error(iDevID, __FILE__, __FUNCTION__, E_PCM_INVALID_DEV, EC_DEV, cBufErrMsg);
    138. iRtn = NOT_OK;
    139. goto end;
    140. }
    141. if (sMachUnit) { // nur bei PT-Read und nicht bei Snap-shots!!
    142. strcpy_s(cReadHead, sizeof(cReadHead) - 1, "LDMA?"); // Lese Airspeed in Units of MACH
    143. strcpy_s(cTxtMach, sizeof(cTxtMach)-1, " (MACH-MODE) "); // Für Trace Ausgabe
    144. dDevTabPressure = &sPT_Mach;
    145. }
    146. else {
    147. strcpy_s(cTxtMach, sizeof(cTxtMach) - 1, " "); // Für Trace Ausgabe
    148. // Bestimmung des Lesekommandos in Abhängikeit von
    149. // .) aktuellem Druckkanal über die SW-Namen (PS101/PT101)
    150. // .) möglichem SNAP-SHOT-WORD Modifier
    151. //
    152. if (strcmp(cDevName, PS101) == 0)
    153. {
    154. if (iSnapshot1) {
    155. strcpy(cReadHead, "PSW1?"); // Lese SNAP-SHOT-WORD-PS1
    156. dDevTabPressure = &sPS1_Snapshot;
    157. }
    158. else if (iSnapshot2) {
    159. strcpy(cReadHead, "PSW2?"); // Lese SNAP-SHOT-WORD-PS2
    160. dDevTabPressure = &sPS2_Snapshot;
    161. }
    162. else {
    163. strcpy(cReadHead, "LDPS?"); // Lese PS Kanalanzeige
    164. dDevTabPressure = &sPS_Channel;
    165. }
    166. }
    167. else // PT101
    168. {
    169. if (iSnapshot1) {
    170. strcpy(cReadHead, "PTW1?"); // Lese SNAP-SHOT-WORD-PS1
    171. dDevTabPressure = &sPT1_Snapshot;
    172. }
    173. else if (iSnapshot2) {
    174. strcpy(cReadHead, "PTW2?"); // Lese SNAP-SHOT-WORD-PS2
    175. dDevTabPressure = &sPT2_Snapshot;
    176. }
    177. else {
    178. strcpy(cReadHead, "LDPT?"); // Lese PS Kanalanzeige
    179. dDevTabPressure = &sPT_Channel;
    180. }
    181. }
    182. }
    183. int retry = 0;
    184. do
    185. {
    186. if (retry > 0) TatsUTL_Sleep(10);
    187. iStrLen = sizeof(cmdResponse) - 1;
    188. if ((iRtn = TatsBUS_QueryDevice(iDevID, cReadHead, cmdResponse,
    189. /* NR-Chars*/ &iStrLen, /* RepeatCnt */ 1, /* Delay */ 0)) == NOT_OK)
    190. {
    191. sprintf_s(cBufErrMsg, sizeof(cBufErrMsg) - 1,
    192. "Fehler bei TatsBUS_QueryDevice (cmd: %s)", cReadHead);
    193. PCM_Error(iDevID, __FILE__, __FUNCTION__, E_DEV_DRV_ERRMSG, EC_ERROR, cBufErrMsg);
    194. }
    195. if (cmdResponse[0] == '?' || cmdResponse[0] == 'E') {
    196. sprintf_s(cBufErrMsg, sizeof(cBufErrMsg) - 1,
    197. "Syntax Fehler PS/PT-Fetch (cmd: %s)", cReadHead);
    198. PCM_Error(iDevID, __FILE__, __FUNCTION__, E_DEV_DRV_ERRMSG, EC_ERROR, cBufErrMsg);
    199. }
    200. *dPressA_p = atof(cmdResponse + 5); // Konvertiere Ergebnis und melde zurück
    201. } while (*dPressA_p < 0.0 && retry++ < 200); // negativer Wert: SnapShot wert noch nicht lesbar
    202. if (retry >= 200) {
    203. PCM_Error(iDevID, __FILE__, __FUNCTION__, E_DEV_DRV_ERRMSG, EC_ERROR, "Timeout on reading SnapShot Value");
    204. }
    205. // Device Table
    206. SetPCMSendBufTxt(cReadHead);
    207. SetPCMReadBufTxt(cmdResponse);
    208. *dDevTabPressure = *dPressA_p; // Update Device Tabelle
    209. sprintf_s(cTxtTrace, sizeof(cTxtTrace) - 1, "Pressure Value %s %8.2f", cTxtMach, *dDevTabPressure);
    210. TatsUTL_DispMsgS(TRCS_DRV, iDevID, __FILE__, __FUNCTION__, cTxtTrace, EC_MSG);
    211. end:
    212. TatsUTL_DispMsgS (TRCS_DRV, iDevID, __FILE__, __FUNCTION__, "Procedure complete", EC_MSG);
    213. #endif // TATS_DLL_DUMMY
    214. return iRtn;
    215. } /* PCMDRVFetch() */

    VB.NET-Quellcode

    1. Public Class Driver
    2. #Region " Declaration "
    3. Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
    4. #End Region
    5. #Region " Globale Variable "
    6. Public ReadOnly Property saReturn() As ReturnFehler()
    7. Get
    8. Return msaReturn
    9. End Get
    10. End Property
    11. #End Region
    12. #Region " Modul Variable "
    13. Public Enum t_pcmType
    14. PCM_TYPE_UNDEF = 0
    15. PCM_TYPE_KOLLSMANNN
    16. PCM_TYPE_DMA_MPS56
    17. PCM_TYPE_UNKNOWN
    18. End Enum
    19. Private Device As NI4882.Device
    20. Private mbTestFlag As Boolean
    21. Private gDevice As Long
    22. Dim sDevName As String ' ATLAS SW-Name
    23. Private mbPCM_Init As Boolean ' Kontrollflag für die Initialisierung
    24. Private sInBuf As String
    25. Private sPRESS_A_PS As Double '= 917.77 ' PRESS-A Wert für PS-Kanal
    26. Private sPRESS_A_PT As Double '= 917.77 ' PRESS-A Wert für PT-Kanal
    27. Private sSLEW_RATE_PS As Integer ' SLEW-RATE Wert für PS-Kanal
    28. Private sSLEW_RATE_PT As Integer ' SLEW-RATE Wert für PT-Kanal
    29. Private sPSControlMode As Boolean ' Mode Indikator für PS-Kanal
    30. Private sPTControlMode As Boolean ' Mode Indikator für PT-Kanal
    31. Private sNeqQC As Short ' Negativer QC Schutz
    32. Private sMachUnit As Short ' PRESS-A Wert in [Mach] oder [MB]
    33. Private sPS_Channel As Double ' PS-Kanal Anzeige
    34. Private sPT_Channel As Double ' PT-Kanal Anzeige
    35. Private sPS1_Snapshot As Double ' Snapshot Wort 1 vom PS-Kanal
    36. Private sPS2_Snapshot As Double ' Snapshot Wort 2 vom PS-Kanal
    37. Private sPT1_Snapshot As Double ' Snapshot Wort 1 vom PT-Kanal
    38. Private sPT2_Snapshot As Double ' Snapshot Wort 2 vom PT-Kanal
    39. Private sPT_Mach As Double ' Mach-Wert PT-Kanal
    40. Private sPS_Mach As Double ' Mach-Wert P2-Kanal
    41. ' These initialisation-commands will be sent to the MPS56-Bw upon the first access to the instrument
    42. ' see procedure "PCMDRV_CheckInitPcm"
    43. Static Dim initPcm() As Char = {"ALPR 2", "UNPR 2", "QCPT 2", "SPPR 2", "ULRD 1100", "ULRS 1100", "ULPT 2600", "ULPS 1400", "LLPT 30", "LLPS 30", "MNQC -16", "MEAS", ""}
    44. ' Table/List of initialisation commands:
    45. ' "ALPR 2" ' Change Display: ALtitude to Pressure
    46. ' "UNPR 2" ' Unit for Pressure: hectoPascal
    47. ' "QCPT 2" ' PT-Mode: Change QC display to PT
    48. ' "SPPR 2" ' pressure control instead of airspeed
    49. ' "ULRD 1100" ' set upper limit for slew rate (PT)
    50. ' "ULRS 1100" ' set upper limit for slew rate (PS)
    51. ' "ULPT 2600" ' set upper limit for PT
    52. ' "ULPS 1400" ' set upper limit for PS
    53. ' "LLPT 30" ' set lower limit for PT
    54. ' "LLPS 30" ' set lower limit for PS
    55. ' "MNQC -16" ' turn on "negative QC protection"
    56. ' "MEAS" ' set Measure mode _
    57. ' "" ' empty string marks end of list
    58. Public Sub Fetch(ByRef sDevName, ByVal bSnapshot1 As Boolean, ByVal bSnapshot2 As Boolean, ByRef dPressA_p As Double)
    59. Dim iLen As Int16 = PCM_READ_LEN
    60. Dim dFactor As Double
    61. '@Dim iIndex As Int16
    62. Dim iLoopStartPS As Int16
    63. Dim iLoopStartPT As Int16
    64. Dim sReadHead As String
    65. Dim sCmDBuf As String ' Command-String for PCM / Ausgabe-String zum PCM
    66. Dim cmdResponse() As Char ' Command Keyword-String for PCM ; Char-Array
    67. Dim sTxtMach As String
    68. Dim dDevTabPressure As Double
    69. sTxtTrace = String.copy("Procedure starts; Device: " & sDevName)
    70. ' FehlerArray zurücksetzen
    71. ReDim msaReturn(0)
    72. ' Check SW-Device-Name
    73. If (String.Compare(sDevName, PS101) <> 0) And (String.Compare(sDevName, PT101) <> 0) Then
    74. AddFehler("invalid SW-Device-Name", "PCM_Driver - Fetch", FehlerCode.Abbruch)
    75. Exit Sub
    76. End If
    77. ' Initialisiere Puffer mit ASCII 0
    78. InitBuffer(sInBuf, PCM_READ_LEN)
    79. ' PCM-String in Array speichern
    80. ReadPCM(sInBuf, iLen)
    81. If sMachUnit Then 'nur bei PT-Read und nicht bei Snap-shots!!
    82. sReadHead = String.Copy("LDMA?") 'Lese Airspeed in Units of MACH
    83. sTxtMach = String.Copy(" (MACH-MODE) ") 'Für Trace Ausgabe
    84. dDevTabPressure = sPT_Mach
    85. Else
    86. sTxtMach = String.Copy(" ") 'Für Trace Ausgabe
    87. ' Bestimmung des Lesekommandos in Abhängikeit von aktuellem Druckkanal über die SW-Namen(PS101/PT101) und möglichem SNAP-SHOT-WORD Modifier
    88. If String.Compare(sDevName, PS101) = 0 Then
    89. If bSnapshot1 Then
    90. ' ATLAS SW-Name "PS101"
    91. sReadRate = String.Copy("PSW1?") 'Lese SNAP-SHOT-WORD-PS1
    92. dDevTabPressure = sPS1_Snapshot
    93. ElseIf bSnapshot2 Then
    94. ' ATLAS SW-Name "PS101"
    95. sReadRate = String.Copy("PSW2?") 'Lese SNAP-SHOT-WORD-PS2
    96. dDevTabPressure = sPS2_Snapshot
    97. Else
    98. ' ATLAS SW-Name "PS101"
    99. sReadRate = String.Copy("LDPS?") 'Lese PS Kanalanzeige
    100. dDevTabPressure = sPS_Channel
    101. End If
    102. Else 'PT101
    103. If bSnapshot1 Then
    104. ' ATLAS SW-Name "PT101"
    105. sReadRate = String.Copy("PTW1?") 'Lese SNAP-SHOT-WORD-PT1
    106. dDevTabPressure = sPT1_Snapshot
    107. ElseIf bSnapshot2 Then
    108. ' ATLAS SW-Name String.Copy("PT101")
    109. sReadRate = String.Copy("PTW2?") 'Lese SNAP-SHOT-WORD-PT2
    110. dDevTabPressure = sPT2_Snapshot
    111. Else
    112. ' ATLAS SW-Name "PT101"
    113. sReadRate = String.Copy("LDPT?") 'Lese PT Kanalanzeige
    114. dDevTabPressure = sPT_Channel
    115. End If
    116. End If
    117. End If
    118. Dim retry As Int16 = 0
    119. Do
    120. If retry > 0 Then
    121. Sleep(10)
    122. End If
    123. If (cmdResponse(0) = "?") OrElse (cmdResponse(0) = "E") Then ' MPS56 signals Error?
    124. AddFehler("Syntax Fehler PS/PT-Fetch", "PCM_Driver - Fetch", FehlerCode.Abbruch)
    125. Exit Sub
    126. End If
    127. If Not Double.TryParse((Strings.Mid(cmdResponse, 5)), dPressA_p) Then
    128. uiMode_Status = Convert.ToDouble((Strings.Mid(cmdResponse, 5)))
    129. Else
    130. Double.Parse((Strings.Mid(cmdResponse, 5)), dPressA_p)
    131. End If
    132. Loop Until ((dPressA_p = 0.0) And (retry + 1 = 200)) 'negativer Wert: SnapShot wert noch nicht lesbar
    133. If (retry >= 200) Then
    134. AddFehler("Timeout on reading SnapShot Value", "PCM_Driver - Fetch", FehlerCode.Abbruch)
    135. End If
    136. ' Device Table
    137. sTxtBuf = String.copy(sReadHead)
    138. dDevTabPressure = dPressA_p ' Update Device Tabelle
    139. sTxtTrace = String.copy("Pressure Value " & sTxtMach & " " & dDevTabPressure.toString(".00"))
    140. End Sub


    Wie importiere ich nun die

    C-Quellcode

    1. #include "stdafx.h"
    2. #include "cem.h"
    3. #include "key.h"
    4. #include "wcem_main.h"
    5. #include "common.h"
    6. #include "error.h"
    7. #include "tats_util.h"
    8. #include "basicdrv.h"
    9. #include "TraceDefs.h"
    10. #include "pcmdrv.h"
    11. #include "pcm.h"

    in das VB.net-Pondon? Der ganze Gerätetreiber (c) liegt als dll schon vor (siehe Bild), und ich wollte diese DLL in das bisherige Gerätetreiber-Projekt importieren.
    Über euer Feedback und Tips würde ich mich echt freuen. ^^

    Ausgelagert aus c++ dll in VB.net einbinden. Spoiler-Tags um langen Code eingefügt. ~Thunderbolt
    Bilder
    • Unbenannt.JPG

      168,72 kB, 1.647×795, 63 mal angesehen

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Thunderbolt“ ()

    So viel ich weiß können Treiber nicht mit .NET geschrieben werden. Wäre es kein Treiber, könntest du aus C++ die Funktionen die du in VB brauchst exportieren und in VB mittels DllImport PInvoken. Dadurch das es ein Treiber ist, wirst du um eine Kommunikationsschnittstelle nicht herum kommen.
    Eignen würde sich dafür vielleicht DeviceIoControl. Zu gut kenne ich mich aber auch nicht aus also vielleicht hat jemand anderes noch eine besser Idee/Lösung.
    @seh
    anbei mal die bisherige Version des Gerätetreibers für das alte Steuergerät. Hier wird anscheinend über die einzelnen Bits mit der Peripherie direkt kommuniziert. Das neue Steuergerät tut dies aber nicht.
    Kannst du das mit der Kommunikationsschnittstelle erläutern? DeviceIoControl habe ich gegooglet und scheint doch nur für c++ zu sein. Mir erschlißt sich nicht, wie ich dies in Vb.net einbinden soll.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Driver
    2. #Region " Declaration "
    3. Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
    4. #End Region
    5. #Region " Globale Variable "
    6. Public ReadOnly Property saReturn() As ReturnFehler()
    7. Get
    8. Return msaReturn
    9. End Get
    10. End Property
    11. #End Region
    12. #Region " Modul Variable "
    13. Private Device As NI4882.Device
    14. Private mbTestFlag As Boolean
    15. Private gDevice As Long
    16. Private mbPCM_Init As Boolean ' Kontrollflag für die Initialisierung
    17. Private sInBuf As String
    18. Private sPRESS_A_PS As Double '= 917.77 ' PRESS-A Wert für PS-Kanal
    19. Private sPRESS_A_PT As Double '= 917.77 ' PRESS-A Wert für PT-Kanal
    20. Private sSLEW_RATE As Integer ' SLEW-RATE Wert
    21. Private sSLEW_RATE_PS As Integer ' SLEW-RATE Wert für PS-Kanal
    22. Private sSLEW_RATE_PT As Integer ' SLEW-RATE Wert für PT-Kanal
    23. Private sPSControlMode As Boolean ' Mode Indikator für PS-Kanal
    24. Private sPTControlMode As Boolean ' Mode Indikator für PT-Kanal
    25. Private sNeqQC As Short ' Negativer QC Schutz
    26. Private sMachUnit As Short ' PRESS-A Wert in [Mach] oder [MB]
    27. Private sPS_Channel As Double ' PS-Kanal Anzeige
    28. Private sPT_Channel As Double ' PT-Kanal Anzeige
    29. Private sPS1_Snapshot As Double ' Snapshot Wort 1 vom PS-Kanal
    30. Private sPS2_Snapshot As Double ' Snapshot Wort 2 vom PS-Kanal
    31. Private sPT1_Snapshot As Double ' Snapshot Wort 1 vom PT-Kanal
    32. Private sPT2_Snapshot As Double ' Snapshot Wort 2 vom PT-Kanal
    33. Public Structure ReturnFehler
    34. Dim Code As Int16
    35. Dim Fehler() As String
    36. Friend Sub Initialize()
    37. ReDim Fehler(1)
    38. End Sub
    39. End Structure
    40. Private msaReturn() As ReturnFehler
    41. Private Enum FehlerCode
    42. Weiter = 1
    43. Abbruch
    44. End Enum
    45. #End Region
    46. #Region " Modul Konstante "
    47. Const bGPIB As Boolean = True ' Auswahl zwischen GPIB-Befehle und NI4882-Befehle
    48. ' Mit den NI4882-Befehlen tritt beim <.ReadByteArray>
    49. ' sporatisch ein Fehler auf
    50. Const PCM_RESET_LEN As Int16 = 23 ' Anzahl der Ausgabebytes bei RESET
    51. Const PCM_SETUP_LEN As Int16 = 23 ' Anzahl der Ausgabebytes bei SETUP
    52. Const PCM_READ_LEN As Int16 = 71 ' Anzahl der Eingabebytes bei READ/SNAPSHOT
    53. Const PCM_SFT_LEN As Int16 = 23 ' Anzahl der Ausgabebytes für den Selbsttest
    54. Const PCM_CHECK_LEN As Int16 = 71 ' Anzahl der Eingabebytes für Checks
    55. Const MAX_NEGQ_LEN As Int16 = 4 ' Stringlänge des NEG-QC-PROTECTION Modifiers
    56. Const SLEEP_LEN As Int16 = 1250 ' 1250 ms Wartezeit:
    57. ' Experimentell ermittelter Wert
    58. Const PS101 As String = "PS101" ' ATLAS SW-Name für PCM, PS-Kanal
    59. Const PT101 As String = "PT101" ' ATLAS SW-Name für PCM, PT-Kanal
    60. Const WAIT_FOR_PS_READY As Int16 = 0 ' Überprüfe, ob programmierter Druckwert
    61. ' im PS-Kanal erreicht ist
    62. Const WAIT_FOR_PT_READY As Int16 = 1 ' Überprüfe, ob programmierter Druckwert
    63. ' im PT-Kanal erreicht ist
    64. Const PS_TRACK_LOSS As Int16 = 2 ' Überprüfe, ob beim PS-Kanal ein Leck
    65. ' aufgetreten ist
    66. Const PT_TRACK_LOSS As Int16 = 3 ' Überprüfe, ob beim PT-Kanal ein Leck
    67. ' aufgetreten ist
    68. Const DBL_MAX As Double = 1.7976931348623157E+308 ' max value
    69. Const EPSILON As Double = 0.000000000000001 ' E-15 für Vergleich zweier double-Werte
    70. #End Region
    71. #Region " Globale Methoden "
    72. ' Anlegen eines neuen Deviceobjektes
    73. Public Sub New(ByVal Board As Integer, ByVal primAddress As Integer, _
    74. ByVal timeOut As TimeoutValue, ByVal TestFlag As Boolean)
    75. ' FehlerArray zurücksetzen
    76. ReDim msaReturn(0)
    77. mbTestFlag = TestFlag
    78. Try 'Zurücksetzen des Gerätes, da das Gerät bei zuvor unerwartetem Abbruch nicht korrekt angesprochen werden kann.
    79. If mbTestFlag Then
    80. If bGPIB Then
    81. ibdev(Board, primAddress, 0, 13, 1, 0, gDevice)
    82. Sleep(100)
    83. Else
    84. Device = New NI4882.Device(Board, primAddress)
    85. Device.IOTimeout() = timeOut
    86. Device.Clear()
    87. 'Device.Reset()
    88. End If
    89. End If
    90. Catch ex As InvalidOperationException
    91. Catch ex As InvalidOperationException
    92. AddFehler(ex.Message, "PCM_Driver - New", FehlerCode.Abbruch)
    93. End Try
    94. End Sub
    95. ' Eingangsdaten vom PCM lesen und berechnet hieraus
    96. ' die Messwerte
    97. Public Sub Fetch(ByVal bSnapshot1 As Boolean, ByVal bSnapshot2 As Boolean, _
    98. ByRef dPressPS As Double, ByRef dPressPT As Double)
    99. Dim iLen = PCM_READ_LEN
    100. Dim dFactor As Double
    101. '@Dim iIndex As Int16
    102. Dim iLoopStartPS As Int16
    103. Dim iLoopStartPT As Int16
    104. ' FehlerArray zurücksetzen
    105. ReDim msaReturn(0)
    106. '' Vor jedem neuen Read ein Init auslösen
    107. Init()
    108. ' Vor dem Read ein Setup
    109. If sPRESS_A_PS > 0 Then
    110. Setup(sPRESS_A_PS, sPRESS_A_PT, 0.003)
    111. End If
    112. 'Sleep(10000)
    113. Sleep(2000)
    114. ' Initialisiere Puffer mit ASCII 0
    115. InitBuffer(sInBuf, PCM_READ_LEN)
    116. ' PCM-String in Array speichern
    117. ReadPCM(sInBuf, iLen)
    118. If iLen <> PCM_READ_LEN Then
    119. AddFehler("Fehler beim Lesen, Länge falsch", "PCM_Driver - Fetch", FehlerCode.Abbruch)
    120. Exit Sub
    121. End If
    122. dPressPS = 0 ' Initialisiere mit 0
    123. dPressPT = 0 ' Initialisiere mit 0
    124. If sMachUnit Then
    125. dFactor = 10 ' Multiplikationsfaktor der höherwertigsten Ziffer
    126. ' für Einheit [Mach]
    127. Else
    128. dFactor = 1000 ' Multiplikationsfaktor der höherwertigsten Ziffer
    129. ' für Einheit [MB]
    130. End If
    131. ' Bestimmung der Leseposition im Empfangspuffer in Abhängikeit von
    132. ' aktuellem Druckkanal über die SW-Namen (PS101/PT101)
    133. ' möglichem SNAP-SHOT-WORD Modifier
    134. '
    135. If bSnapshot1 Then
    136. iLoopStartPS = 43 ' Lese SNAP-SHOT-WORD-PS1
    137. ElseIf bSnapshot2 Then
    138. iLoopStartPS = 50 ' Lese SNAP-SHOT-WORD-PS2
    139. Else
    140. iLoopStartPS = 23 ' Lese PS Kanalanzeige
    141. 'iLoopStart = 0 ' Lese PS Kanalanzeige
    142. End If
    143. If bSnapshot1 Then
    144. iLoopStartPT = 57 ' Lese SNAP-SHOT-WORD-PT1
    145. ElseIf bSnapshot2 Then
    146. iLoopStartPT = 64 ' Lese SNAP-SHOT-WORD-PT2
    147. Else
    148. iLoopStartPT = 30 ' Lese PT Kanalanzeige
    149. 'iLoopStart = 8 ' Lese PT Kanalanzeige
    150. End If
    151. ' Berechne den Messwert
    152. 'For iIndex = iLoopStart To iLoopStart + 6
    153. ' dPressA += ((Val(sInBuf.Substring(iIndex, 1)) - 48) * dFactor) ' ASCII beachten !
    154. ' dFactor /= 10
    155. 'Next
    156. ' Alternativ
    157. dPressPS = Val(sInBuf.Substring(iLoopStartPS, 6)) * dFactor
    158. dPressPT = Val(sInBuf.Substring(iLoopStartPT, 6)) * dFactor
    159. ' Update Device Tabelle
    160. ' Für PS-Kanal
    161. Select Case iLoopStartPS
    162. Case 0
    163. sPS_Channel = dPressPS
    164. 'Case 8
    165. ' sPT_Channel = dPressPT
    166. Case 23
    167. sPS_Channel = dPressPS
    168. 'Case 30
    169. ' sPT_Channel = dPressPT
    170. Case 43
    171. sPS1_Snapshot = dPressPS
    172. Case 50
    173. sPS2_Snapshot = dPressPS
    174. 'Case 57
    175. ' sPT1_Snapshot = dPressPT
    176. 'Case 64
    177. ' sPT2_Snapshot = dPressPT
    178. Case Else
    179. End Select
    180. ' Für PT-Kanal
    181. Select Case iLoopStartPT
    182. 'Case 0
    183. ' sPS_Channel = dPressPS
    184. Case 8
    185. sPT_Channel = dPressPT
    186. 'Case 23
    187. ' sPS_Channel = dPressPS
    188. Case 30
    189. sPT_Channel = dPressPT
    190. 'Case 43
    191. ' sPS1_Snapshot = dPressPS
    192. 'Case 50
    193. ' sPS2_Snapshot = dPressPS
    194. Case 57
    195. sPT1_Snapshot = dPressPT
    196. Case 64
    197. sPT2_Snapshot = dPressPT
    198. Case Else
    199. End Select
    200. If sPRESS_A_PS = 0 Then
    201. sPRESS_A_PS = dPressPS / 100000.0 ' mBar
    202. End If
    203. dPressPS /= 100000.0 ' mBar
    204. dPressPT /= 100000.0 ' mBar
    205. End Sub
    206. ' Ausgangsdaten für ein FETCH zum PCM senden
    207. Public Sub Init()
    208. Dim sOutBuf As String ' Ausgabe-String zum PCM
    209. ' FehlerArray zurücksetzen
    210. ReDim msaReturn(0)
    211. mbPCM_Init = True
    212. ' Initialisiere Puffer mit ASCII 0
    213. InitBuffer(sOutBuf, PCM_SETUP_LEN)
    214. ' Für PS-Kanal
    215. AddIntegerIntoASCIIString(sPRESS_A_PS * 100, sOutBuf, 0)
    216. ' Für PT-Kanal
    217. AddIntegerIntoASCIIString(sPRESS_A_PT * 100, sOutBuf, 7)
    218. ' Bei Init wird der Monitor-Mode fest eingestellt
    219. 'sPSControlMode = False ' PS in Monitor Mode
    220. 'sPTControlMode = False ' PT in Monitor Mode
    221. ' Monitor-Mode PS-Kanal
    222. sOutBuf = sOutBuf.Remove(20, 1)
    223. sOutBuf = sOutBuf.Insert(20, Chr(&H42))
    224. ' Monitor-Mode PT-Kanal
    225. sOutBuf = sOutBuf.Remove(21, 1)
    226. sOutBuf = sOutBuf.Insert(21, Chr(&H43))
    227. If sNeqQC = 0 Then
    228. sOutBuf = sOutBuf.Remove(22, 1)
    229. sOutBuf = sOutBuf.Insert(22, Chr(&H30))
    230. Else
    231. sOutBuf = sOutBuf.Remove(22, 1)
    232. sOutBuf = sOutBuf.Insert(22, Chr(&H31))
    233. End If
    234. Try
    235. If mbTestFlag Then
    236. If bGPIB Then
    237. ibonl(gDevice, 1)
    238. Sleep(500)
    239. ibwrt(gDevice, sOutBuf)
    240. Else
    241. Device.Reset()
    242. Sleep(500)
    243. Device.Write(sOutBuf)
    244. End If
    245. End If
    246. Catch ex As System.InvalidOperationException
    247. AddFehler(ex.Message, "PCM_Driver - Init", FehlerCode.Abbruch)
    248. End Try
    249. End Sub
    @Angemon84 Meinst Du einen Wrapper in VB.NET für den vorhandenen Treiber?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany
    das mit dem Wrapper kannte ich noch gar nicht. Ich habe mich hier eingelesen. Ich kenne mich mit der hardwarenahen Programmierung in VB.net auch nicht aus, sondern nur in C.
    Welches Vorgehen würdet ihr hier empfehlen?
    Ich würde folgendes andenken:
    1) die pcm_mps56_dll (inkl. aller Header-Files) versuchen komplett zu extrahieren [siehe Bild aus dem ersten Post].
    2) Einfügen /
    DllImport
    in das bestehende VB.net -Projekt.
    3) Umschreiben des bestehenden Gerätetereiber auf das neue Gerät äquivalent zum entsprechenden C-Gerätetreiber
    4) Ist ein Benutzen desWrappers notwendig um die c-Funktionen der Header-Files anzusprechen, oder ist der Funktionsaufruf mit den richtigen Übergabeparametern ausreichend?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!