Serial-Port ansteuerung

  • VB.NET

Es gibt 12 Antworten in diesem Thema. Der letzte Beitrag () ist von Eierlein.

    Serial-Port ansteuerung

    Hallo,

    ich möchte bei der seriellen Schnittstelle unter VB 2012 die Leitungen TxD, DTR und RTS einzeln (und unabhängig voneinander) auf high bzw. low setzen.

    Problem: TxD lässt sich wunderbar über SerialPort1.BreakState = True setzen. Setze ich nun aber SerialPort1.RtsEnable = True fällt TxD wieder auf low (gleiches bei DTR)
    Ich kann zwar TxD im Anschluss gleich wieder auf "True" setzen, dieses "gepulste" TxD stört allerings das Endgerät.

    Wenn ich auf einen anderen Basic-Dialekt verlinken darf: freebasic-portal.de/code-beisp…en-comport-winapi-78.html
    Hier funktioniert dies problemlos, nur würde ich ein grafisches Setup und die Möglichkeit der Weiterverarbeitung der Daten in VB vorziehen.

    Handshake ist nicht aktiviert. Auch das Thema "Bitwackeln" über die Suche habe ich schon, soweit mir als VB-Neuling nachvollziehbar, durch.

    Grüße, Börny
    Hallo fraju,

    richtig, ich benutze zwei COM-Ports welche über USB-Adapter (FTDI-Chipsatz) angeschlossen sind. Dies müsste dann aber ein Problem der Ansteuerung unter VB sein, da beide Ports unter FreeBasic einwandfrei arbeiten. Echte Com-Ports werden bei PCs oder Notebooks anscheinend nicht mehr benötigt, sind nur noch selten anzutreffen.
    Kann ich dieses Ansteuerungs-Problem evtl. umgehen? Ich habe öfters was von "MSCOMM32.OCX" und diversen DLLs gelesen, jedoch wird hier nur das Senden und Empfangen von Zeichenketten beschrieben. Ich muss jedoch nur bestimmte Pins der Schnittstelle auf high/low schalten und bekomme auf einem Pin eine Bitfolge zur Auswertung zurück.

    Danke, Börny
    Für die direkte Ansteurung musst du, wie bei FreeBasic, über API-Aufrufe gehen.
    (Wie die API Deklaration in Vb.net funktioniert und wie du an den COM-Handle kommst, musst du selber rausfinden).

    Quellcode

    1. 'Deklaration für VB(6,A)
    2. 'FÜR VB.NET Long durch Integer ersetzen!
    3. Declare Function EscapeCommFunction Lib "kernel32.dll" ( _
    4. ByVal nCid As Long, _
    5. ByVal nFunc As Long) As Long
    6. nCid --> Handle des COMPorts
    7. Werte für nFunc:
    8. Entweder als Konstanten deklarieren oder die Zahlen verwenden
    9. SETDTR ----> 5
    10. CLRDTR ----> 6
    11. SETRTS ----> 3
    12. CLRRTS ----> 4
    13. SETBREAK --> 8
    14. CLRBREAK --> 9
    @Boerny:: Kannst Du dieses Kabel einfach abklemmen und im Stecker direkt auf High oder Low legen?
    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!
    @Eierlein

    das habe ich auch schon gefunden, leider ist das hier msdn.microsoft.com/de-de/library/bb979092.aspx#ID0EVD nicht gerade verständlich für Einsteiger (zumindest für mich) geschrieben. Und wieder wird mit Zeichenketten hin und her geschickt, das kann ich leider nicht umsetzen.

    @Rod

    naja, können täte ich schon, dann wäre aber das hier alles sinnfrei. TxD ist für die Stromversorgung der angeschlossenen Schaltung zuständig und sollte durch die Software schaltbar sein.

    Börny

    Boerny schrieb:

    und sollte durch die Software schaltbar sein.
    Dann aber nicht über ein Signalkabel!
    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!
    Hier ein compilierbares Consolen-Programm zum testen:

    VB.NET-Quellcode

    1. Imports System
    2. Imports System.Runtime.InteropServices
    3. '-------------------------------------------------------------------------
    4. Module Module1
    5. <DllImport("kernel32.dll")> Function _
    6. EscapeCommFunction( _
    7. ByVal nCid As Integer, _
    8. ByVal nFunc As Integer) As Integer
    9. End Function
    10. <DllImport("kernel32.dll")> Function _
    11. EscapeCommFunction(ByVal hFile As Integer, ByVal ifunc As Long) As Boolean
    12. End Function
    13. <DllImport("kernel32.dll")> Function _
    14. CreateFile(<MarshalAs(UnmanagedType.LPStr)> ByVal lpFileName As String, _
    15. ByVal dwDesiredAccess As Integer, ByVal dwShareMode As Integer, _
    16. ByVal lpSecurityAttributes As Integer, ByVal dwCreationDisposition As Integer, _
    17. ByVal dwFlagsAndAttributes As Integer, ByVal hTemplateFile As Integer) As Integer
    18. End Function
    19. <DllImport("kernel32.dll")> Function _
    20. CloseHandle(ByVal hObject As Integer) As Integer
    21. End Function
    22. Sub Main()
    23. Dim hComm1 As Integer, hComm4 As Integer
    24. hComm1 = OpenCom("Com1")
    25. hComm4 = OpenCom("Com4")
    26. TXT_An(hComm4)
    27. Console.WriteLine("Enter drücken") : Console.ReadLine()
    28. DTR_An(hComm4)
    29. Console.WriteLine("Enter drücken") : Console.ReadLine()
    30. RTS_An(hComm4)
    31. Console.WriteLine("Enter drücken") : Console.ReadLine()
    32. DTR_Aus(hComm4)
    33. Console.WriteLine("Enter drücken") : Console.ReadLine()
    34. RTS_Aus(hComm4)
    35. Console.WriteLine("Enter drücken") : Console.ReadLine()
    36. DTR_An(hComm4)
    37. Console.WriteLine("Enter drücken") : Console.ReadLine()
    38. TXT_Aus(hComm4)
    39. Console.WriteLine("Enter drücken") : Console.ReadLine()
    40. CloseCom(hComm1)
    41. CloseCom(hComm4)
    42. End Sub
    43. Sub DTR_An(ByVal nCid As Integer)
    44. EscapeCommFunction(nCid, 5)
    45. End Sub
    46. Sub RTS_An(ByVal nCid As Integer)
    47. EscapeCommFunction(nCid, 3)
    48. End Sub
    49. Sub TXT_An(ByVal nCid As Integer)
    50. EscapeCommFunction(nCid, 8)
    51. End Sub
    52. Sub DTR_Aus(ByVal nCid As Integer)
    53. EscapeCommFunction(nCid, 6)
    54. End Sub
    55. Sub RTS_Aus(ByVal nCid As Integer)
    56. EscapeCommFunction(nCid, 4)
    57. End Sub
    58. Sub TXT_Aus(ByVal nCid As Integer)
    59. EscapeCommFunction(nCid, 9)
    60. End Sub
    61. Function tt()
    62. End Function
    63. Sub CloseCom(ByVal nCid As Integer)
    64. CloseHandle(nCid)
    65. End Sub
    66. Function OpenCom(ByVal ComNr As String) As Integer
    67. Dim nCid As Integer
    68. nCid = CreateFile(ComNr, _
    69. &H80000000 Or &H40000000, 0, 0, _
    70. 3, 0, 0)
    71. If nCid <> -1 Then
    72. OpenCom = nCid
    73. Else
    74. OpenCom = 0
    75. End If
    76. End Function
    77. End Module
    Ich möchte euch nicht von eurem Weg abbringen, möchte aber dies noch schreiben.
    Dies kommt bei einigen USB to Serial Adaptern vor, in Verbindung mit VB.net.

    Hatte dieses Problem vor Jahren auch, bis ich verschiedene USB to232 Wandler testete.
    Könnte sein das dies hier sogar im Forum steht.
    Gruß
    @ Eierlein,

    habe den Code in eine Windows-Anwendung übernommen und drei Check-Buttons hinzugefügt. Dankeschön, das klappt so nun einwandfrei mit der getrennten Ansteuerung der drei Ausgänge (zumindest auf einer Testplatine am Com-USB-Adapter)
    Jetzt wahrscheinlich eine dämliche Frage: Könnte man darüber auch Eingangsleitungen abfragen oder muss das über den VB-Internen Serialport gemacht werden?

    Frohes neues Jahr,
    Börny
    Könnte man darüber auch Eingangsleitungen abfragen


    Kann man. (Konnte ich allerdings noch nicht testen).


    Statt GetCommModemStatus hatte ich EscapeCommFunction 2-mal deklariert.
    Hier noch mal alle benötigten Deklarationen:

    VB.NET-Quellcode

    1. <DllImport("kernel32.dll")> Function _
    2. EscapeCommFunction( _
    3. ByVal nCid As Integer, _
    4. ByVal nFunc As Integer) As Integer
    5. End Function
    6. <DllImport("kernel32.dll")> Function _
    7. GetCommModemStatus( _
    8. ByVal hFile As Integer, _
    9. ByVal lpModemStat As Integer) As Integer
    10. End Function
    11. <DllImport("kernel32.dll")> Function _
    12. CreateFile(<MarshalAs(UnmanagedType.LPStr)> ByVal lpFileName As String, _
    13. ByVal dwDesiredAccess As Integer, ByVal dwShareMode As Integer, _
    14. ByVal lpSecurityAttributes As Integer, ByVal dwCreationDisposition As Integer, _
    15. ByVal dwFlagsAndAttributes As Integer, ByVal hTemplateFile As Integer) As Integer
    16. End Function
    17. <DllImport("kernel32.dll")> Function _
    18. CloseHandle(ByVal hObject As Integer) As Integer
    19. End Function

    ------------------------------------

    'Beispiel um den CTS Status abzufragen

    VB.NET-Quellcode

    1. CTSStatus = CTS(hCOMMx)


    ------------------------------------

    VB.NET-Quellcode

    1. Function CTS(ByVal nCid As Integer) As Integer
    2. Dim status As Integer
    3. GetCommModemStatus(nCid, status)
    4. If (status And &H10%) = &H10% Then CTS = 1 Else CTS = 0
    5. End Function
    6. Function DSR(ByVal nCid As Integer) As Integer
    7. Dim status As Integer
    8. GetCommModemStatus(nCid, status)
    9. If (status And &H10%) = &H10% Then DSR = 1 Else DSR = 0
    10. End Function
    11. Function RI(ByVal nCid As Integer) As Integer
    12. Dim status As Integer
    13. GetCommModemStatus(nCid, status)
    14. If (status And &H40%) = &H40% Then RI = 1 Else RI = 0
    15. End Function
    16. Function DCD(ByVal nCid As Integer) As Integer
    17. Dim status As Integer
    18. GetCommModemStatus(nCid, status)
    19. If (status And &H80%) = &H80% Then DCD = 1 Else DCD = 0
    20. End Function


    Falls du lieber die Konstanten verwenden willst, hier die Werte:

    Konstanten für EscapeCommFunction:

    Quellcode

    1. SETXOFF = 1 ' Simulate XOFF received
    2. SETXON = 2 ' Simulate XON received
    3. SETRTS = 3 ' Set RTS high
    4. CLRRTS = 4 ' Set RTS low
    5. SETDTR = 5 ' Set DTR high
    6. CLRDTR = 6 ' Set DTR low
    7. RESETDEV = 7 ' Reset device if possible
    8. SETBREAK = 8 ' Set the device break line.
    9. CLRBREAK = 9 ' Clear the device break line.

    Konstanten für GetCommModemStatus:

    Quellcode

    1. MS_CTS_ON = &H10%
    2. MS_DSR_ON = &H20%
    3. MS_RING_ON = &H40%
    4. MS_RLSD_ON = &H80% 'DCD


    Müssen dann mit CONST deklariert werden