I am writing a VB.Net (VS 2015) application to control equipment in real time which is connected via USB ports. The equipment requires that text string, terminated by a chr(13) be sent. Most commands will get a response back. For example one command (set VALVE1 ON) will open a valve one on the equipment. When plugging the equipment in it appears as COM7 on my laptop, though I can change this via device manager, and have done so to ensure I don't get the problem just on COM7. the euipment then sends back a string to confirm valve has opened. A light also displays to show valve has opened.

When running my code the valve opens and about seven seconds later the coms port closes and the equipment locks up. If I use Hyperterminal or Docklight to send the string, then valve opens and string comes back.

I started using Framework 4.5 and the valve would not open. I now use Framework 4.6.1 and get the results described.

If I connect to another computer running Hyperterminal or Docklight then the sent string is displayed correctly and strings can be sent back to my application.

 Sub SendSerialData(ByVal data As String)
        ' Send strings to a serial port.

        Dim _continue As Boolean
        Dim s As String
        Dim sl As Integer
        Dim rct As Integer
        Dim CC As Integer
        Dim incoming As String

        Dim J As Integer
        J = 0
        Dim jl As Integer
        Dim bytes() As Byte

        ' Dim ascii As New ASCIIEncoding()

        ' Create two different encodings.
        Dim ascii As Encoding = Encoding.UTF8

        Dim unicode As Encoding = Encoding.Unicode

        ' Convert the string into a byte array.
        Dim unicodeBytes As Byte() = unicode.GetBytes(data)



        ' Perform the conversion from one encoding to the other.
        Dim asciiBytes As Byte() = Encoding.Convert(unicode, ascii, unicodeBytes)

        ' Convert the new byte array into a char array and then into a string.
        Dim asciiChars(ascii.GetCharCount(asciiBytes, 0, asciiBytes.Length) - 1) As Char
        ascii.GetChars(asciiBytes, 0, asciiBytes.Length, asciiChars, 0)
        Dim asciiString As New String(asciiChars)

        Dim indata As String

        ' Send strings to a serial port.
         ' sending one bit at a time. Have also tried whole line at a time.

        Using com1 As IO.Ports.SerialPort = My.Computer.Ports.OpenSerialPort("COM7", 115200, Parity.None, 8, StopBits.One)

            com1.NewLine = Chr(13)
            jl = Len(data)
            Dim b As Byte

            For J = 0 To Len(asciiChars) - 1
                com1.Write(asciiChars(J))
            Next j

            MsgBox(com1.IsOpen)

            _continue = True

            s = ""
            sl = 0
            rct = 0
            '   
            While _continue
                CC = 0
                Try
                    While com1.BytesToRead = 0 And CC < 2000
                        CC = CC + 1
                        J = com1.BytesToRead
                    End While
                Catch ex As Exception
                    _continue = False
                End Try

               incoming = com1.ReadExisting

                rct = rct + 1
                If rct > 100 Then _continue = False

                s = s & incoming


                If Len(s) >= 1 Or rct > 1000 Then
                    _continue = False
                    sl = Len(s)

                Else

                    '    MsgBox(Len(s) & "  -" & s)
                End If
            End While
        End Using

        MsgBox(rct & " - " & s & "  Length " & sl)

    End Sub

So has anyone had this problem and found a solution please ? I suspect it is something to do with Framework, because one version would not work and current one partially works. So far no strings returned.

Alternatively can any one point me to sending strings to USB without using Framework please ?

Dani AI

Generated

A few practical points and a short checklist to try before assuming a framework bug.

The symptoms you describe (command accepted, then ~7s later the COM closes and the device "locks") are commonly caused by control-line or I/O-pattern differences between your app and a terminal program. HyperTerminal/Docklight may be leaving DTR/RTS, handshake or newline behavior set differently than your code. Your current routine also polls BytesToRead in a tight loop and opens/closes the port per send, both of which can hide timing/control issues. was right to suggest a serial sniffer — seeing the actual line toggles will often point straight to DTR/RTS resets or an unexpected close.

Quick checklist

  • Match exactly the port settings shown in Docklight/HyperTerminal (baud, parity, stop bits, handshake, DTR/RTS). Try toggling DtrEnable/RtsEnable in code to match the terminal.
  • Send the exact bytes the device expects (use ASCII or explicit bytes and include the CR). Avoid the Unicode/Convert dance.
  • Open the SerialPort once and reuse it instead of opening/disposing every command; opening or closing can toggle control lines on some USB-serial chips.
  • Avoid busy-wait loops; use ReadLine/ReadTimeout or the DataReceived event and set ReceivedBytesThreshold.
  • Add logging and catch exceptions around Read/Write so you can see if a SerialException or timeout coincides with the lock.

Minimal VB.NET pattern to try (open once, ASCII, send CR-terminated line, read with timeout):

Using sp As New IO.Ports.SerialPort("COM7", 115200, IO.Ports.Parity.None, 8, IO.Ports.StopBits.One)
    sp.Handshake = IO.Ports.Handshake.None
    sp.Encoding = System.Text.Encoding.ASCII
    sp.DtrEnable = False   ' try True if terminal uses it
    sp.RtsEnable = False
    sp.NewLine = vbCr
    sp.ReadTimeout = 3000
    sp.Open()
    sp.DiscardInBuffer()
    sp.WriteLine("SET VALVE1 ON")
    Try
        Dim reply As String = sp.ReadLine()
        ' process reply
    Catch ex As TimeoutException
        ' handle no-reply case
    End Try
End Using

If that still locks the device: (a) run a hardware or software port monitor to capture control-line changes, (b) try updating the USB-serial driver (FTDI/Prolific/etc.), and (c) keep a terminal open after your app to see whether the device recovers or stays locked. These steps usually reveal whether the problem is driver/control-line related rather than a .NET encoding bug.

Recommended Answers

All 3 Replies

Sorry for the delay. But let's tackle a few items.

To do this without .NET you'll have to use a language other than VB.net, C# and so on. But I don't see any reason to avoid .NET here.

-> Now to work. There are so many code examples on the web for serial IO in VB.net that I suggest you try a terminal program from source to see how that works.

What I think I see is an old school polling the serial port method. You may have to up your game here to have a routine that fires on serial reception and be careful not to send data and have no delay for the response.

Example that I find doesn't work in psuedo code.
1. Open port.
2. Send string.
3. Wait for answer.

What's wrong with that? Not much. But we are dealing with the real world and I've been burned by drivers and devices that take one hundred milliseconds for the port to get ready. I can't write what your choice would be here but for many years I'll open the port early then the user can click on this or that button. The human's delay has always been long enough to avoid that old issue.

BTW, my other nice trick is to scan the ports for a connection so the user never has to tell me which COM port to use. I find that end users today are very unaware of old school serial ports.

Hello,

Thank you for your suggestions.

I have tried much of what you have suggested, so I apologose for having said so.

I have tried various opening and sending strings, including having a message box between opening the port and sending the string, for the reasons you say.

I also have a routine for scanning and finding the ports, but for testing this bit I know what the com port numbber is..

Have you sucessfully used Framework 4.5 and/or 4.6 to communicate with a port ?

Since posting I have downloaded a port monitor which appears to show my program continuing to send data. I am investigating further. I have also heard indirectly from the board makers who say I can't lock the board from VB.....

Well, no. My apps on on .NET 3.5 for long reasons. They were fielded back in 2009 and I leave them be for reasons.

One of the test tools I used along the way was a serial sniffer. This can be a hardware box ($$$$) or cheap cables wired up to listen on TX or RX on a second PC. That way we see what's on the wire.

I have fielded serial port comms for well, since DOS days. The code above is pretty rudimentary but what is this about lock up? If you exit your app and open a terminal, is it still locked up?

Also, if you are in the USA or Can, drop me a direct line about the app you need.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.