How to solve System.Timeout.Exception on a PBX SMDR Capture app?
The port connection is successful but when it gets to receive data I get this timeout exception. Got no idea what to do...what to fix. Need help.
System.TimeoutException: The operation has timed out.
at System.IO.Ports.SerialStream.Read(Byte[] array, Int32 offset, Int32 count, Int32 timeout)
at System.IO.Ports.SerialStream.Read(Byte[] array, Int32 offset, Int32 count)
at System.IO.Ports.SerialPort.InternalRead(Char[] buffer, Int32 offset, Int32 count, Int32 timeout, Boolean countMultiByteCharsAsOne)
at System.IO.Ports.SerialPort.ReadTo(String value)
at System.IO.Ports.SerialPort.ReadLine()
at SMDR_Capture.SerialPortDataReceive.ReadFromCom() in e:\punn\my documents\visual studio 2010\Projects\SMDR Capture\SMDR Capture\SMDR Capture.vb:line 165
Below you have the Visual Basic.NET 2010 project solution in .doc (word 2003) file.
Don't know how to put code here in tags thus I had to manage with an attachment if you happen not see any attachment I'll manage another way of uploading a link and post in comment.
Re: How to solve System.Timeout.Exception on a PBX SMDR Capture app?
To put code in code tags you either use the # icon on the advanced editor or you simply type them in around your code like it shows in my signature.
Without having sow the code I would say that the most likely issue is that you are telling it to read from the port without first checking to see if there is anything there to read.
You also may want to look at your readtimeout setting on the serialport object in your code.
Last edited by DataMiser; February 8th, 2012 at 12:19 PM.
Re: How to solve System.Timeout.Exception on a PBX SMDR Capture app?
The code is already uploaded in an attachment...and for my account I don't see any advanced editor so I can put #before code so that it can generate a code view...I previously had review of people who commented in my post regarding not proper code post so I chose to upload it in attachment and beside the code is a bit long. Its virus/trojan/malware free doc, word file I guarentee 100%. Yeah I did the .ReadTimeout = 11000 more than the BaudRate (9600) but still I was getting that error...as for the other opinion i really havent got an idea how to...
Re: How to solve System.Timeout.Exception on a PBX SMDR Capture app?
As to your issue, I notice in the error message you are using readline() this may result in an error if the newline character is not received within the timeout period even if there was data there to read as it will try to read up to a newline character which is by default a line feed character CHR(10)
Re: How to solve System.Timeout.Exception on a PBX SMDR Capture app?
Ok here we go.
Code:
Imports System
Imports System.IO.Ports
Imports System.Threading
Imports System.Threading.Thread
Imports System.Runtime.InteropServices
Imports System.ComponentModel
Public Class SerialPortDataReceive
#Region "SerialPort"
Dim RS232 As New SerialPort
Dim readThread As Thread = New Thread(AddressOf ReadFromCom)
Dim abortThread As Boolean
Private Sub ProgramClosing(ByVal sender As Object, ByVal e As ComponentModel.CancelEventArgs) Handles MyBase.Closing
If MessageBox.Show("Do you really want to close the window?", "SMDR Capture", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.No Then
e.Cancel = True
Else
' Close COM port on a new thread when the form is terminated with [X]
Dim t As New Thread(AddressOf ClosePort)
t.Start()
End If
End Sub
Private Sub ClosePort()
If RS232.IsOpen = True Then RS232.Close()
End Sub
'Private Sub SerialPortDataReceive_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
' If MessageBox.Show("Do you really want to close the window", "SMDR Capture", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.No Then
' e.Cancel = True
' Else
' ' Close COM port on a new thread when the form is terminated with [X]
' If RS232.IsOpen = True Then
' RS232.Close()
' End If
' End If
'End Sub
Private Sub SerialPortDataReceive_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
For Each COMPort As String In My.Computer.Ports.SerialPortNames
cmbPort.Items.Add(COMPort)
Next
'Filling combo box Baud Rate with exact numbers predefined earlier. (Mbush combo box-in e Baud Rate me numra ekzakte te paradefinuara.)
cmbBaud.Items.Add("2400")
cmbBaud.Items.Add("4800")
cmbBaud.Items.Add("7200")
cmbBaud.Items.Add("9600")
cmbBaud.Items.Add("19200")
cmbBaud.Items.Add("38400")
cmbBaud.Items.Add("57600")
'Filling combo box Parity with exact values predefined earlier. (Mbush combo box-in e Parity me vlera ekzakte te paradefinuara.)
cmbParity.Sorted = True
cmbParity.Items.Add("None")
cmbParity.Items.Add("Odd")
cmbParity.Items.Add("Even")
cmbParity.Items.Add("Mark")
cmbParity.Items.Add("Space")
'Filling combo box Data Bits with exact values predefined earlier. (Mbush combo box-in e Data Bits me vlera ekzakte te paradefinuara.)
cmbData.Sorted = True
cmbData.Items.Add("8")
cmbData.Items.Add("7")
cmbData.Items.Add("6")
cmbData.Items.Add("5")
cmbData.Items.Add("4")
'Filling combo box Stop Bits with exact values predefined earlier. (Mbush combo box-in e Stop Bits me vlera ekzakte te paradefinuara.)
cmbStop.Sorted = True
cmbStop.Items.Add("None")
cmbStop.Items.Add("1")
cmbStop.Items.Add("1.5")
cmbStop.Items.Add("2")
cmbPort.SelectedIndex = 0
cmbBaud.SelectedIndex = 3
cmbParity.SelectedIndex = 2
cmbData.SelectedIndex = 4
cmbStop.SelectedIndex = 0
'RS232 = srpPBX
'With RS232
' .PortName = "COM16"
' .BaudRate = 9600
' .Parity = Parity.None
' .DataBits = 8
' .StopBits = 1
' .ReadTimeout = 500
' .DtrEnable = True
'End With
End Sub
Private Sub btnOpenClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOpenClose.Click
If cmbPort.SelectedItem = True Then
Try
If btnOpenClose.Text Is "Open" Then
If chkbDTR.Checked = True AndAlso chkbRTS.Checked = True Then
RS232 = srpPBX
RS232.PortName = cmbPort.Text()
RS232.BaudRate = CInt(cmbBaud.Text)
RS232.Parity = CType([Enum].Parse(GetType(Parity), cmbParity.Text), Parity)
RS232.DataBits = CInt(cmbData.Text)
RS232.StopBits = CInt(cmbStop.Text)
RS232.ReadTimeout = 11000
RS232.DtrEnable = True
RS232.RtsEnable = True
RS232.Open()
abortThread = False
readThread.Start()
btnOpenClose.Text = "Close"
tltPBX.SetToolTip(btnOpenClose, "Close communication")
txtReceive.ReadOnly = True
lblStatus.Text = "Connection succesfully opened on " & RS232.PortName & "."
cmbPort.Enabled = False
cmbBaud.Enabled = False
cmbParity.Enabled = False
cmbData.Enabled = False
cmbStop.Enabled = False
ElseIf MessageBox.Show("You haven't checked DTR and RTS which results no received data!", "SMDR Capture", MessageBoxButtons.RetryCancel, MessageBoxIcon.Warning) = Windows.Forms.DialogResult.Retry Then
chkbDTR.Checked = True
chkbRTS.Checked = True
End If
ElseIf btnOpenClose.Text = "Close" Then
Try
RS232.Close()
abortThread = True
btnOpenClose.Text = "Open"
tltPBX.SetToolTip(btnOpenClose, "Open communication")
txtReceive.ReadOnly = False
lblStatus.Text = "Connection succesfully closed on " & RS232.PortName & "."
cmbPort.Enabled = True
cmbBaud.Enabled = True
cmbParity.Enabled = True
cmbData.Enabled = True
cmbStop.Enabled = True
Catch ex As Exception
MsgBox(ex.Message & vbCritical)
End Try
End If
Catch ex As Exception
MsgBox("Another program is already using " & cmbPort.Text() & vbCrLf & vbCrLf & _
"Please try again later", MsgBoxStyle.OkOnly + MsgBoxStyle.Information, cmbPort.Text() & " is not available")
End Try
Else
MessageBox.Show("You haven't selected any of the available ports or process terminated since there is no available port!", "Parameter Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
End If
End Sub
Public Sub ReadFromCom()
While abortThread = False
Try
Dim message As String = RS232.ReadLine
updateStatus("Received: " & message)
Catch ex As TimeoutException
updateStatus(ex.ToString)
End Try
End While
End Sub
Public Delegate Sub updateStatusDelegate(ByVal newStatus As String)
Public Sub updateStatus(ByVal newStatus As String)
If Me.InvokeRequired Then
Dim upbd As New updateStatusDelegate(AddressOf updateStatus)
Me.BeginInvoke(upbd, New Object() {newStatus})
Else
Try
txtReceive.Text = newStatus & vbCrLf & vbCrLf & txtReceive.Text
My.Computer.FileSystem.WriteAllText("C:\Users\Punn\Desktop\SMDR_Error_Log.txt", txtReceive.Text, True)
Catch ex As Exception
MsgBox(ex.Message & vbCritical)
End Try
End If
End Sub
#End Region
#Region "Initializations"
Private Sub txtReceive_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtReceive.TextChanged
End Sub
Private Sub lblPort_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lblPort.Click
End Sub
Private Sub lblBaud_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lblBaud.Click
End Sub
Private Sub lblParity_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lblParity.Click
End Sub
Private Sub lblData_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lblData.Click
End Sub
Private Sub lblStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lblStop.Click
End Sub
Private Sub cmbPort_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbPort.SelectedIndexChanged
End Sub
Private Sub cmbBaud_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbBaud.SelectedIndexChanged
End Sub
Private Sub cmbParity_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbParity.SelectedIndexChanged
End Sub
Private Sub cmbData_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbData.SelectedIndexChanged
End Sub
Private Sub cmbStop_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbStop.SelectedIndexChanged
End Sub
Private Sub chkbDTR_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkbDTR.CheckedChanged
End Sub
Private Sub chkbRTS_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkbRTS.CheckedChanged
End Sub
Private Sub lblEvents_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lblEvents.Click
End Sub
Private Sub grbConn_Enter(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles grbConn.Enter
End Sub
Private Sub grbReceived_Enter(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles grbReceived.Enter
End Sub
Private Sub msSerialPortDataReceive_ItemClicked(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ToolStripItemClickedEventArgs) Handles msSerialPortDataReceive.ItemClicked
End Sub
Private Sub OpenToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OpenToolStripMenuItem.Click
End Sub
Private Sub SaveToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SaveToolStripMenuItem.Click
End Sub
Private Sub ExitToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExitToolStripMenuItem.Click
If MessageBox.Show("Do you really want to close the window", "SMDR Capture", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then
Dim t As New Thread(AddressOf ClosePort)
t.Start()
Application.Exit()
'Else
' Dim e1 As ComponentModel.CancelEventArgs
' e1.Cancel = True
' Close COM port on a new thread when the form is terminated with [X]
End If
End Sub
Private Sub AboutToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AboutToolStripMenuItem.Click
Dim F As New frmAbout
F.Show()
End Sub
Private Sub lblStatus_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lblStatus.Click
End Sub
Private Sub timerStatus_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles timerStatus.Tick
Try
If RS232.IsOpen Then
lblStatus.Text = ""
Else
lblStatus.Text = ""
End If
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Exclamation, Me.Text)
End Try
End Sub
#End Region
End Class
Yeah I used readline() to read from serialport and no the data receive is not in the DataReceived Event of the SerialPort. Try a new project with this code and tell me how can you fix the error please. I'd be thankful to your kindness. =)
Re: How to solve System.Timeout.Exception on a PBX SMDR Capture app?
2 Things,
1: does the data being sent have line feeds?
2: You should be using the datareceived event of the serialport class and reading your data there.
Really I see no need for a second thread. I have did tons of serial based apps and never had an issue that would require a second thread.
Basically either use the data received event which will cause your program to only try to read data when data is there to read or optionally you could use a timer and poll the port using the btyestoreceive property to see if anything is waiting to be read and execute a read when this value >0
As is if you open the port you try to read never checking to see if anything is there or even if there is anything actually connected to the port, Your code will then try to read until it is closed by the user or gives up and throws an error.
Re: How to solve System.Timeout.Exception on a PBX SMDR Capture app?
The data sent doesn't have either LF or CR+LF...as for DataReceived Event should I write the readline code with the thread inside of it or should I completely drop that code down and write something else in DataReceived Event...I'm very new to this field of telephone/PBX/serialport programming thus it's hard to understand what I am supposed to do next. I'd be thankful if you can show me in code example of how you would write or manage to check if there's something to read in the port.
I did run my application today worked fine in the very first seconds of communication and it showed me this result : Received: 2/ 8/12 6:52PM 102 01 00491623746564 00:00'29" ....
but after that the same System.TimeoutException...
Re: How to solve System.Timeout.Exception on a PBX SMDR Capture app?
For starters I would comment out this line
Code:
readThread.Start()
I would then add in the datareceived event of the serial port
Code:
Dim strMessage As String = RS232.ReadLine
txtReceive.Text = strMessage & vbCrLf & vbCrLf & txtReceive.Text
This may be fine but since there is no LF characters in your transmission it may not.
The other option is to use Read() instead of readline()
Read will require a bit more code since it returns a byte array rather than a string and will need to be converted before it is displayed.
Re: How to solve System.Timeout.Exception on a PBX SMDR Capture app?
I've made a research over the internet about Port.Read() method and made conversation to UTF-8(65001) and made few breakpoints where I thought I must and Debugged(F5) or Step Over(F10) and I saw there were 0 bytes in the buffer to read but I'm sure there are bytes to read since with Terminal or other application that I'm testing it shows me the log, caller id and etc etc stuff like that.
And here is my code to the DataReceived event of my serial port but there is a problem I don't know what to do, how to fire that event. I have a button designated to open the communication which after it opens sets the boolean value of SndRcv = True whereas in DataReceived event I made a While loop about that true/false statement of that bool obj.
I've completely removed the lines with .ReadLine and remove unnecessary threads.
Code below:
Code:
Private Sub srpPBX_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles srpPBX.DataReceived
'This event will Receive the data from the selected COM port..
Dim bRead, nRead As Integer ' Dim returnStr As String = ""
Dim ascStr As String = ""
Dim cData(bRead - 1) As Byte
While SndRcv = True
If e.EventType = System.IO.Ports.SerialData.Chars Then
RS232.Encoding = System.Text.Encoding.GetEncoding(65001)
bRead = RS232.BytesToRead 'Number of Bytes to read
nRead = RS232.Read(cData, 0, bRead) 'Reading the Data
For Each b As Byte In cData
ascStr += Chr(b) 'Ascii String
Next
txtReceive.Text = ascStr & vbCrLf & vbCrLf & txtReceive.Text
My.Computer.FileSystem.WriteAllText("C:\Users\Punn\Desktop\SMDR_New_Log.txt", txtReceive.Text, True)
RaiseEvent DataRecieved(ascStr)
End If
End While
End Sub
So what's left is how to fire this event after the connection is successful?
Re: How to solve System.Timeout.Exception on a PBX SMDR Capture app?
There is nothing you need to do to fire the event. This event is controled by the property ReceivedBytesThreshold by default this is set to 1. The event will fire when at leaset this many bytes have been receive through the open port and only when this happens.
As for your new code there should not be a loop there. The event will fire when data is received. Your loop will just be a problem.
There is a single method to convert a byte array to a string so no need for that other loop that sets the characters either.
See Encoding.GetString()
The raiseevent statement should not be there either
It is really very simple. In your data received event you should have code to
Read the data that has just been received
If reading into a byte array then use the encoding class to convert that array to a string.
Do something with that string
This will happen each time data is received. No need to loop or call the event it will know when it is time.
When you want to stop receiving data you close the port.
Re: How to solve System.Timeout.Exception on a PBX SMDR Capture app?
Ok I think this is end I can get so far...but I don't get any result in my textbox...I removed the unnecessary loops and every other triggering just made the read data code into DataReceived.
Can you help me a little bit more...
Previous properties are : ReceivedDataThreshold = 1, DTR and RTS enabled and ReadTimeout = 500 (ms). When I run the other applications they show me data in the txtbox...but with the code I have no error but no result aswell...
Code:
Private Sub srpPBX_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles srpPBX.DataReceived
'This event will Receive the data from the selected COM port..
Dim n As Integer = RS232.BytesToRead()
Dim comBuffer As Byte() = New Byte(n - 1) {}
Dim BytesReceived As Integer
Try
BytesReceived = RS232.Read(comBuffer, 0, n)
If BytesReceived > 0 Then
txtReceive.Text = txtReceive.Text + System.Text.Encoding.ASCII.GetString(comBuffer)
'My.Computer.FileSystem.WriteAllText("C:\Users\albann\Desktop\SMDR_New_Log.txt", txtReceive.Text, True) output to a txt file for later use.
End If
Catch ex As Exception
MessageBox.Show("Error: " & ex.Message, ex.Source, MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Re: How to solve System.Timeout.Exception on a PBX SMDR Capture app?
Looks much better but I am a bit confused by your naming in the code.
Code:
Private Sub srpPBX_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles srpPBX.DataReceived
'This event will Receive the data from the selected COM port..
Dim n As Integer = RS232.BytesToRead()
Dim comBuffer As Byte() = New Byte(n - 1) {}
Dim BytesReceived As Integer
Try
BytesReceived = RS232.Read(comBuffer, 0, n)
If BytesReceived > 0 Then
txtReceive.Text = txtReceive.Text + System.Text.Encoding.ASCII.GetString(comBuffer)
'My.Computer.FileSystem.WriteAllText("C:\Users\albann\Desktop\SMDR_New_Log.txt", txtReceive.Text, True) output to a txt file for later use.
End If
Catch ex As Exception
MessageBox.Show("Error: " & ex.Message, ex.Source, MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
If your SerialPort is named srpPBX then this is what you need to read from.
If your serial port is named RS232 then this is what you need to handle the datareceived event for.
As is you are trying to read from a port named RS232 when data is received on a port named srpPBX. Clearly the result will not be what you are looking for.
Also I am a little confused by this line
Code:
Dim comBuffer As Byte() = New Byte(n - 1) {}
You do not need to specify the size and I have no idea why the {} is there.
Re: How to solve System.Timeout.Exception on a PBX SMDR Capture app?
I thought that too but wanted a confirmation from your reading of code...but I have an initialization up in my button click event where RS232 = srpPBX...and what do you suggest about byte I have to just simply Dim comBuffer as Byte and nothing else?
Re: How to solve System.Timeout.Exception on a PBX SMDR Capture app?
Code:
Dim ComBuffer() As Byte
Why are you setting RS232=srpBPX?
I see code that defines RS232 as a New SerialPort which is fine.
then you have code that sets RS232=srpPBX ??
srpPBX is not defined in the code that I can see. What is it?
All you have to do is
1: drag the serialport from the toolbox to the form
2: Give it a name if you like
3: Add some code for the settings if you like
4: Add some code somewhere to open and close the port
5: Select the serial port you added from the drop down on the left in the code editor
6: Choose datareceived from the drop down on the right
7: Add the code to receive the data.
Bookmarks