Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Sending and Receiving data using Mscomm

Status
Not open for further replies.

lexer

Programmer
Jun 13, 2006
432
VE
Hi

I'm trying to make a VB program for interacting with a Nortel PBX through a serial port.
First What I've got to see the PBX port status, For This send a CrLf to the PBX and wait for the response, If the port is free I will receive "OVL111" + CrLf. If I receive OVL111 I can send a user and a password to the PBX.
I also want to show the receive data on a RechTextBox, below is the program for detecting the "OVL111" word:


Dim Buffer As String
Dim Varix As String
Private Sub Command1_Click()
MSComm1.Output = vbCrLf
End Sub

Private Sub Form_Load()
MSComm1.InputLen = 0 ' Read All
MSComm1.RThreshold = 1
MSComm1.CommPort = 2 'COM 2
MSComm1.PortOpen = True
End Sub
Private Sub MSComm1_OnComm()
Dim pos As Integer
Select Case MSComm1.CommEvent
Case comEvReceive
Buffer = MSComm1.Input
'Show received data from the PBX on RichtextBox
'RichTextBox1.SelStart = Len(RichTextBox1.Text)
'RichTextBox1.SelText = Buffer
Varix = Varix + Buffer
'If Arrive CrLF then look for OVL111
If Right(Varix, 2) = vbCrLf Then
pos = InStr(Varix, "OVL111")
If pos > 0 Then 'If pos > 0 then I found OVL111
Print "Found OVL111" 'Print the data colected
Print Varix
Varix = ""
End If
End If
End Select
End Sub


If I show the received data on the ReichTextBox using:

RichTextBox1.SelStart = Len(RichTextBox1.Text)
RichTextBox1.SelText = Buffer

I have to click several times Command1_Click() for detecting OVL111.
If I don't show the receive data in the RichTextBox the program found OVL111 at once

Any ideas?
 
Whenever you read the mscomms, you only read what has been received in the buffer.
As modern computers are much faster than baud rates, the whole read process can often occur before the whole message has been sent.
So sending "Hello there" you might get it in 4 chunks
"Hell"
"o t"
"her"
"e"

This is probably why you have to click a number of times.

You have to collect the data in a loop
MyBuffer=MyBuffer & NewData so that MyBuffer becomes
"Hell"
"Hello t"
"Hello ther"
"Hello there"

Here is one I did

Dim Buffer1 '(in declarations)

Private Sub MSComm1_OnComm()
'receive data from Device
If MSComm1.CommEvent = 2 Then
Buffer1 = Buffer1 & MSComm1.Input 'store current contents of comms1 buffer in Buffer1 a few bytes at a time
If InStr(Buffer1, vbCrLf) Then
ProcessData Buffer1 (next sub to process data)
Buffer1 = "" 'Got it all so clear it for next time
End If
End If
End Sub

Each packet of data ends with VBCRLF then goes to the Sub ProcessData(Buffer as string) to handle the received data.

Maybe you could subsitiute your characters in the Instr if that is all you want or detect it later
 
Thanks tedsmith

I changed my program following your code and I can detect when the PBX port is free "OVL111". Now I want to send the user ID to the PBX and then the password.
To send the User ID to PBX, I have to send "LOGI ADMIN1" the PBX has to answer "PASS?". The program below should do the following:
*When I click Command2_Click(), I send "*" to PBX
*If The PBX port is free I will see "OVL111" (This work fine)
*When I detect OVL111, I enable Timer1 for waiting 1 second
*In Timer1 private sub I send the user ID to the PBX "LOGI ADMIN1" (When I send LOGI ADMIN1 to the PBX, the PBX sees more caracters, because I receive a PBX messaging telling me that Login name and password combination is invalid)

Dim text As Variant
Private Sub Form_Load()
MSComm1.InputLen = 0 ' Read all in the port
MSComm1.RThreshold = 1
MSComm1.CommPort = 2 'Port 2
MSComm1.PortOpen = True '
End Sub
Private Sub Command2_Click()
text = "*" & vbCrLf
MSComm1.Output = text
End Sub
Private Sub MSComm1_OnComm()
Dim Buffer As String
Dim pos As Integer
Dim Vari As String
Select Case MSComm1.CommEvent
Case comEvReceive
Buffer = Buffer & MSComm1.Input
RichTextBox1.SelStart = Len(RichTextBox1.text)
RichTextBox1.SelText = Buffer
If InStr(Buffer, vbCrLf) Then
Vari = Buffer
Call ProcessData(Vari)
Buffer = "" 'Got it all so clear it for next time
End If
End Select
End Sub
Private Sub ProcessData(Vari As String)
If Right(Vari, 6) = "OVL111" Then
Print "OVL111 Found"
Buffer = ""
Timer1.Interval = 1000
Timer1.Enabled = True
End If
If Right(Vari, 5) = "PASS?" Then
Print "PASS Found" 'It never detects PASS
End If
End Sub

Private Sub Timer1_Timer()
text = "LOGI ADMIN1" & vbCrLf
MSComm1.Output = text
End Sub

Any Ideas?
 
Hi

Trying I noted that I can detect OVL111 because the PBX sends OVL111 after the message: TTY 01 SCH CTY 16:48
I receive, So the whole message the PBX sends is:

TTY 01 SCH CTY 16:48
OVL111 BKGD 44

I made a program for detecting when I already login, If I already login and I send "*" + VBCr, The PBX has to answer with: "OVL000"
But I receive:
"OVL0"
"00"

This the program:

Dim text As String
Private Sub Command2_Click()
Cls
text = "*" & vbCrLf
MSComm1.Output = text
End Sub
Private Sub Form_Load()
MSComm1.InputLen = 0 ' Read all in the port
MSComm1.RThreshold = 1
MSComm1.CommPort = 1 'Port 1
MSComm1.PortOpen = True '
End Sub
Private Sub MSComm1_OnComm()
Dim Buffer As String
Dim pos As Integer
Dim Vari As String
Select Case MSComm1.CommEvent
Case comEvReceive
Buffer = Buffer & MSComm1.Input
RichTextBox1.SelStart = Len(RichTextBox1.text)
RichTextBox1.SelText = Buffer 'Show data on RechTextBox
If InStr(Buffer, vbCr) Then 'If I detect VbCr
Vari = Buffer
Call ProcessData(Vari) 'Goto Procress Data
End If
End Select
End Sub
Private Sub ProcessData(Vari As String)
Print Vari
If InStr(Vari, "OVL000") Then 'If A Detect OVL000 Goto Logout to PBX
Print "Root Menu"
Call logo
Buffer = ""
End If
End Sub
Private Sub logo()
texto = "LOGO" + vbCr 'Send Logout to PBX
MSComm1.Output = texto
End Sub

Mscomm is program at 9600,n,8,1. If I use this program in another (slower PC Pentium III), I receive the whole message:
"OVL000"
How can I do for reading the whole word in a faster PC?
 
One of you problems is that you seem to be assuming that your variable [tt]buffer[/tt] retains it's value between calls of the OnComm event. But you'd need to declare it as Static within the event, or declare it as a global at the form or module level, for this to be the case. Without making this change, [tt]buffer[/tt] will only ever hold whatever is in MSComm's input buffer at the time OnComm is raised.
 
For this reason, in my original example I had the Dim Buffer at the head of the form so it is not erased every time the Mscomm fires.

It is important that erase the Buffer(="") in the end of the Processdata Sub after you have used the data so that the next packet starts with a blank buffer.

Also it is possible sometimes to get errors that will lock out any further valid reads or end up with a huge buffer so have as below: This can be because of corruption such as plugging in the device when the app is running,interference or a wrong baud rate etc

Private Sub MSComm1_OnComm()
On Error goto HandleErrors

Put your routine here . . . .

If Len(Buffer)>20 then Buffer="" 'make this actual value a bit bigger than maximum normally expected

Exit Sub

HandleErrors:
Buffer=""
Resume next

End Sub

Also have a few active statements as possible in the Sub OnComm so it runs as fast as possible. Do all the work in the ProcesData Sub.
 
One thing I have found that works well is to create a loop in the MSComm1_OnComm() procedure that watches the size of the buffer of MSCommm1 and doesn't pull the MSComm1.Input until the buffer stops growing. This may be the only way when you don't have a delimiter, CR, or LF to depend on. Timing is a huge thing to think through in your head to code effectively because every computer may run faster or slower than the computer you are developing on.

Another thing to keep in mind when sending data to a device is your send threshold on MSComm1. Set it appropriately so it sends your entire string.



Creator of - Movie Reviews, Movie Lists, and much more!
 
I hadn't though of that one but it wouldn't work unless there was a reasonable gap between packets. Sometimes the data keeps coming without a break.
You could allow for different computers by adjusting your delay time to how fast your computer was by executing a big dummy loop on startup and counting the milliseconds to do it.

I had a problem once with no end delimiter but the microprocessor device kept sending a string with the same unique start character (a semicolon) so I had to use that as a convoluted reference instead.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top