locked
VB code to automatically detect baud rate of serial port

    Question

  • Hi All,

    We have a weigh bridge connected to PC via serial port.A VB code fetches the data from serial port and puts it in clipboard,which can be used by other applications like SAP.

    We have several different makes of weigh bridge at different locations, each with separate settings(baud rate,data bit,parity), hence we need to change the VB code each time a new make weigh bridge is installed.

    can we write a generic VB code which can automatically detect all these settings and capture the weight?

    This will help us making changes in source code each time.

    Thanks in advance

    Saturday, January 28, 2012 3:38 AM

Answers

  • The only way is to use a loop that applies a sequence of rates and then looks for receive data that can be decoded properly.  Fortunately, you will have to know the actual embedded protocol -- for most such scale-type devices, the data sent is terminated by a newline (CRLF) character pair.  Thus, your detection code would buffer a set of characters of sufficient length to guarantee that a full message has been received.  Scan that set of characters to look for the pattern that you expect to see, and if it is present then you have the correct speed.  Otherwise try the next possible speed. 

    Some devices require that you send a command and await a response, though most simply output data continuously.  Regardless, the same basic pattern should work.

    I have several different examples of this sort of thing in my book (some for devices that send a continuous stream of data and others for devices that require a command and then issue a specific response), and in each case I use the same basic approach.

    Dick


    Dick Grier. Author of Visual Basic Programmer's Guide to Serial Communications 4. See www.hardandsoftware.net.
    Saturday, January 28, 2012 6:11 PM
  • You are showing VB6 code, so this isn't the forum to answer that question specifically.

    However, to autodetect, what you have to do is to add a loop.  Inside the loop set the serial port speed, then open the port.  The block of the code then waits for data to be detected and properly decoded.  If this code succeeds (within some timeout), then the you have the correct speed for that device.  You then can exit the loop and continue to receive data somewhere else (such as in the OnComm event - or just later in the routine) and process it there.  If you do not detect properly decoded data, then first close the port (this is required), then reset the port speed to the next possible speed and repeat by allowing the loop to continue until it finally succeeds - or fails if no data is properly decoded.

    Make sure that any loop that you use has a terminating condition, and often loops should terminate if they take too long to execute.

    Dick


    Dick Grier. Author of Visual Basic Programmer's Guide to Serial Communications 4. See www.hardandsoftware.net.
    Monday, January 30, 2012 5:47 PM
  • Use the .NET4.0 SerialPort and look for errors in the SerialErrorReceived event.  You should get frame errors if the baud rate isn't correct.
    Tuesday, January 31, 2012 8:10 PM

All replies

  • I am not sure that you can autodetect the port settings.  Why not just create a configuration file which the end user can modify with the settings?  Read the file to get the setting values at startup.  You could even provide a small dialog which lets the end user change this setting in your application.
     

    --
    Mike
    Saturday, January 28, 2012 12:20 PM
  • A method is given by Jinzai: http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/91743d3c-f649-4fa0-8896-24f625186c5d, but you might still want a fall-back where the user can enter the settings, as suggested by Mike. Perhaps you could have a drop-down with a list of manufacturers and models for convenience.

    --
    Andrew

    Saturday, January 28, 2012 2:21 PM
  • You can see if the device itself returns any kind of information about the model or manufacturer of the device, Like hardware ID, Vendor ID , etc, then based on that information you could configure your settings.

     

    http://stackoverflow.com/questions/3744344/get-usb-serial-number-using-vb-net


    If you want something you've never had, you need to do something you've never done. If you believe something to be true, then one day you will be called upon to demonstrate that truth.
    Saturday, January 28, 2012 5:15 PM
  • The only way is to use a loop that applies a sequence of rates and then looks for receive data that can be decoded properly.  Fortunately, you will have to know the actual embedded protocol -- for most such scale-type devices, the data sent is terminated by a newline (CRLF) character pair.  Thus, your detection code would buffer a set of characters of sufficient length to guarantee that a full message has been received.  Scan that set of characters to look for the pattern that you expect to see, and if it is present then you have the correct speed.  Otherwise try the next possible speed. 

    Some devices require that you send a command and await a response, though most simply output data continuously.  Regardless, the same basic pattern should work.

    I have several different examples of this sort of thing in my book (some for devices that send a continuous stream of data and others for devices that require a command and then issue a specific response), and in each case I use the same basic approach.

    Dick


    Dick Grier. Author of Visual Basic Programmer's Guide to Serial Communications 4. See www.hardandsoftware.net.
    Saturday, January 28, 2012 6:11 PM
  • Thank you all for you quick response.

    Mike's Idea is what I thought first.However we still need to know the settings of the machine.In some cases vendors provide, but in some cases they are are not aware of the same.Here we have to figure it out our self.That's why I need an auto-detection method.

    Hi Paul these weigh bridge machines do not send any information, it keeps streaming the measured weight(which is 0kg when no vehicle is present).

    I think you are right Dick, in fact I had this Idea as an option in my mind. These weigh bridge machines continuously stream the measured weight and don't need any command to be sent. I even thought of making an application to try all possible combinations manually. Automating this process will need some hit and trial testing sessions. Please share any relevant code, if you have any.

    Thanks once again :)

    Sunday, January 29, 2012 5:33 AM
  • It seems that every scale manufacture has his own idea of an appropriate embedded protocol -- each seem to be different from another similar machine.  For that reason, I have several examples in the code that accompaies my book.  This might or might not be close to what you need.  If you post a link to the embedded protocol description, I may be able to reply with an example that you could start with.

    Dick


    Dick Grier. Author of Visual Basic Programmer's Guide to Serial Communications 4. See www.hardandsoftware.net.
    Sunday, January 29, 2012 6:50 PM
  • It is a very simple solution,if you have the settings.

    And moreover as mentioned earlier, these devices continuously stream the weight as a string(which is 0kg when no vehicle is there).

    Hence if you have settings then, it's pretty simple.

    I have pasted the code below for the same.

     

    MSComm1.CommPort = 1
    MSComm1.Settings = "2400,e,7,1"

    MSComm1.InputLen = 0
    MSComm1.PortOpen = True
    MSComm1.Output = Chr$(5)
    MSComm1.RThreshold = 0

    Do
        dummy = DoEvents
    Loop Until MSComm1.InBufferCount >= 7
    InString = MSComm1.Input

    MSComm1.PortOpen = False

    Char = ""
    For I = 1 To Len(InString)
        If Asc(Mid(InString, I, 1)) >= 48 And Asc(Mid(InString, I, 1)) <= 57 Then
            Char = Char + Mid(InString, I, 1)
        End If
    Next I
    Weight = Char
    Clipboard.Clear
    Clipboard.SetText (Int(Weight))
    Unload Me

    If auto baud detection is possible then there will be a generic solution for all weigh bridges.

    Monday, January 30, 2012 11:18 AM
  • Hi,

    You can see what a particular serial port baud rate is already set at as follows.>>

            Dim sp1 As New System.IO.Ports.SerialPort("COM1")
            MessageBox.Show(sp1.BaudRate.ToString)
    


    I hope this helps.  :-)

     




    Regards,

    profile for John Anthony Oliver at Stack Overflow, Q&A for professional and enthusiast programmers

    Click this link to see the NEW way of how to insert a picture into a forum post.

    Installing VB6 on Windows 7

    App Hub for Windows Phone & XBOX 360 developers.

    Monday, January 30, 2012 12:07 PM
  • You are showing VB6 code, so this isn't the forum to answer that question specifically.

    However, to autodetect, what you have to do is to add a loop.  Inside the loop set the serial port speed, then open the port.  The block of the code then waits for data to be detected and properly decoded.  If this code succeeds (within some timeout), then the you have the correct speed for that device.  You then can exit the loop and continue to receive data somewhere else (such as in the OnComm event - or just later in the routine) and process it there.  If you do not detect properly decoded data, then first close the port (this is required), then reset the port speed to the next possible speed and repeat by allowing the loop to continue until it finally succeeds - or fails if no data is properly decoded.

    Make sure that any loop that you use has a terminating condition, and often loops should terminate if they take too long to execute.

    Dick


    Dick Grier. Author of Visual Basic Programmer's Guide to Serial Communications 4. See www.hardandsoftware.net.
    Monday, January 30, 2012 5:47 PM
  • Once again Thank you all for your response.

    Your code is really helpful John but only in those cases where vendor has changed the settings of comm port and most of the time they are least bothered of doing so.

    Thank you Dick for your guidance.I will surely go ahead with this idea and see if it works reliably.This was something which I started with in my mind.

    I thought there could be some better approach in auto calculation of baud rate, however it seems this is the best option we have :)

    Once I finish this I will surly share the benefits and shortcomings of this method.

    Meanwhile if you guys have something to share on this, then please do so.

     

    Tuesday, January 31, 2012 4:55 AM
  • Use the .NET4.0 SerialPort and look for errors in the SerialErrorReceived event.  You should get frame errors if the baud rate isn't correct.
    Tuesday, January 31, 2012 8:10 PM
  • The other errors that you might see are receive overrun (or parity, since OP's message indicates that parity is used).  However, this isn't 100% effective, and requires use of an additional method; I've seen situations where there was no error generated.

    Dick


    Dick Grier. Author of Visual Basic Programmer's Guide to Serial Communications 4. See www.hardandsoftware.net.
    Wednesday, February 01, 2012 9:26 PM
  • The other errors that you might see are receive overrun (or parity, since OP's message indicates that parity is used).  However, this isn't 100% effective, and requires use of an additional method; I've seen situations where there was no error generated.

    Dick


    Dick Grier. Author of Visual Basic Programmer's Guide to Serial Communications 4. See www.hardandsoftware.net.

    It seems pretty effective for GPS.  I only get Frame errors.  I compare the received byte count to the error count.  For any baud other than 4800, the byte count is less than 3 times the error count.  For 4800 there are a few errors immediately after the port is opened, but none after.
    Wednesday, February 01, 2012 9:42 PM
  • These weigh bridges are connected to a micro-controller box which is programed to stream the weight serially.

    It depends on the micro-controller box's programming that, what the settings would be(baud rate,parity,start stop bit).

    Most of the time weight is continuously transferred in text format.Once baud rate is detected then parity and other settings are piece of cake.

    Most important is baud rate itself.

    I think John's frame error could help in detecting baud rate and as said once baud detected rest is easy part :).

    One more thing I am deliberately using MSCOMM32.OCX in the solution as, registering MSCOMM32 on a PC is very easy and if need be it can be controlled through SAP-ABAP code directly.So in that case, logic just need to be transferred in SAP-ABAP without changes.

    Thursday, February 02, 2012 5:45 AM