vb.net SerialPort writing and receiving - vb.net

I have an issue with reading the results of a serialport communication.
If have multiple functions, which are executing different commands on my device and also receiving and process the sent results on slightly different ways.
If i call the functions all at once, its not working 100% reliable. If i call only one of these functions, all of them working perfectly. Im assuming, thinks going a little to fast for the slow serialPort communication, so some functions dont get propper results when calling all "at once"
Code which calls 3 functions (Error on different Positions: "Index out of (array) range" or "CRC incorrect")
Private Sub btn_initialize_Click(sender As Object, e As EventArgs) Handles btn_initialize.Click
Dim actual_mw As Double
Dim attenuated As Integer
'open (virtual)COMport
If rfid.init_serialport(cb_com.SelectedItem.ToString) = True Then
flp_data.Visible = True
lbl_snr_data.Text = rfid.get_serial_number()
lbl_type_data.Text = rfid.get_reader_type
Dim collection As MatchCollection = Regex.Matches(rfid.get_attennuation, "\d+")
attenuated = collection(1).Value
If attenuated = 0 Then
lbl_leistung_data.Text = "100mW / 100mW"
Else
actual_mw = 100 - (10 ^ (attenuated / 10))
lbl_leistung_data.Text = Math.Round(actual_mw, 2) & "mW / 100mW"
End If
Else
MsgBox("Error! COM-Schnittstelle konnte nicht initialisiert werden!", MsgBoxStyle.Critical, "Error")
End If
End Sub
Intialize and Dispose SerialPort
Public Class RFE
Private RF_CHECKSUM As Byte
Private device_output() As Byte
Private data() As Byte
Private device_input() As Byte
Private sp As SerialPort
Public Function init_serialport(portName As String) As Boolean
Try
sp = New SerialPort
sp.PortName = portName
sp.BaudRate = 9600
sp.Parity = Parity.None
sp.DataBits = 8
sp.StopBits = StopBits.One
sp.Handshake = Handshake.None
sp.ReadTimeout = 500
sp.WriteTimeout = 500
sp.Open()
If sp.IsOpen Then
Return True
Else
Return False
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Function
Public Function disp_serialport()
Try
sp.Dispose()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Function
Functions
Public Function get_serial_number() As String
Try
Dim serial_number As String
ReDim data(8)
data(0) = RF_START_BYTE0
data(1) = RF_START_BYTE1
data(2) = RF_START_BYTE2
data(3) = RF_COMMAND_START_BYTE
data(4) = RF_READER_COMMON
data(5) = RF_GET_SERIAL_NUMBER
data(6) = RF_LENGTH_START_BYTE
data(7) = &H0
data(8) = RF_CHECKSUM_START_BYTE
RF_CHECKSUM = Hex(calc_xor(data, 1))
device_input = data
Array.Resize(device_input, data.Length + 1)
device_input(9) = "&H" & RF_CHECKSUM
sp.Write(device_input, 0, device_input.Length)
ReDim device_output(sp.BytesToRead)
sp.Read(device_output, 0, device_output.Length - 1)
If calc_xor(device_output, 3) <> device_output(14) Then
MsgBox("CRC incorrect!", MsgBoxStyle.Critical, "Error")
Form1.Close()
End If
serial_number = Hex(device_output(9)).PadLeft(2, "0") & "-" & Hex(device_output(10)).PadLeft(2, "0") & "-" & Hex(device_output(11)).PadLeft(2, "0") & "-" _
& Hex(device_output(12)).PadLeft(2, "0")
device_output = Nothing
data = Nothing
RF_CHECKSUM = Nothing
sp.DiscardInBuffer()
sp.DiscardOutBuffer()
Return serial_number
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Function
The other functions are structure-vise the same, only the sent bytes and the processing of the result is slightly different.
As I said, im assueming the problem is the transaction of the signals (possibly in both directions) so the SerialPort and/or Device cant handle things fast enough.
What do I have to do so that the communication runs reliably/sequentially?
Maybe DataReceivedHandler could fix the Problem? But for every function I call, the processing of the result is different, how do I implement this in the DataReceivedHandler then (if the Handler could fix the Problem)?
Thank you all!

Related

How to call the result of a function from a class in Vb.Net?

I would like to know how to call the result of a function that is in another class, in Visual Basic .Net, to then use that result for comparison in an if?
I want to call the result of the SubtractBalance function, specifically, if there is in it, I would like to have it in the class from where I want to call it(FRM_CashWithdrawal2).
I am simulating an ATM. Form FRM_CashWithdrawal2 calls two forms. One is for the impression of the receipt after the desired amount to be withdrawn is entered and the other is for the same procedure but without receipt in order to withdraw the money at the end. Otherwise, the program launches the Message: "Insufficient Funds." When I call the function in this way: oConnection.SubtractBalance (FRM_InsertCardID.TXB_CardID.Text), the SubtractBalance function is evaluated, when the fund is insufficient, it throws the message but also calls the previously mentioned forms. I wish that when you send the message: "Insufficient Funds", do not call those forms.
Thanks in advance.
Imports System.Data.SqlClient
Public Class FRM_CashWithdrawal2
Dim oConnection As New clsDBConnection
Private Sub BTN_Ok_Click(sender As Object, e As EventArgs) Handles BTN_Ok.Click
If TXB_Amount_to_Withdraw.Text.Length = 0 Then
MsgBox("You must fill the field.")
Return
End If
If TXB_Amount_to_Withdraw.Text = "0" Then
MsgBox("Enter the amount to withdraw.")
Return
End If
Dim intAmount As Integer
If Not Integer.TryParse(TXB_Amount_to_Withdraw.Text, intAmount) Then
MessageBox.Show("Please enter a value in the field.")
Return
End If
Select Case intAmount
Case > 10000
MsgBox("It is only possible to withdraw up to RD $ 10000.00 at ATMs.")
Return
End Select
Dim NumMultiple1 = intAmount Mod 100
Dim NumMultiple2 = intAmount Mod 200
Dim NumMultiple3 = intAmount Mod 500
Dim NumMultiple4 = intAmount Mod 1000
Dim NumMultiple5 = intAmount Mod 2000
oConnection.SubtractBalance(FRM_InsertCardID.TXB_CardID.Text)
If NumMultiple1 = 0 OrElse NumMultiple2 = 0 OrElse NumMultiple3 = 0 OrElse NumMultiple4 = 0 OrElse NumMultiple5 = 0 Then
Dim Answer = MessageBox.Show("Do you want to print a receipt?", "Print Receipt", MessageBoxButtons.YesNo)
If Answer = DialogResult.Yes Then
FRM_RemoveYourCard.Show()
Me.Hide()
Else
FRM_RemoveYourCard1.Show()
Me.Hide()
End If
Else
MsgBox("You can only make withdrawals on multiple tickets of RD $ 100.00, RD $ 200.00, RD $ 500.00, RD $ 1000.00 and RD $ 2000.00 pesos.")
End If
End Sub
End Class
Public Class clsDBConnection
Private _strUserDB As String
Private _strPassDB As String
Private _strNameDB As String
Private _strSRVName As String
Private _strConnection As String
Private adAdaptator As SqlDataAdapter
Private tbTable As DataTable
Private drRegister As SqlDataReader
Public strComando As String
Public _Error As Boolean
Public _Menssage As String
Public Sub New()
With ATMApp3.My.Settings
_strSRVName = .strNameSRV.ToString
_strNameDB = .strNameDB.ToString
_strUserDB = .strUserDB
_strPassDB = .strPassUserDB
End With
_strConnection = "Data Source=JOVALLES-PC\SQLSERVEREX;Initial Catalog=" & _strNameDB & ";User ID=" & _strUserDB & ";Password=" & _strPassDB
Try
Dim dbConnection As New System.Data.SqlClient.SqlConnection(_strConnection)
dbConnection.Open()
MsgBox("CONNECTED")
Catch ex As Exception
MsgBox("Error to connect due to: " + ex.ToString)
End Try
End Sub
Public Function Modify(ByVal pCard As String, ByVal pBalance As Integer) As String
Dim Output As String = "It was modified correctly."
Dim dbConnection As New System.Data.SqlClient.SqlConnection(_strConnection)
Dim cmd As New SqlClient.SqlCommand("up_modify_balance", dbConnection)
cmd.CommandType = CommandType.StoredProcedure
Try
If dbConnection.State = ConnectionState.Closed Then
dbConnection.Open()
End If
With cmd.Parameters
.AddWithValue("#Num_Card", pCard)
.AddWithValue("#Balance", pBalance)
End With
cmd.ExecuteNonQuery()
Catch ex As Exception
Output = "It was not modified due to:" + ex.ToString
dbConnection.Close()
End Try
Return Output
End Function
Public Function SubtractBalance(ByVal pCard As String) As SqlDataReader
Dim dbConnection As New System.Data.SqlClient.SqlConnection(_strConnection)
Dim cmd As New SqlClient.SqlCommand("up_consult_balance", dbConnection)
cmd.CommandType = CommandType.StoredProcedure
With cmd.Parameters
.AddWithValue("#Num_Card", pCard)
End With
Try
If dbConnection.State = ConnectionState.Closed Then
dbConnection.Open()
End If
drRegister = cmd.ExecuteReader
If drRegister.Read Then
Dim Subtract As Double
Dim CurrentBalance As Double = CStr(drRegistros("BALANCE_AVAILABLE"))
Subtract = (BalanceActual - FRM_CashWithdrawal2.TXB_Amount_To_Withdraw.Text)
If CurrentBalance < FRM_CashWithdrawal2.TXB_Amount_To_Withdraw.Text Then
MsgBox("Insufficient funds.")
Else
Modify(FRM_InsertCardID.TXB_CardID.Text, Subtract)
End If
Else
_Error = True
_Message = "There is not data"
dbConnection.Close()
Return Nothing
End If
Catch ex As Exception
MsgBox("It was not modified due to:" + ex.ToString)
dbConnection.Close()
End Try
End Function
End Class
I don't see the reason why your SubtractBalance function returns an SqlDataReader.
Instead I would recommend returning a boolean. True if they have money to withdrawal, false if not.
Then you could code it as...
If oConnection.SubtractBalance(FRM_InsertCardID.TXB_CardID.Text) Then
' Rest of processing code here processing
Else
' Tell them insufficient balance here
End If
If this isn't the answer you're looking for can you be more specific about the function return value that you wish to get?
Once a class is initialized, you can get the result of a public function by setting a variable to it's return:
'in a FRM_CashWithdrawal2 instance:
Dim result as SqlDataReader = oConnection.SubtractBalance(pCardString)
Hope it helps.

Function start doesn't return a value on all code paths. A null reference exception could occur at run time when the result is used

can you help its say's (Function 'Start' doesn't return a value on all code paths. A null reference exception could occur at run time when the result is used.)
Private Function Start() As Object
Dim thr As Integer = TextBox4.Text
Dim Threading As Integer = Nothing
If CheckBox1.Checked = True Then
Threading = thr + 300
Else
Threading = thr
End If
While Not stopp
Try
Try
Dim i As String = Geting("https://i.instagram.com/api/v1/users/search?q=" & TextBox5.Text & "&access_token=" & Guid.NewGuid.ToString.ToUpper & "/")
If i.Contains("""username"": """ & TextBox5.Text & """") Or Nothing Then
intt += 1
Me.Invoke(Sub() TextBox3.Text = intt)
Else
If ChangeUserName(TextBox5.Text) Then
Me.Invoke(Sub() Label1.Text = "username claimed " & TextBox5.Text)
stopp = True
End If
End If
Catch ex2 As Exception
End Try
Thread.Sleep(Threading)
Catch ex As Exception
End Try
End While
End Function
You probably don't need to return a value from your function. Change
Private Function Start() As Object
into
Private Sub Start()
As a side note, your error handling is bad.
Try
(Do something)
Catch Exception
End Try
should never be used. It prevents you from seeing when something goes wrong (even if your code has a flaw).

"Response received is incomplete"

So I reversed the syntax of this send sms code from c# to vb net so I can reuse it.
The code works sometimes, but for some reason it would often give me the "response received is incomplete" exception.
I was thinking perhaps my code is processing commands faster than my GSM device, could handle, so I tried increasing the timeout response for the serial port, still ends up with this exception.
What do you think is the problem and what would you recommend I do to solve it?
Public Class SmsHelper
Public receiveNow As AutoResetEvent
#Region "Open and Close Ports"
'Open Port
Public Function OpenPort(portName As String, baudRate As Integer, dataBits As Integer, readTimeout As Integer, writeTimeout As Integer) As SerialPort
receiveNow = New AutoResetEvent(False)
Dim port As New SerialPort()
Try
port.PortName = portName
'COM1
port.BaudRate = baudRate
'9600
port.DataBits = dataBits
'8
port.StopBits = StopBits.One
'1
port.Parity = Parity.None
'None
port.ReadTimeout = readTimeout
'300
port.WriteTimeout = writeTimeout
'300
port.Encoding = Encoding.GetEncoding("iso-8859-1")
port.NewLine = vbCrLf
AddHandler port.DataReceived, AddressOf port_DataReceived
port.Open()
port.DtrEnable = True
port.RtsEnable = True
Catch ex As Exception
Throw ex
End Try
Return port
End Function
' Send AT Command
Public Function SendATCommand(port As SerialPort, command As String, responseTimeout As Integer, errorMessage As String) As String
Try
port.DiscardOutBuffer()
port.DiscardInBuffer()
receiveNow.Reset()
port.Write(command & Convert.ToString(vbCrLf))
Dim input As String = ReadResponse(port, responseTimeout)
Console.WriteLine("Received data is " & input)
If (input.Length = 0) OrElse ((Not input.EndsWith(vbCr & vbLf & "> ")) AndAlso (Not input.EndsWith(vbCr & vbLf & "OK" & vbCr & vbLf))) Then
Throw New ApplicationException("No success message was received.")
End If
Return input
Catch ex As Exception
Throw ex
Finally
End Try
End Function
'Receive data from port
Public Sub port_DataReceived(sender As Object, e As SerialDataReceivedEventArgs)
Try
If e.EventType = SerialData.Chars Then
receiveNow.[Set]()
End If
Catch ex As Exception
Throw ex
End Try
End Sub
Public Function ReadResponse(port As SerialPort, timeout As Integer) As String
Dim serialPortData As String = ""
Try
Do
If receiveNow.WaitOne(timeout, False) Then
Dim data As String = port.ReadLine()
serialPortData += data
Else
'Console.WriteLine("SerialPortData data is " & serialPortData)
If serialPortData.Length > 0 Then
Console.WriteLine("SerialPortData is " & serialPortData.ToString)
Throw New ApplicationException("Response received is incomplete.")
Else
Throw New ApplicationException("No data received from phone.")
End If
End If
Loop While Not serialPortData.EndsWith(vbCr & vbLf & "OK" & vbCr & vbLf) AndAlso Not serialPortData.EndsWith(vbCr & vbLf & "> ") AndAlso Not serialPortData.EndsWith(vbCr & vbLf & "ERROR" & vbCr & vbLf)
Catch ex As Exception
Throw ex
End Try
Return serialPortData
End Function
Shared readNow As New AutoResetEvent(False)
Public Function SendMessage(port As SerialPort, phoneNo As String, message As String) As Boolean
Dim isSend As Boolean = False
Try
Dim recievedData As String = SendATCommand(port, "AT", 3000, "No phone connected")
Dim command As String = "AT+CMGF=1" + Char.ConvertFromUtf32(13)
recievedData = SendATCommand(port, command, 3000, "Failed to set message format.")
' AT Command Syntax - http://www.smssolutions.net/tutorials/gsm/sendsmsat/
command = (Convert.ToString("AT+CMGS=""") & phoneNo) + """" + Char.ConvertFromUtf32(13)
recievedData = SendATCommand(port, command, 3000, "Failed to accept phoneNo")
'wait(2)
command = message & Char.ConvertFromUtf32(26)
recievedData = SendATCommand(port, command, 3000, "Failed to send message")
Console.WriteLine("Received data is " & recievedData)
If recievedData.EndsWith(vbCr & vbLf & "OK" & vbCr & vbLf) Then
isSend = True
ElseIf recievedData.Contains("ERROR") Then
isSend = False
End If
Return isSend
Catch ex As Exception
Throw ex
End Try
End Function
Private Shared Sub DataReceived(sender As Object, e As SerialDataReceivedEventArgs)
Try
If e.EventType = SerialData.Chars Then
readNow.[Set]()
End If
Catch ex As Exception
Throw ex
End Try
End Sub
#End Region
End Class

Download Direct links

My program has been using:
Dim DLLink1 As String
DLLink1 = Trim(TextBox2.Text)
Dim DownloadDirectory1 As String
DownloadDirectory1 = Trim(TextBox4.Text)
Try
Button3.Enabled = False
' My.Computer.Network.DownloadFile(DLLink1, (DownloadDirectory1 + "/UpdatedClient.zip"))
Dim HttpReq As HttpWebRequest = DirectCast(WebRequest.Create(DLLink1), HttpWebRequest)
Using HttpResponse As HttpWebResponse = DirectCast(HttpReq.GetResponse(), HttpWebResponse)
Using Reader As New BinaryReader(HttpResponse.GetResponseStream())
Dim RdByte As Byte() = Reader.ReadBytes(1 * 1024 * 1024 * 10)
Using FStream As New FileStream(DownloadDirectory1 + "/UpdatedClient.zip", FileMode.Create)
FStream.Write(RdByte, 0, RdByte.Length)
End Using
End Using
End Using
Finally
MsgBox("Finished Download.")
Button3.Enabled = True
Label4.Visible = True
I tried this previously, and it didn't work at all:
My.Computer.Network.DownloadFile(DLLink1, (DownloadDirectory1 + "/UpdatedClient.zip"))
The website requires you to be logged in, so I made a spare account for the program:
WebBrowser1.Navigate("http://www.mpgh.net/forum/admincp/")
Timer1.Start()
Button2.Enabled = False
Then
WebBrowser1.Document.GetElementById("vb_login_username").SetAttribute("value", "AutoUpdaterAccount")
WebBrowser1.Document.GetElementById("vb_login_password").SetAttribute("value", "password")
Dim allelements As HtmlElementCollection = WebBrowser1.Document.All
For Each webpageelement As HtmlElement In allelements
If webpageelement.GetAttribute("type") = "submit" Then
webpageelement.InvokeMember("click")
Timer1.Stop()
Label5.Text = "Authorized."
Button2.Enabled = True
So now you're logged into the account, on the website, but when the code above to download runs, it downloads a zip, but it's corrupted. So I opened it with notepad++ and this is what I get (Does this mean it didn't login for the download, and it only logged in with the webbrowser and they aren't linked? Or something? Like My firefox logins aren't linked with chrome?:
The code is huge, it's like a HTML coding. Here is the link to a online notepad I put it on:
http://shrib.com/nCOucdfL
Another thing, a webbrowser can't be showing on the program, it can be on the outside not showing, like I did with the login. They also can't click the save button like on a normal web browser when a window pops up, I want it to download automatically to where they set it using a button which sets the directory as DownloadDirectory1
It must be your lucky day because today I woke up and decided that I would like to help you with your cause. I first tried to get the download to work with the web browser control but unfortunately I am sure this is not possible without extending the web browser control and we don't want to do that today.
As I mentioned in the comments, the only way I really know that this is possible (without user interaction) is to log in via the HttpWebRequest method. It's pretty tricky stuff. Definitely not for beginners.
Now I must admit that this isn't the cleanest, most "proper" and user-friendly code around, so if anyone wants to suggest a better way to do things, I am all ears.
I suggest you test this first before you incorporate it into your existing app. Just create a new vb.net app and replace all of the code in Form1 with the code below. You will have to update the usernamehere and passwordhere strings with your real username and password. Also, the file is saving to C:\file.rar by default so you can change this path if you want. This code completely removes the need for the web browser control (unless you are using it for something else) so most likely you can remove that from your real application once you incorporate this properly:
Imports System.Net
Imports System.IO
Imports System.Text
Public Class Form1
Private Const gsUserAgent As String = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0"
Const sUsername As String = "usernamehere"
Const sPassword As String = "passwordhere"
Const sMainURL As String = "http://www.mpgh.net/"
Const sCheckLoginURL As String = "http://www.mpgh.net/forum/login.php?do=login"
Const sDownloadURL As String = "http://www.mpgh.net/forum/attachment.php?attachmentid=266579&d=1417312178"
Const sCookieLoggedInMessage As String = "mpgh_imloggedin=yes"
Dim oCookieCollection As CookieCollection = Nothing
Dim sSaveFile As String = "c:\file.rar"
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
StartScrape()
End Sub
Private Sub StartScrape()
Try
Dim bContinue As Boolean = True
Dim sPostData(15) As String
sPostData(0) = UrlEncode("vb_login_username")
sPostData(1) = UrlEncode(sUsername)
sPostData(2) = UrlEncode("vb_login_password")
sPostData(3) = UrlEncode(sPassword)
sPostData(4) = UrlEncode("vb_login_password_hint")
sPostData(5) = UrlEncode("Password")
sPostData(6) = UrlEncode("s")
sPostData(7) = UrlEncode("")
sPostData(8) = UrlEncode("securitytoken")
sPostData(9) = UrlEncode("guest")
sPostData(10) = UrlEncode("do")
sPostData(11) = UrlEncode("login")
sPostData(12) = UrlEncode("vb_login_md5password")
sPostData(13) = UrlEncode("")
sPostData(14) = UrlEncode("vb_login_md5password_utf")
sPostData(15) = UrlEncode("")
If GetMethod(sMainURL) = True Then
If SetMethod(sCheckLoginURL, sPostData, sMainURL) = True Then
' Login successful
If DownloadMethod(sDownloadURL, sMainURL) = True Then
MessageBox.Show("File downloaded successfully")
Else
MessageBox.Show("Error downloading file")
End If
End If
End If
Catch ex As Exception
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Private Function GetMethod(ByVal sPage As String) As Boolean
Dim req As HttpWebRequest
Dim resp As HttpWebResponse
Dim stw As StreamReader
Dim bReturn As Boolean = True
Try
req = HttpWebRequest.Create(sPage)
req.Method = "GET"
req.AllowAutoRedirect = False
req.UserAgent = gsUserAgent
req.Accept = "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"
req.Headers.Add("Accept-Language", "en-us,en;q=0.5")
req.Headers.Add("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7")
req.Headers.Add("Keep-Alive", "300")
req.KeepAlive = True
resp = req.GetResponse ' Get the response from the server
If req.HaveResponse Then
' Save the cookie info if applicable
SaveCookies(resp.Headers("Set-Cookie"))
resp = req.GetResponse ' Get the response from the server
stw = New StreamReader(resp.GetResponseStream)
stw.ReadToEnd() ' Read the response from the server, but we do not save it
Else
MessageBox.Show("No response received from host " & sPage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
bReturn = False
End If
Catch exc As WebException
MessageBox.Show("Network Error: " & exc.Message.ToString & " Status Code: " & exc.Status.ToString & " from " & sPage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
bReturn = False
End Try
Return bReturn
End Function
Private Function SetMethod(ByVal sPage As String, ByVal sPostData() As String, sReferer As String) As Boolean
Dim bReturn As Boolean = False
Dim req As HttpWebRequest
Dim resp As HttpWebResponse
Dim str As StreamWriter
Dim sPostDataValue As String = ""
Try
req = HttpWebRequest.Create(sPage)
req.Method = "POST"
req.UserAgent = gsUserAgent
req.Accept = "application/x-shockwave-flash,text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"
req.Headers.Add("Accept-Language", "en-us,en;q=0.5")
req.Headers.Add("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7")
req.Referer = sReferer
req.ContentType = "application/x-www-form-urlencoded"
req.Headers.Add("Pragma", "no-cache")
req.Headers.Add("Keep-Alive", "300")
If oCookieCollection IsNot Nothing Then
' Pass cookie info from the login page
req.CookieContainer = SetCookieContainer(sPage)
End If
str = New StreamWriter(req.GetRequestStream)
If sPostData.Count Mod 2 = 0 Then
' There is an even number of post names and values
For i As Int32 = 0 To sPostData.Count - 1 Step 2
' Put the post data together into one string
sPostDataValue &= sPostData(i) & "=" & sPostData(i + 1) & "&"
Next i
sPostDataValue = sPostDataValue.Substring(0, sPostDataValue.Length - 1) ' This will remove the extra "&" at the end that was added from the for loop above
' Post the data to the server
str.Write(sPostDataValue)
str.Close()
' Get the response
resp = req.GetResponse
If req.HaveResponse Then
If resp.Headers("Set-Cookie").IndexOf(sCookieLoggedInMessage) > -1 Then
' Save the cookie info
SaveCookies(resp.Headers("Set-Cookie"))
bReturn = True
Else
MessageBox.Show("The email or password you entered are incorrect." & vbCrLf & vbCrLf & "Please try again.", "Unable to log in", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
bReturn = False
End If
Else
' This should probably never happen.. but if it does, we give a message
MessageBox.Show("The email or password you entered are incorrect." & vbCrLf & vbCrLf & "Please try again.", "Unable to log in", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
bReturn = False
End If
Else
' Did not specify the correct amount of parameters so we cannot continue
MessageBox.Show("POST error. Did not supply the correct amount of post data for " & sPage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
bReturn = False
End If
Catch ex As Exception
MessageBox.Show("POST error. " & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
bReturn = False
End Try
Return bReturn
End Function
Private Function DownloadMethod(ByVal sPage As String, sReferer As String) As Boolean
Dim req As HttpWebRequest
Dim bReturn As Boolean = False
Try
req = HttpWebRequest.Create(sPage)
req.Method = "GET"
req.AllowAutoRedirect = False
req.UserAgent = gsUserAgent
req.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
req.Headers.Add("Accept-Language", "en-US,en;q=0.5")
req.Headers.Add("Accept-Encoding", "gzip, deflate")
req.Headers.Add("Keep-Alive", "300")
req.KeepAlive = True
If oCookieCollection IsNot Nothing Then
' Set cookie info so that we continue to be logged in
req.CookieContainer = SetCookieContainer(sPage)
End If
' Save file to disk
Using oResponse As System.Net.WebResponse = CType(req.GetResponse, System.Net.WebResponse)
Using responseStream As IO.Stream = oResponse.GetResponseStream
Using fs As New IO.FileStream(sSaveFile, FileMode.Create, FileAccess.Write)
Dim buffer(2047) As Byte
Dim read As Integer
Do
read = responseStream.Read(buffer, 0, buffer.Length)
fs.Write(buffer, 0, read)
Loop Until read = 0
responseStream.Close()
fs.Flush()
fs.Close()
End Using
responseStream.Close()
End Using
oResponse.Close()
End Using
bReturn = True
Catch exc As WebException
MessageBox.Show("Network Error: " & exc.Message.ToString & " Status Code: " & exc.Status.ToString & " from " & sPage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
bReturn = False
End Try
Return bReturn
End Function
Private Function SetCookieContainer(sPage As String) As System.Net.CookieContainer
Dim oCookieContainerObject As New System.Net.CookieContainer
Dim oCookie As System.Net.Cookie
For c As Int32 = 0 To oCookieCollection.Count - 1
If IsDate(oCookieCollection(c).Value) = True Then
' Fix dates as they seem to cause errors/problems
oCookieCollection(c).Value = Format(CDate(oCookieCollection(c).Value), "dd-MMM-yyyy hh:mm:ss")
End If
oCookie = New System.Net.Cookie
oCookie.Name = oCookieCollection(c).Name
oCookie.Value = oCookieCollection(c).Value
oCookie.Domain = New Uri(sPage).Host
oCookie.Secure = False
oCookieContainerObject.Add(oCookie)
Next
Return oCookieContainerObject
End Function
Private Sub SaveCookies(sCookieString As String)
Dim sCookieStrings() As String = sCookieString.Trim.Replace(" HttpOnly,", "").Replace(" HttpOnly", "").Replace(" domain=.mpgh.net,", "").Split(";".ToCharArray())
oCookieCollection = New CookieCollection
For Each sCookie As String In sCookieStrings
If sCookie.Trim <> "" Then
Dim sName As String = sCookie.Trim().Split("=".ToCharArray())(0)
Dim sValue As String = sCookie.Trim().Split("=".ToCharArray())(1)
oCookieCollection.Add(New Cookie(sName, sValue))
End If
Next
End Sub
Private Function UrlEncode(ByRef URLText As String) As String
Dim AscCode As Integer
Dim EncText As String = ""
Dim bStr() As Byte = Encoding.ASCII.GetBytes(URLText)
Try
For i As Long = 0 To UBound(bStr)
AscCode = bStr(i)
Select Case AscCode
Case 48 To 57, 65 To 90, 97 To 122, 46, 95
EncText = EncText & Chr(AscCode)
Case 32
EncText = EncText & "+"
Case Else
If AscCode < 16 Then
EncText = EncText & "%0" & Hex(AscCode)
Else
EncText = EncText & "%" & Hex(AscCode)
End If
End Select
Next i
Erase bStr
Catch ex As WebException
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
Return EncText
End Function
End Class

Serial Port Data Received only working when breakpoint set

I have a program that starts an ultrasonic wind gauge and then requests the reading after 5 seconds. When I put a breakpoint in the Data Received handler the data being returned from the wind gauge is processed correctly, however if I do not have the breakpoint in place the data is ignored. The code is as follows (startWG is called when F2 is pressed on the keyboard)
Dim WGCom As New SerialPort
Private Function initWG() As Boolean
Dim WGPort = My.Settings.WGCom
If Not (WGCom.IsOpen) Then
Try
WGCom.PortName = "COM" & WGPort
WGCom.Parity = Parity.Even
WGCom.DataBits = 7
WGCom.StopBits = StopBits.One
WGCom.Handshake = Handshake.None
'WGCom.ReadTimeout = 3000
WGCom.WriteTimeout = 50000
WGCom.Open()
Catch ex As InvalidOperationException
MessageBox.Show(ex.Message)
Catch ex As UnauthorizedAccessException
MessageBox.Show(ex.Message)
Catch ex As System.IO.IOException
MessageBox.Show(ex.Message)
End Try
End If
If (WGCom.IsOpen) Then
Return True
Else
Return False
End If
End Function
#If (WGPort > 0) Then
#End If
'What to do with the wind gauge data when it is received.
Public Sub DataReceivedHandler(
sender As Object,
e As SerialDataReceivedEventArgs)
Dim sp As SerialPort = CType(sender, SerialPort)
Dim indata As String = sp.ReadExisting()
'MsgBox("Seen Data from WG " & indata)
If (indata.Length 0) Then
reading = indata.Substring(plus - 1, 5)
read = True
End If
Catch ex As Exception
End Try
Try
minus = InStr(indata, "-")
If (minus > 0) Then
reading = indata.Substring(minus - 1, 5)
read = True
End If
Catch ex As Exception
End Try
If (read) Then
WGReading = reading
' MsgBox(reading)
WGHasRead = True
read = False
plus = 0
minus = 0
Dim forClass As New WGReads
forClass.Reading = reading
SerialLog.WGReadings.Add(forClass)
RaiseEvent PropertyChanged("DataReceivedHandler", New PropertyChangedEventArgs("LastWG"))
WGFill(wgfield, hjevent)
End If
End Sub
Public Sub WGStart(wg() As String, hjevents As hjCompetition)
wgfield = wg
hjevent = hjevents
If (initWG()) Then
AddHandler WGCom.DataReceived, AddressOf DataReceivedHandler
Dim initBuffer(9) As Byte
initBuffer(0) = &H1
initBuffer(1) = &H13
initBuffer(2) = &H43
initBuffer(3) = &H57
initBuffer(4) = &H49
initBuffer(5) = &H2
initBuffer(6) = &H30
initBuffer(7) = &H35
initBuffer(8) = &H4
Try
WGCom.Write(initBuffer, 0, initBuffer.Length)
Catch ex As System.TimeoutException
End Try
'After init wait for the wind gauge to catch up
System.Threading.Thread.Sleep(100)
Dim outputBuffer1(9) As Byte
outputBuffer1(0) = &H1
outputBuffer1(1) = &H13
outputBuffer1(2) = &H43
outputBuffer1(3) = &H57
outputBuffer1(4) = &H53
outputBuffer1(5) = &H2
outputBuffer1(6) = &H30
outputBuffer1(7) = &H30
outputBuffer1(8) = &H4
Try
WGCom.Write(outputBuffer1, 0, outputBuffer1.Length)
Catch ex As System.TimeoutException
End Try
'Wait for the wind gauge to finish
wait(5500)
'Add a handler for when data is received from the Wind Gauge
AddHandler WGCom.DataReceived, AddressOf DataReceivedHandler
'Get the reading from the wind gauge
Dim getBuffer(9) As Byte
getBuffer(0) = &H1
getBuffer(1) = &H13
getBuffer(2) = &H43
getBuffer(3) = &H57
getBuffer(4) = &H4F
getBuffer(5) = &H2
getBuffer(6) = &H30
getBuffer(7) = &H30
getBuffer(8) = &H4
Try
WGCom.Write(getBuffer, 0, getBuffer.Length)
Catch ex As System.TimeoutException
End Try
'closeCom()
End If
End Sub
It doesn't matter where the breakpoint in the Data Received handler is but as long as there is one. If the breakpoint is in the WGStart Sub it doesn't work either.
Surely a breakpoint should not change the way the program executes?
Thanks in advance for your help.
Adding in a wait(100) has fixed the issue. The code for the wait sub is as follows for others looking for a solution to similar issues
Private Sub wait(ByVal interval As Integer)
Dim sw As New Stopwatch
sw.Start()
Do While sw.ElapsedMilliseconds < interval
' Allows UI to remain responsive
Application.DoEvents()
Loop
sw.Stop()
End Sub