Results 1 to 15 of 15

Thread: Serial Port

  1. #1

    Thread Starter
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,754

    Serial Port

    If you have a question about this please post the question here
    http://www.vbforums.com/forumdisplay.php?f=25 not in this tread. Thanks!

    Much of the difficulty I see here, and in other forums, surrounding the use of Windows serial port is centered around an assumption.

    That assumption is that the serial port receives data in chunks that are conveniently packaged in the format we want. If you are talking about terminal stuff that is true, they are called lines and it is easy. But when that is not the case panic sets in.

    The second thing I see is people fighting the DataReceived Event Handler. My advice is don’t. Treat it like a spoiled child that is never going to learn and just give it whatever it wants, whenever it wants.

    Lastly, a byte can contain 256 values. The standard encoder for the serial port is for 7-bit data. If you have 8 bit data you need to change the encoding. I use
    System.Text.Encoding.GetEncoding("Windows-1252") always and have not had any problems.

    I wanted fast code, and to write the code in such a way that it could be used for any application.

    I have successfully sent, received, processed, and updated the UI at close to 1Mbps (USB Serial Converter) using the techniques I will describe. My test bed is a USB SerialConverter to breakout box with Pins 2 & 3 hot wired.



    **DataReceived Event Handler**

    Mine is short, sweet, simple. I read the number of bytes available (.BytesToRead) into a buffer of bytes of the correct size. I store that buffer of bytes into a queue.

    Depending on how the UI is being driven I then raise an event, start a delegate, or do nothing if it is timer or usr interaction based.

    That is it! Any time it wants to fire, it can.



    **So how does the data get to the user…**

    Ask yourself what are the possible scenarios of how you might want data? You might want:

    -one byte
    -a number of bytes
    -a character
    -a string
    -a string delimited by a character (like lines)
    -etc.

    And what if you want 2 bytes, then 4 characters, then a byte, and then a variable length line?

    At this point my DataReceived Event Handler has placed any data received into a queue. Here is an example. I have a GPS receiver that sends NMEA sentences (lines ending with CRLF). This is an example of one of the sentences:

    $GPGSV,3,1,11,10,75,053,29,29,52,311,32,24,50,298,30,02,39,073,30*77

    The serial ports DataReceived Event Handler might (usually does on my PC) fire several times with chunks of that data. The queue might look like this:


    Queue entry – data
    1 $
    2 GPGSV,3,1,11,10
    3 ,75,053,29,29,52,311,
    4 32,24,50,298,30,02,39,073,30*77

    The approach I took, with my limited knowledge of the programming tool at the time, was to write several routines that pieced the data back together. The common routine for all of those created a user buffer by removing entries from the queue and piecing them back together. The other routines then access the user buffer when they need data, and in the case of string based functions, converts it. If there is not enough data to satisfy the request the routines return empty strings or zero length byte arrays.

    Lets say I used a Timer control to read, process the sentences, and update the UI from my GPS receiver. In my Timer routine I have a function call to my version of readline. The first few times it is called it might return empty strings because the entire sentence has not been received. Eventually all of the data is in and I get the entire sentence back, because it is actually all there.

    At time 1
    Queue entry – data
    1 $
    2 GPGSV,3,1,11,10

    User buffer – empty


    At time 2
    Queue entry – data
    1 ,75,053,29,29,52,311,
    2 32,24,50,298,30,02,39,073,30*77

    User buffer – $ GPGSV,3,1,11,10


    At time 3
    Queue empty


    User buffer – $ GPGSV,3,1,11,10,75,053,29,29,52,311, 32,24,50,298,30,02,39,073,30*77


    The only imperative is that when you have a device that sends data all the time is that you process it in a timely manner. If not, as you can imagine, you run out of memory.

    During my testing of the USB to SerialPort converter I was surprised to find that it was capable of speeds near 1Mbps and I made the mistake of not doing that. I was using a user interface driven (click a button, see the data) routine that read all of the data and displayed the last chunk, when I received a high priority interrupt from Honey. You know the one, take the trash out, change the light bulb, etc. I left the test bed running and I had received an out of memory exception while servicing the Honey interrupt.


    What prompted me to write this was something I read in another thread. The poster had a problem because he said the device he was interfacing with only provided a 1 ms. gap in the data as its protocol. As it turned out the protocol was a delimiter, followed by a length byte, followed by the data. Then the problem was that that wasn’t enough to know that you actually had good data. The posters point was this:

    message_delimiter - 1 byte
    4 - length - 1 byte
    (4 data bytes) - 4 bytes

    But if you look at it this way, a **valid** message is always bounded by the message_delimiter:

    message_delimiter - 1 byte
    4 - length - 1 byte
    (4 data bytes) - 4 bytes
    message_delimiter - 1 byte

    Then you can safely process the data.


    Many of you are better at using your programming tool of choice. The code I wrote for serial ports was written several years ago when I was just learning VB .Net.(I cringe when I look at some of it today). But I am willing to bet that it will out perform most of the C(pick a flavor) code I have seen posted on many forums. One day I plan on re-visiting the code.

    I hope that this helps.





    The attached has several examples that use the loopback feature of a modem to do simulations. If you have a modem you should just need to open the port "COMx" and click go(a serial port with a loopback plug should work also). There is a debug feature, but it should only be used sparingly and for short periods of time. The examples show how to do reads using a timer, delegate, or loop.

    There is one other example that reads NMEA sentences and checks that the checksum is correct.

    There are routines to read bytes, strings and terminated strings.


    Enjoy.
    Link to this post http://www.vbforums.com/showpost.php...31&postcount=1

    VB 2008 Version
    NuSerial.zip



    updated - 3 Jan 2009
    changed sample program to remove confusion over receiving bytes backwards, at least i hope i did.

    updated - 9 Jan 2009
    corrected error in zip file

    updated - 29 Jan 2009
    new version

    EDIT: 31 March 2023

    A simple version of how to do SerialPorts. The test code requires a button, a textbox, three labels and a richtextbox.

    Two background tasks run. One accumulates the data looking for a message terminated by a carriage return. When found the message is queued for the message processing task.

    Code:
    Public Class Form1
    #Region "CODE TO TEST SERIAL PORT IMPLEMENTATION"
    
        '>>>>>>>>>>>>>>>>>>>>>>>>  
        Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
            'start the worker tasks <<<<<<<<<<<<!!!!!
            'this could be in the load event also
            MessageProcTask = Task.Run(Sub() ProcMessages())
            ReadSerialPortTask = Task.Run(Sub() ReadSerialPort())
    
            SerialPort1.PortName = "COM1"
            'OverRun errors occur at speeds > 38400 when using the loop back plug
            SerialPort1.BaudRate = 38400 '110, 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 57600, 115200 
            SerialPort1.Open()
            SerialPort1.DtrEnable = True
            SendStuff()
        End Sub
    
        Private Sub SendStuff()
            ' this is ran on a PC with a hardware serial port
            '  this port has a loop back plug which means what is sent is received on the same PC
            Static t As Task
            If t Is Nothing OrElse t.Status = TaskStatus.RanToCompletion Then
                Me.BeginInvoke(Sub()
                                   RichTextBox1.Clear()
                                   Label2.Text = _DataReceivedEvents.ToString("n0")
                                   Label1.Text = _messagesRcvd.ToString("n0")
                               End Sub)
                t = Task.Run(Sub()
                                 Dim mess As String
                                 Dim mTX As Integer
                                 Threading.Thread.Sleep(100)
                                 Const sendCT As Integer = 100
                                 For mTX = 1 To sendCT
                                     mess = String.Format("{1}{0}FOO {1}{0}{1,4} Lorem ipsum dolor sit amet, consectetur adipiscing...{0}",
                                                            ControlChars.Tab, mTX)
                                     SerialPort1.Write(mess)
                                     SerialPort1.Write(ControlChars.CrLf)
                                 Next
    
                                 'test empty messages
                                 SerialPort1.Write(ControlChars.Cr)
                                 SerialPort1.Write(ControlChars.Cr)
    
                                 Threading.Thread.Sleep(sendCT \ 100 * 1000 + 500) 'give a chance for all messages to be processed
    
                                 Me.BeginInvoke(Sub()
                                                    Label2.Text = _DataReceivedEvents.ToString("n0")
                                                    Label1.Text = _messagesRcvd.ToString("n0")
                                                    Label3.Text = _ErrorReceivedEvents.ToString("n0")
                                                    _DataReceivedEvents = 0
                                                    _messagesRcvd = 0
                                                    _ErrorReceivedEvents = 0
                                                End Sub)
                             End Sub)
            End If
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            SendStuff()
        End Sub
    #End Region
    
    #Region "SERIAL PORT IMPLEMENTATION"
        Private WithEvents SerialPort1 As New IO.Ports.SerialPort
        Private _ErrorReceivedEvents As Long = 0L
        Private Sub SerialPort1_ErrorReceived(sender As Object,
                                              e As IO.Ports.SerialErrorReceivedEventArgs) Handles SerialPort1.ErrorReceived
            Threading.Interlocked.Increment(_ErrorReceivedEvents)
            Dim err As Long = Threading.Interlocked.Read(_ErrorReceivedEvents)
            Debug.Write(err.ToString("n0"))
            Debug.Write("  ERR  ")
            Debug.WriteLine(e.EventType.ToString)
            ' Stop
        End Sub
    
        Private _DataReceivedEvents As Integer = 0 'typically a lot more _DataReceivedEvents than of _messagesRcvd
        Private ReadWait As New Threading.AutoResetEvent(False)
        Private Sub SerialPort1_DataReceived(sender As Object,
                                             e As IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
            'this is the entire DataReceived event handler
            Threading.Interlocked.Increment(_DataReceivedEvents)
            ReadWait.Set() 'cause ReadSerialPort to run
        End Sub
    
        Private _messagesRcvd As Integer = 0
        Private ReadSerialPortTask As Task
        Private Sub ReadSerialPort()
            '
            'this is run as a Background task
            '
            Dim data As New System.Text.StringBuilder(1024 * 1024) 'accumulate SerialPort data here
            Dim mess As New System.Text.StringBuilder(1024 * 4) 'individual message
            Dim foundMess As Boolean = False
            Do
                ReadWait.WaitOne() 'wait for SerialPort1.DataReceived
    
                Do While SerialPort1.BytesToRead > 0 'accumulate all available bytes
                    data.Append(SerialPort1.ReadExisting)
                Loop
                Do 'process message, if one available
                    '  protocol
                    '   in this case looking for a string terminated by CR
                    mess.Length = 0 'reset message
                    foundMess = False ' and not found
                    Dim idx As Integer = 0
                    For idx = 0 To data.Length - 1
                        'look for CR??????
                        If data(idx) = ControlChars.Cr Then '<<<<<<<<<<<<<<<<<<<<<<<
                            'note that the CR will NOT be in mess
                            foundMess = True 'message found 
                            Threading.Interlocked.Increment(_messagesRcvd)
                            Exit For
                        ElseIf data(idx) = ControlChars.Lf Then '<<<<<<<<<<<<<<<<<<<<<<<
                            Continue For 'skip LF
                        End If
                        mess.Append(data(idx))
                    Next
                    If foundMess Then
                        data.Remove(0, idx + 1) 'remove found message from data
                        _messageQ.Enqueue(mess.ToString)
                        MessageWait.Set() ' method ProcMessages will process messages
                    End If
                    'look for more messages in data?
                Loop While foundMess AndAlso data.Length > 0 'found one, more data present 
            Loop
        End Sub
    
        Private MessageProcTask As Task
        Private _messagesProcd As Integer = 0
        Private MessageWait As New Threading.AutoResetEvent(False)
        Private _messageQ As Concurrent.ConcurrentQueue(Of String)
        Private Sub ProcMessages()
            _messageQ = New Concurrent.ConcurrentQueue(Of String)
            Do
                MessageWait.WaitOne()
                Do While _messageQ.Count > 0
                    Dim mess As String
                    If _messageQ.TryDequeue(mess) Then
                        Dim parts() As String
                        parts = mess.Split(ControlChars.Tab)
                        '  interact with the UI
                        If parts.Length < 3 Then Continue Do
                        Me.BeginInvoke(Sub()
                                           Label1.Text = parts(0)
                                           If parts.Length >= 3 Then TextBox1.Text = parts(2)
                                           RichTextBox1.AppendText(parts(1))
                                           RichTextBox1.AppendText(ControlChars.Cr)
                                           RichTextBox1.ScrollToCaret()
                                       End Sub)
                    Else
                        Threading.Thread.Sleep(0)
                    End If
                Loop
            Loop
        End Sub
    #End Region
    End Class
    Last edited by dbasnett; Mar 31st, 2023 at 12:29 PM.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  2. #2

    Thread Starter
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,754

    Re: Serial Port

    Here is a 2005 version. It was pieced together from the 2008 version and was NOT (barely) tested under 2005.

    MySerial2005.zip
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  3. #3
    Member
    Join Date
    Jul 2008
    Location
    Czech Republic
    Posts
    55

    Re: Serial Port

    Thank you a lot for 2005 version
    Code Hard, Go Pro!

  4. #4
    New Member
    Join Date
    Dec 2008
    Location
    South Africa
    Posts
    1

    Re: Serial Port

    Quote Originally Posted by dbasnett
    VB2008

    My method of handling the serial port is demonstrated in the attached project. The module has all of the routines, even though only some are demonstrated.

    I do not use BeginInvoke. At very high bit rates it is very expensive.

    Attachment 67815
    Hi dbasnett,
    I am trying to read a serial instrument with your sample, I have changed baudrate=4800, databits=7, stop bits=2 and set dtr=true
    i can communicate with the instrument but in the rtbytes string the string is back to front intead of +006.14 I get 41.600+ as I am new to Vb2008 i would appreciate any help to correct this, I need the value in a string
    i have some BBC Basic programming experiance not nothing to write home about and it was in 1984
    thank you
    Softselect

  5. #5

    Thread Starter
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,754

    Re: Serial Port

    to read a string use one of the following:
    Code:
                        Dim rcvSTR As String
                        rcvSTR = zSPGetString() 'read all available bytes as a string
                        rcvSTR = zSPGetLine(True, False, False, False) 'or read a line
    you didn't post code so it is hard to know what happened. also, describe what you are trying to read? will it always look like "+006.14"?
    Last edited by dbasnett; Dec 16th, 2008 at 08:52 AM.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  6. #6
    New Member
    Join Date
    Dec 2008
    Posts
    2

    Re: Serial Port

    Hello, when I load the program in VS2008, I am getting a security error about the location of the program. If I click ok, it loads in with 14 errors about names that are not declared, how can I fix that?

    EDIT: I removed the file SerialPortRcvEvent.VB and re-added it, those errors are gone but I am getting 3 warnings:


    Warning 1 Variable 'zSPGetAllBytes' is passed by reference before it has been assigned a value. A null reference exception could result at runtime. C:\Documents and Settings\Allan\My Documents\Visual Studio 2008\Projects\MySerial\MySerial\SerialPortRcvEvent.vb 157 26 MySerial
    Warning 2 Function 'zSPGetAllBytes' doesn't return a value on all code paths. A null reference exception could occur at run time when the result is used. C:\Documents and Settings\Allan\My Documents\Visual Studio 2008\Projects\MySerial\MySerial\SerialPortRcvEvent.vb 165 5 MySerial
    Warning 3 Variable 'zSPGetLine' is used before it has been assigned a value. A null reference exception could result at runtime. C:\Documents and Settings\Allan\My Documents\Visual Studio 2008\Projects\MySerial\MySerial\SerialPortRcvEvent.vb 214 12 MySerial



    I am still getting the error about the project location not being trusted.


    EDIT:

    I have ignored the three warnings for the time being. I have used your program and while it does indeed read data from my radio, I found that sometimes I have to send the command several times and then finally it will display the bytes in your rtbCHAR Rich Text Box. Is there a delay or perhaps a glitch that might prevent the command from being executed everytime?
    I have also discovered that the bytes returned are reversed, how would I get it to read the bytes in the proper order? I think that this is the issue that SoftSelect is talking about.
    Last edited by allan-m; Dec 22nd, 2008 at 03:16 AM.

  7. #7

    Thread Starter
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,754

    Re: Serial Port

    i don't know about the security error, it probably has to do with your setup. no one else has ever commented on it.

    the three warnings can be ignored.

    as to returning bytes in the wrong order; the code returns bytes in the order they are received.

    what are you sending, and what do you expect back? the code i provided accumulates text in thBytes, a stringbuilder, in reverse order. that code is there for the display only. you need to write your own calls to my routines for your application.
    Last edited by dbasnett; Dec 22nd, 2008 at 08:37 AM.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  8. #8
    New Member
    Join Date
    Dec 2008
    Posts
    2

    Re: Serial Port

    Ok, I am still having problems. Here is exactly what I am doing:

    I am sending the following command to the serial port:

    SerialPort1.Write("FA;")

    The above is in a timer and sent every second, because this is the frequency display of my radio.

    The data that is sent back to me over the serial port is:

    ;00059270000AF;00059270000AF;00059270000AF;00059270000AF;00059270000AF;00059270000AF;00059270000AF;0 0059270000AF;00059270000AF;00059270000AF;00059270000AF;00059270000AF;00059270000AF;00059270000AF



    If you look closely at the above data, you will see the following number backwards "7295". That is the radios frequency in Mhz, what I need to do is get that data somehow and display it in a textbox that is updated with the timer. Below is code that was borrowed and is what is giving me the above data.

    Private Sub butOC_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles butOC.Click
    'open / close button
    butOC.Enabled = False : butOC.Refresh()
    If butOC.Text = "Open" Then
    'open Port
    'Port Setup
    'defaults
    'SerialPort1.ReadBufferSize = 4096
    'SerialPort1.DataBits = 8
    'SerialPort1.Parity = IO.Ports.Parity.None
    'SerialPort1.StopBits = IO.Ports.StopBits.One
    'SerialPort1.ReadTimeout = -1 'forever
    SerialPort1.ReadTimeout = 0
    'SerialPort1.WriteTimeout = -1 'forever
    SerialPort1.WriteTimeout = 2
    'SerialPort1.ReceivedBytesThreshold = 1 'don't change! unless you really need to
    'SerialPort1.Encoding = Encoding.GetEncoding(20127) ' byte < 128, bytes > 127 equal question mark
    SerialPort1.Encoding = AllByteEnc 'so byte > 127 aren't question marks
    If cbSPD.SelectedItem Is Nothing Then
    SerialPort1.BaudRate = Convert.ToInt32(defSPD) '<<<<<<<<<<<<<<<<<<<<<<< my default speed - Change
    Else
    SerialPort1.BaudRate = Convert.ToInt32(cbSPD.SelectedItem.ToString) '<<<<<<<<<<<<<<<<<<<<<<< my default speed - Change
    End If
    'determine port to open
    If cbPorts.SelectedItem Is Nothing Then
    SerialPort1.PortName = defPort 'use port default if nothing selected
    Else
    SerialPort1.PortName = cbPorts.SelectedItem.ToString 'use selected item
    End If
    If zSPopen(SerialPort1, True) Then 'zSPopen opens the port and sets up handler
    'port opened succesfully
    butOC.Text = "Close"
    butOC.Enabled = True : butOC.Refresh()
    butSend.Enabled = True
    tbSend.ReadOnly = False
    'loop while there are bytes in the queue
    Do While SerialPort1.IsOpen OrElse zSPNumBytesInQ() > 0
    bytesFromQ = New Byte() {}
    bytesFromQ = zSPGetBytes(1) 'get one byte if available
    If bytesFromQ.Length > 0 Then 'did we get data
    'yes
    ' the rich text box shows newest byte on left
    rbRcv.Checked = True : rbRcv.Refresh()
    thBytes.Insert(0, " ", 1) 'insert new byte on left in the RTB
    thBytes.Insert(0, bytesFromQ(0).ToString, 1)
    rtbBytes.Text = thBytes.ToString
    'don't show cr lf in the following textbox
    If Not (bytesFromQ(0) = 10 OrElse bytesFromQ(0) = 13) Then
    rtbCHAR.Text = Chr(bytesFromQ(0)).ToString & rtbCHAR.Text
    End If
    If thBytes.Length > 512 Then thBytes.Length = 128 'don't let rtb get to big
    If rtbCHAR.TextLength > 512 Then rtbCHAR.Text = "" 'don't let rtb get to big
    Else 'no data received
    rbRcv.Checked = False : rbRcv.Refresh()
    End If
    Application.DoEvents() 'needed so event handler fires
    Loop
    End If
    Else
    'close Port
    FreqTime.Enabled = False 'disable frequency display
    butSend.Enabled = False
    tbSend.ReadOnly = True
    zSPclose(SerialPort1) 'close serial port, remove handler
    butOC.Text = "Open"
    butOC.Enabled = True : butOC.Refresh()
    rbRcv.Checked = False
    End If
    End Sub

    rtbCHAR is the textbox that I would like to send the proper data and format to. I guess I just do not quite understand what the program is doing. The program was downloaded here . I am just trying to adapt his serial program to my needs until I understand what is going on.


    How would I write the code within the above code to display the data that I need? Remember the timer is sending the command once every second.

  9. #9
    New Member
    Join Date
    Dec 2008
    Posts
    5

    Re: Serial Port

    hi guys, I tried both of the program, but none works for me.... I can open the port but when i send the text, it didnt change anything, like Bytes in Queue still in 0, Byte/Sec still in 0, Events / sec still in 0, Queue Depth still 0 and Max still 0... Receive data show nothing...

    For the hardware side, I have connect the serial cable from this PC to another PC since each of my PC only has 1 serial port. So like that correct? Do I need to do anything else?

    Thanks very much!

  10. #10

    Thread Starter
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,754

    Re: Serial Port

    i thought in the other thread you said it was receiving data?
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  11. #11
    Member
    Join Date
    Feb 2009
    Posts
    41

    Re: Serial Port

    dwbasnett,

    Slightly OT:

    I read in another post from you about an example project to interface with a USB-serial port, and that you would put it in the 'code bank'. I assume that the cide bank is some sort of repository of user contributions, but where is it? Can't find it...

    Thanks,

    Jan Didden

  12. #12

    Thread Starter
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,754

    Re: Serial Port

    there is nothing special about a usb serial port. the project in post #1 should work for you.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  13. #13
    Member
    Join Date
    Feb 2009
    Posts
    41

    Re: Serial Port

    Hi Dewayne,

    I did indeed study your NuSerial example, but there's one or two things that still confuse me.

    For instance, I understand the selection box where you can select a ComPort, but how would Joe User know which one to select? I thought that in the program you could look at a property of each particular driver, like VID or PID or Manufacturer name, and select the comport you need for your app.

    In your example you also use the specific hardware lines coded in thePins, but isn't that a strictly hardware thing? If yo look at a USB virtual ComPort, can you actually access those 'virtual' pins??

    Edit: I guess what I want is some kind of 'GetDeviceInfo' that gives me access to the same kind of info that you get from Properties in the device manager.

    Thanks for educating me,

    Jan Didden
    Last edited by janneman; Mar 1st, 2009 at 02:04 PM.

  14. #14
    Member
    Join Date
    Feb 2009
    Posts
    41

    Re: Serial Port

    OK, made some more progress to find 'my' comport.
    There are structures Dev_Broadcast_Hdr containing info on system devices, and Dev_Broadcast_Port with info on system ports. So what I need to do is to check all _Hdr's to see if the device is a com port, and if so, check dbcp_name in _Port to see if it is 'My' device driver on that comport. Makes sense?

    Question is, how do I 'cycle' through all devices and when I find a com port, how to poit to the -Port block for that particular com port?

    This is what I have so far:

    Code:
    Imports System.IO.Ports
    Imports System.Runtime.InteropServices
    
    Public Class Form1
        'Device information structure
        Public Structure Dev_Broadcast_Hdr
            Public dbch_size As Int32
            Public dbch_devicetype As Int32
            Public dbch_reserved As Int32
        End Structure
        Const DevTypeIsComPort As Int32 = &H3
    
        'Port information structure
        Public Structure Dev_Broadcast_Port
            Public dbcp_size As Int32
            Public dbcp_devicetype As Int32
            Public dbcp_reserved As Int32
            Public dbcp_name As String
        End Structure
        Dim MyDevice As String = "My Device"
    
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            'this is just to see the available comports
            Dim comm As New List(Of SerialPort) 'list of comm ports
            For Each PNstr As String In SerialPort.GetPortNames() 'get a list of Com Port Names
                comm.Add(New SerialPort) 'insert new port into list
                comm(comm.Count - 1).PortName = PNstr 'set the name
                MessageBox.Show(PNstr)
            Next
    
            'this is to find "My Device" among the com ports
            Dim DeviceInfo As Dev_Broadcast_Hdr
            'How to cycle through devices to find com ports?
            If DeviceInfo.dbch_devicetype = DevTypeIsComPort Then ' this device is a com port
                'how to point to this particular Dev_Braodcast_Port?
                Dim PortInfo As Dev_Broadcast_Port
                'Now find friendly name in dbcp_name
                If PortInfo.dbcp_name = MyDevice Then
                    'found it; do something
                End If
            End If
    
        End Sub
    End Class
    Any help is appreciated!

    Jan Didden

  15. #15
    Member
    Join Date
    Aug 2010
    Posts
    44

    Re: Serial Port

    I am a green horn so some of your code I don't understand but do get the general concepts. I was very excited to see you program since for what I want to do them main part I need is a hypterterminal like program in VB that I can modify slightly. I program CDMA and GPRS wireless cell modems and wanted to create a program that I could send all my commands with automatically. Basically send the first command and then send the next based on the response back from the modem

    I downloaded your PC Comm utility and am having problems. I am using VB Express 2008 so it did have to convert the program. The only error I got was something to do with the start page, and was an easy fix.
    I am able to open a port, I am connecting to a GPRS cell modem through
    Com 4
    38400 (I did have to change the selection value in you program from 36000 to 38400) No big deal
    8
    None
    1

    most of the commands I send should return a simple "Ok" I am able to send commands but receive nothing in return. I then went into HypterTerminal to verify that I can communicate with the device and when I open the port in hypterterminal all the commands I was trying to send seemed to be buffered at the port some how and got sent all at once which of course returned an error.
    Is there something I'm missing?

    Any help would be appriciated, please let me know if there is any more information I can provide for you.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width