Mscomm1 Advice Please
Mscomm1 Advice Please
Mscomm1 Advice Please
Mscomm1 Advice Please
Mscomm1 Advice Please
Mscomm1 Advice Please Mscomm1 Advice Please Mscomm1 Advice Please Mscomm1 Advice Please Mscomm1 Advice Please Mscomm1 Advice Please Mscomm1 Advice Please Mscomm1 Advice Please
Mscomm1 Advice Please Mscomm1 Advice Please
Mscomm1 Advice Please
Go Back  Xtreme Visual Basic Talk > > > Mscomm1 Advice Please


Reply
 
Thread Tools Display Modes
  #1  
Old 11-12-2007, 01:06 PM
AlexanderJames AlexanderJames is offline
Junior Contributor
 
Join Date: Sep 2005
Posts: 382
Default Mscomm1 Advice Please


Hi All

Please could someone give me some advice, i am writing a program that gets data from a digital scale using the mscomm1 control. I have set the scale to send data continuesly. So basicall what i have at the moment is when an item is put onto the scale i click on a command button and the weight is put into a textbox, the only problem i am having is that i have to push the command button 2 or 3 times before i get the correct weight. Please could someone give me some advice on this. Below is the code that i have for the command button.

Code:
Private Sub cmdGet_Click()
'Puts the full bottle weight from the scale into the full text box'
    txtNew.Text = MSComm1.Input
    txtNew.Text = Replace(txtNew.Text, "@", "")
    txtNew.Text = Replace(txtNew.Text, "B", "")
    txtNew.Text = Replace(txtNew.Text, "00", "")
End Sub
I set all the com port settings on form load which seems to work fine.

Many thanks in advance
AJ
Reply With Quote
  #2  
Old 11-12-2007, 07:38 PM
Cerian Knight's Avatar
Cerian KnightMscomm1 Advice Please Cerian Knight is offline
Polymath (in disciplina)

Super Moderator
* Expert *
 
Join Date: May 2004
Location: Michigan
Posts: 4,199
Default

A typical digital scale (that I am familiar with) will output either 16 or 22 characters of data per reading. However many characters are being sent, you need to know the exact format of the data output from the balance. You can then build a Public or Static string (don't write to the TextBox yet!) until it contains between x and 2x-1 characters looking for x-1 characters before the terminator (e.g. EOT). I would normally request a single reading instead of setting for continuous, as that simplifies coding dramatically. In any case, for a fixed length data string you can change MSComm1.InputLen so that it equals the number of characters. Using the OnComm Event can help, but takes more study. I recommend it, though. Once you have enough data in the String you can parse it with InStr looking for the terminator and then use the Mid$ function to extract just the reading to put in the TextBox. Work through some of this and post back some more information about the character format and show us some more code you have tried.
__________________
I got all the answers wrong on the GLAT, apparently even #9 (where I put a period in the middle of the box and labeled it 'singularity ripe for rapid inflation').
Reply With Quote
  #3  
Old 11-13-2007, 12:50 AM
AlexanderJames AlexanderJames is offline
Junior Contributor
 
Join Date: Sep 2005
Posts: 382
Default

Thank you Cerian

I will give this a go, and report back.

Many thanks
AJ
Reply With Quote
  #4  
Old 11-13-2007, 01:13 AM
mkaras's Avatar
mkarasMscomm1 Advice Please mkaras is offline
Ultimate Contributor

Retired Leader
* Expert *
 
Join Date: Mar 2004
Location: Beaverton, OR
Posts: 1,874
Default

Some serial port devices that send data over and over may very well have a lead-in character as well. If there is such on the frames of data sent then the process of receiving the data can be simplified to some degree. I often perform this type of task in the following manner:

Input data is handled either on the fly via the OnComm event or I use a timer that ticks every 10 milliseconds to fetch the bytes from MSComm. The code I make is typically coded as a state machine that may include states like:
0 - Waiting for Lead-In-Character
1 - Got LeadIn, Initialize Buffer to empty, Zero CRC accumulator if used and then wait for packet length byte to arrive,
2 - Got Length so set size counter, and wait for packet byte.
3 - Got Packet byte, append to buffer, calc partial CRC, decrement size counter and if zero go to 4. Wait in state 3 for next byte.
4 - Wait for CRC byte
5 - Got CRC byte, Check packet validity and if good pass to application.
Reply With Quote
  #5  
Old 11-13-2007, 12:47 PM
gayouj's Avatar
gayoujMscomm1 Advice Please gayouj is offline
Junior Contributor

* Expert *
 
Join Date: Jan 2006
Location: California
Posts: 317
Default

If all else fails, you can also just post all of the raw data to a text box so you can analyze it and verify that you are actually getting what you think you are getting. This is always good for a few clues.
__________________
http://www.joshuagayou.com
Reply With Quote
  #6  
Old 11-13-2007, 02:55 PM
AlexanderJames AlexanderJames is offline
Junior Contributor
 
Join Date: Sep 2005
Posts: 382
Default

Hi All

Thank you for all your advise, this is my first time coding a scale as well as using the Mscomm1 control so this is a bit greek to me. I have been testing a few things i set the inputlen to the length that i need and then replace all the characters that i dont need to get the correct weight. This works fine exept i need to push the command button a few times before the correct weight comes through and can't figure out why ( has this got something to do with the buffer) I also did some reading on the onCom event, but i only need to collect data once a command button is pushed, or maybe i read wrong. So still a bit stuck on this one. Any advice is much appreciated.

Many thanks
AJ
Reply With Quote
  #7  
Old 11-14-2007, 12:25 AM
mkaras's Avatar
mkarasMscomm1 Advice Please mkaras is offline
Ultimate Contributor

Retired Leader
* Expert *
 
Join Date: Mar 2004
Location: Beaverton, OR
Posts: 1,874
Default

Sounds like you have several conceptual problems here.

One. --- Setting the InputLen property of MSComm to the length of string you were expecting is almost useless when the data is arriving continuously in a repeating manner. The chance that MSComm happens to capture your string at the the begin to end of the string you desire is very small indeed. As a matter of fact the chance of this happening is probably about 1 in XX chances where the XX is the number of bytes in the repeating data flow!! You would probably do just as well to set the InputLen to 1 byte and fetch one at a time. The key is to buffer all the bytes received like has been suggested several times already in this thread. Trapping all the bytes gives you the opportunity to look over the stream of past characters and match up where you find its beginning and ending part within the buffer. Once again using the XX value from before you are likely to find the start of the scale report string anywhere from 1 to XX bytes into this accumulation buffer. The reason you currently have to press the command button several times is because each time you are grabbing a string of bytes from MSCOMM that are not synced to the begin to end of the string. Each time you are getting the last portion of one scale report and then the first portion of the next report. I suspect that the only reason that a few button clicks are able to capture a sequence that makes sense at all is that the scale has a somewhat of a delay time between the end of one report to the start of the next one.

Two. -- Consider looking at the data stream from the scale to identify what common byte may be transferred at the beginning of every packet. You can simplify the data capture of the stream from MSComm if you do not start storing the data into the buffer until you see this starting character. Setting the InputLen of MSComm to One (1) can actually be beneficial here since it facilitates the looking at the inputted character values for the start packet character. Many devices may use an ASCII control character like an SOH (start of header - &H01) or an STX (start of text - &H02) or ESC (escape character - &H1B) as the character to delimit the beginning of a data packet. There are other devices which simply spew out an ASCII text string of letters numbers and spaces that is then ended with a CR (carriage return - &H0D) value. In this case, since your data arrives repeatedly in a continuous manner, you could consider using such CR type end character as the BEGINNING start character of the next packet. As I described before you can look one byte at a time for this BEGIN character to determine when you are in sync with the scale data stream. Once the BEGIN character is received you may start to capture subsequent bytes into a buffer until you have captured the number in the bytes in the string you are trying to capture.

There are two good ways to access the bytes from MSComm. The preferred way is to use the OnComm event routine that can be triggered by the MSComm each time something arrives as input. If you set the properties if the MSComm control correctly you can have OnComm be triggered as each individual byte arrives in which case you initally search for the start character. Once that is found you set a global flag or state variable to indicate "start found' and instead append each received subsequent byte onto a global receive data packet buffer.

An alternate way to capture the MSComm input is to setup a Timer event routine in your Form code with the interval set to 10 or 20 milliseconds or so.
Each time the Timer tick event routine is triggered have it fetch bytes, one by one from MSComm, until there are none left in the controls internal buffer. As the bytes are fetched in this manner you can scan for the start byte pattern and then when found start capturing the bytes to the global reading buffer in a manner like described above for the OnComm method.

Each time this code, which will run asynchronous to any button press code on your form, has detected a start and gathered a scale report string into a buffer it can then place the string into another holding string. It could even set a boolean flag to indicate that data is in this holding buffer. Then when your button press comes that event code can test the holding buffer available flag and if set it can use the data in this holding buffer as the reading to display to the user. In the mean time the OnComm or Timer tick code continues to run and start gathering the next reading from the Scale which can subsequently be transferred to the holding buffer. If coded correctly the holding buffer will always have the most recent copy of the reading from the scale and is available whenever the command button is pressed.
Reply With Quote
  #8  
Old 11-16-2007, 01:15 AM
AlexanderJames AlexanderJames is offline
Junior Contributor
 
Join Date: Sep 2005
Posts: 382
Default

Thank you Very Much MKaras

I understand a bit better how the scale and Mscomm work now, i will test it out this weekend and post back.

Many thanks for your great explanation.
AJ
Reply With Quote
  #9  
Old 11-21-2007, 01:03 PM
AlexanderJames AlexanderJames is offline
Junior Contributor
 
Join Date: Sep 2005
Posts: 382
Default

Hi MKaras

Thank you for your advice, i have tried everything i still cannot get this **** scale to work the, if i set the input length to 0 i get a whole lot of junk if i set it to 1 then all i get is a C. And i am not advanced enough in vb to understand entirely how to put into code what you are suggesting. I never ask for code but please if you have a sample code or something i can work with i would really appreciate as i am completely stuck here.

Many thanks
AJ
Reply With Quote
  #10  
Old 11-21-2007, 02:15 PM
AlexanderJames AlexanderJames is offline
Junior Contributor
 
Join Date: Sep 2005
Posts: 382
Default

after alot of reading and reasearch i put together this code, im not sure if it is correct or am doing too much but still i get no data from the scale. Please could someone take a look at this and tell me where i'm going wrong.
Code:
Private Sub cmdGetData_Click()
    If Inside = True Then Exit Sub
    Inside = True
    stime = Timer
    MSComm1.CommPort = 1
    MSComm1.InBufferSize = 20
    MSComm1.Settings = "9600,n,8,1"
    MSComm1.InputLen = 0
    MSComm1.InputMode = comInputModeText
    MSComm1.InputLen = 0
    MSComm1.InputMode = comInputModeText
    If MSComm1.PortOpen = False Then MSComm1.PortOpen = True
    MSComm1.Output = Chr(5)
    While Timer - stime < 0.2: Wend
    buffer$ = ""
    i = 0
    Do
        i = i + 1
        buffer$ = buffer$ & MSComm1.Input
    Loop Until InStr(buffer$, Chr(13)) Or i = 20
    If buffer$ <> "" Then
        txtScale.Text = Format(Val(Mid(buffer$, 1, Len(buffer$) - 1)) / 1000, "0.000")
    Else
        If i = 20 Then txtScale.Text = "0.00"
    End If
    DoEvents
    If MSComm1.PortOpen = True Then MSComm1.PortOpen = False
    Inside = False
    Exit Sub
End Sub
Many thanks

Last edited by DougT; 11-22-2007 at 12:18 AM. Reason: Added Code tags
Reply With Quote
  #11  
Old 11-22-2007, 01:25 AM
the master's Avatar
the master the master is offline
Tachikoma
 
Join Date: Mar 2003
Location: Mansfield, UK
Posts: 4,596
Default

wow, that was a long post mkaras. I have been messing about with comm inputs lately too and found problems with syncing. I wanted 3 bytes but after so long i started getting the last 2 bytes then the first byte from the next set of data. I never thought about setting the inputlength to 1.

I do have some questions though. What does inputlen=0 do? I would have thought it would trigger the oncomm event when any number of bytes arrive but it doesnt seem to work like that.

If i was to have a long string of say 50 chars coming in. Would it affect performance to have the event fire for each character instead of just once for all 50?
__________________
"That which seems simple is often overlooked" ~ me
Halloween 2014 Yard Haunt
Halloween Special FX
Reply With Quote
  #12  
Old 11-22-2007, 01:28 AM
the master's Avatar
the master the master is offline
Tachikoma
 
Join Date: Mar 2003
Location: Mansfield, UK
Posts: 4,596
Default

AlexanderJames. Your problem might be the loop you are using to get the input data. Try adding "doevents"

Code:
......
    Do
        i = i + 1
        buffer$ = buffer$ & MSComm1.Input
doevents
    Loop Until InStr(buffer$, Chr(13)) Or i = 20
......
Edit: On second thoughts its probably your counter "i". You are telling it to loop 20 times max then stop. It depends how fast your PC is but it might loop through 20 times so fast that the device doesnt have time to reply before your app gives up. Doevents will slow it down a bit but maby you should put a delay in too so it checks for new bytes every 1 or 2 seconds
__________________
"That which seems simple is often overlooked" ~ me
Halloween 2014 Yard Haunt
Halloween Special FX
Reply With Quote
  #13  
Old 11-22-2007, 03:44 AM
DougT's Avatar
DougT DougT is offline
Ultimate Antique

Administrator
* Expert *
 
Join Date: Sep 2005
Location: Maldon,Essex, UK
Posts: 3,939
Default

The OnComm event is triggered when RThreshold > 0. I normally only ever use the OnComm as opposed to polling. Leaving InputLen = 0 causes the control to read (and empty) the entire buffer.

So with RThreshold = 1 and InputLen = 0 the OnComm will trigger on receipt of each individual byte (mostly, there may be more than RThreshold number of bytes received by the time your code actually processes the buffer - RThreshold is the minimum number of bytes that must be received before the OnComm event triggers) and the Input property will return all the data currently in the buffer.

By using that combination you can accumulate the data received into your own buffer until you receive the carriage return. Once that has been received it's a simple matter to unblock and display the result. A very simple implementation might look somethng like this:
Code:
Option Explicit
Dim strBuffer As String

Private Sub Form_Load()
'
' Set-up the Comm port to trigger the
' OnComm event when at least one character
' has been received
'
MSComm1.CommPort = 1
MSComm1.Settings = "9600,n,8,1"
MSComm1.RThreshold = 1
End Sub

Private Sub cmdGetData_Click()
'
' Open the port and request a measurement
'
MSComm1.PortOpen = True
MSComm1.Output Chr(5)
End Sub

Private Sub MSComm1_OnComm()
Dim strData As String
Dim intPos As Integer
Select Case MSComm1.CommEvent
    Case comEvReceive
        '
        ' Input the character(s) received and
        ' append them to our buffer
        '
        strData = MSComm1.Input
        strBuffer = strBuffer & strData
        '
        ' When a CR has been received
        ' unblock the data into the TextBox
        ' clear our buffer, ready for the next measurement,
        ' and close the Com port (it will be re-opened next time
        ' the cmdGetData_Click event happens)
        '
        ' If a CR hasn't been received just exit the routine
        ' leaving the contents of strBuffer intact and wait for
        ' the next comEvReceive Comm event
        '
        intPos = InStr(strBuffer, vbCr)
        If intPos <> 0 Then
            txtReceived.Text = Mid(strBuffer, 1, intPos - 1)
            strBuffer = ""
            MSComm1.PortOpen = False
        End If
End Select
End Sub
__________________
semel insanivimus omnes
S Data in context = Information, S Information in context = Knowledge, S Knowledge in context = Experience
S Experience in context = Wisdom= Data

Last edited by DougT; 11-22-2007 at 05:45 AM. Reason: Tidied comments
Reply With Quote
  #14  
Old 11-22-2007, 07:14 AM
the master's Avatar
the master the master is offline
Tachikoma
 
Join Date: Mar 2003
Location: Mansfield, UK
Posts: 4,596
Default

Ahh, That makes sense. I think my problem was not quite understanding RThreshold properly. The default is 0 so thats how i left it. I did try changing it once but i wasnt sure what was happening.

So, RThreshold=1 means fire the oncomm event for every byte
Inputlen=0 means get everything there is to get

Seems obvious now. I completely understand the way the custom buffer works because ive done it before with winsock. Ill be needing a serial input soon so ill get round to testing it within the next week or 2

Thanx
__________________
"That which seems simple is often overlooked" ~ me
Halloween 2014 Yard Haunt
Halloween Special FX
Reply With Quote
  #15  
Old 11-22-2007, 10:42 AM
AlexanderJames AlexanderJames is offline
Junior Contributor
 
Join Date: Sep 2005
Posts: 382
Default

Hi DougT

Thank you so much for your sample code it has helped me loads. I have added your code into my project with a few small changes, but i still have a similar problem all i get in my textbox now is @B when i weigh an object and press my comman button. If i press the same command button many times, sometimes the correct weight comes through. I have used hyperTerminal on the scale and the data comes through correctly, so can't understand why i can't get it to work in VB. Please could you help me with this. Below is the code, i have'nt got the wrap code tags icon so i will try to put it in a quote.

Code:
Dim strBuffer As String
Private Sub cmdGetData_Click()
    MSComm1.PortOpen = True
    MSComm1.Output = Chr(5)
End Sub
Private Sub Form_Load()
    MSComm1.CommPort = 1
    MSComm1.Settings = "9600,n,8,1"
    MSComm1.RThreshold = 1
    MSComm1.InputLen = 0
    MSComm1.InputMode = comInputModeText
End Sub
Private Sub MSComm1_OnComm()
    Dim strData As String
    Dim intPos As Integer
        Select Case MSComm1.CommEvent
         Case comEvReceive
            strData = MSComm1.Input
            strBuffer = strBuffer & strData
    
        intPos = InStr(strBuffer, vbCr)
        If intPos <> 0 Then
            txtScale.Text = Mid(strBuffer, 1, intPos - 1)
            strBuffer = ""
            MSComm1.PortOpen = False
        End If
    End Select
End Sub
Many thanks for all the help

Last edited by DougT; 11-22-2007 at 11:37 PM.
Reply With Quote
  #16  
Old 11-22-2007, 10:51 AM
the master's Avatar
the master the master is offline
Tachikoma
 
Join Date: Mar 2003
Location: Mansfield, UK
Posts: 4,596
Default

Code tags work the same as all the others using square brackets around "CODE" and "/CODE"

Why dont you try opening the port right after you set the settings in form_load then close it in form_unload. Not sure if it will help but its what i always do
__________________
"That which seems simple is often overlooked" ~ me
Halloween 2014 Yard Haunt
Halloween Special FX
Reply With Quote
  #17  
Old 11-22-2007, 11:31 AM
AlexanderJames AlexanderJames is offline
Junior Contributor
 
Join Date: Sep 2005
Posts: 382
Default

Hi The Master

Thank you i tried as you suggested and i also saw that my code for cmdGetData was incorrect, but i still get an @B when i click the button and only apon the third or fourth click does the correct data come through. I'm starting to pull my hair out with this scale.

Private Sub cmdGetData_Click()[CODE]
' Open the port and request a measurement
MSComm1.PortOpen = True
txtScale.Text = intPos
End Sub[CODE]

I think it should be like this. Hope i got the code tags correct.

AJ
Reply With Quote
  #18  
Old 11-22-2007, 11:52 AM
the master's Avatar
the master the master is offline
Tachikoma
 
Join Date: Mar 2003
Location: Mansfield, UK
Posts: 4,596
Default

The closing tag has a slash before it [ /CODE ] (without spaces)

Im not sure about the sub you posted. From what i can see you need to send a command to the device then the device will reply. In form_load you should setup everything as you are now then right at the end of that sub open the port. in form_unload you close the port. When you click your command button you should just send the command you want (dont open or close the port here)
__________________
"That which seems simple is often overlooked" ~ me
Halloween 2014 Yard Haunt
Halloween Special FX
Reply With Quote
  #19  
Old 11-22-2007, 12:13 PM
AlexanderJames AlexanderJames is offline
Junior Contributor
 
Join Date: Sep 2005
Posts: 382
Default

Hi

I tried that exactly they way you suggested, but then i get no data through at all. I think i should go and study some rocket science in order to code this blasted scale LOL. Do you have anything else i could try, all your suggestions are very much appreciated.

Thanks
AJ
Reply With Quote
  #20  
Old 11-22-2007, 12:17 PM
the master's Avatar
the master the master is offline
Tachikoma
 
Join Date: Mar 2003
Location: Mansfield, UK
Posts: 4,596
Default

Hmm. Im not sure what else to try. If you upload your project ill give it a test. What format are the commands in? Both to and from the device. Ill program a PIC to mimic your device
__________________
"That which seems simple is often overlooked" ~ me
Halloween 2014 Yard Haunt
Halloween Special FX
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
Mscomm1 Advice Please
Mscomm1 Advice Please
Mscomm1 Advice Please Mscomm1 Advice Please
Mscomm1 Advice Please
Mscomm1 Advice Please
Mscomm1 Advice Please Mscomm1 Advice Please Mscomm1 Advice Please Mscomm1 Advice Please Mscomm1 Advice Please Mscomm1 Advice Please Mscomm1 Advice Please
Mscomm1 Advice Please
Mscomm1 Advice Please
 
Mscomm1 Advice Please
Mscomm1 Advice Please
 
-->