VB.net GPIB Termination character problem - vb.net

This is my first question here.
I have a problem with the termination character when sending a message on the GPIB
Default character is line feed and my instrument needs a carriage return.
I´v tried to change it but when I sniffing at the bus it is still line feed.
Anyone knows what I´m doing wrong?
EDIT:
As I understand instrEprobe.IO.TerminationCharacter only affects the receiving message from instrument but I need to send message with carrage return and not line feed
BR
Niklas
Public Function InitEprobe(ByVal strGpib As String, ByVal Type As String)
ioMgr = New Ivi.Visa.Interop.ResourceManager
instrEprobe = New Ivi.Visa.Interop.FormattedIO488
Try
Dim Out As String = ""
instrEprobe.IO = ioMgr.Open("GPIB0::" & strGpib) 'set GPIBport
instrEprobe.IO.TerminationCharacter = 13 ' set termination character
instrEprobe.IO.TerminationCharacterEnabled = True
instrEprobe.WriteString("I") 'Send command to instrument
Wait(500)
Out = instrEprobe.ReadString 'Read command from instrument
Return Out
Catch exp As Exception
Return exp.ToString
End Try
End Function

Related

How to detect/identify a serial port programatically in a winform?

I am programming a windows form that will communicate with a microcontroller.
After the winform is loaded, it should automatically detect the comport where the microcontroller is connected .
What I am doing is:
- Get the names of the available ports
- with a loop through these names :
- assign the port name to the serial port instance in the form
- send a command for the detection
- wait some time
- check if some text has been received
- compare the received message to the identification message
- if it is the right one break the loop and return the result, if not
continue
Below is the code of the function. I am using thread.sleep method. But the function is not working and I don't detect the board when it is there.
Can You tell me what is wrong with the function? Is the time delay blocking the reception? how should I ameliorate it?
This function is excuted at the beginning after loading the form. If I don't find the port, nothing can go forward. On the other side, there are no other threads I have to take into account at that stage of the excution. I thought about the DatarRceived Event, but it does not make sense at this stage, it will be activated after the right port has been detected.
Please let me know what you think
thank you
Public Function connect(testport As SerialPort, recognizeText As String, userCommand As String) As Boolean
Dim intReturnASCII As Integer = 0
Dim charReturnValue = Chr(intReturnASCII)
Dim returnMessage As String = ""
Dim count As Integer = 0
Dim ports As String() = IO.Ports.SerialPort.GetPortNames
If testport.IsOpen Then
testport.Close()
End If
Try
For Each newport As String In ports
testport.PortName = newport
testport.Open()
testport.Write(STX & userCommand & ETX)
Thread.Sleep(200) ' stop the userform and wait for the reception of the response
count = testport.BytesToRead
While count > 0
intReturnASCII = testport.ReadByte
returnMessage = returnMessage + Convert.ToChar(intReturnASCII)
count -= 1
End While
testport.Close()
XMCPort = newport ' Danach instantiate the serial port publicly with port name , is true instantiate
If returnMessage.Contains(recognizeText) Then
Return True
End If
Next
Return False
Catch ex As Exception
Return False
End Try
count = 0
returnMessage = ""
End Function

Encoding newline in VB.NET for HMAC SHA1

I'm having a problem authenticating an API with OAuth. I can get it work fine in Python, but not in VB.Net. I realised the issue is that SHA1 algorithm is returning a different value in Python and VB.NET for the what I thought was the same message. This only seems to be the case when there is a newline character "\n" in the message (which there has to be for the API call). Using Environment.NewLine doesn't seem to help.
The code I'm using (based on this answer) is here, with the expected values I get from my Python program:
Public Sub Main()
' Expect D/5B78PD9pFhmqZQi3eenPBy6ks=
' Get D/5B78PD9pFhmqZQi3eenPBy6ks=
console.writeline(getHash("a", "msg"))
' Expect yuuq6RwtwkoJ6n3PquGFx60MLas=
' Get uv4AwQjvYeCTajhHw7EFtPlJfCE=
console.writeline(getHash("a", "msg\n"))
' Expect yuuq6RwtwkoJ6n3PquGFx60MLas=
' Get efRfAnmIN/C/YX/UPHVPFY5VjJg=
console.writeline(getHash("a", "msg" + Environment.NewLine))
End Sub
Public Function getHash(ByVal key As String, ByVal msg As String) As String
Dim myEncoder As New System.Text.UTF8Encoding
Dim keyBytes() As Byte = myEncoder.GetBytes(key)
Dim msgBytes() As Byte = myEncoder.GetBytes(msg)
Dim myHMACSHA1 As New System.Security.Cryptography.HMACSHA1(keyBytes)
Dim HashCode As Byte() = myHMACSHA1.ComputeHash(msgBytes)
Return Convert.ToBase64String(HashCode)
End Function
In case it's useful, my Python program is:
import base64
import hashlib
import hmac
key = "a"
msg = "msg\n"
key_byte = key.encode('utf-8')
msg_byte = msg.encode('utf-8')
h = hmac.new(key_byte, msg_byte, hashlib.sha1)
print base64.b64encode(h.digest()) # yuuq6RwtwkoJ6n3PquGFx60MLas=
My guess is it's something to do with how the newline character is encoded, but I can't figure out how to solve it.
To start with I'd just like to point out that \n in VB.NET does not represent a new line character. It will literally just become \n.
Environment.NewLine adapts to the current OS. Different operating systems use different line endings. The issue here is that the Python code is using a Line Feed character (\n) as a new line indicator, but since Environment.NewLine adapts to the OS it will return Windows' line ending, which is Carriage Return + Line Feed (\r\n).
Therefore if you want it to match the Python code you've got to be sure to insert a Line Feed only. For instance:
Console.WriteLine(getHash("a", "msg" & vbLf))

Issue sending big string over TCP

I have the following function to send and receive data it works OK for short strings like 150 bytes, but with a string of 2500 bytes it get stuck.
I tried to send some data with HTWin and nothing get the other end of the net.
So receiver on the other end never get even a character.
I tried also with the old Hyperterminal with same result.
Private Function SendReport(ByVal Msg As String, ByVal Host As String, ByVal Port As String) As String
Try
Dim Tx As New TcpClient()
Dim stream As NetworkStream = Nothing
Dim CloseStream As Boolean = False
Dim LingerMode As New LingerOption(True, 5)
' String to store the response ASCII representation.
Dim responseData As [String] = [String].Empty
Tx.NoDelay = True
Tx.LingerState = LingerMode
Tx.SendTimeout = 10000
Tx.ReceiveTimeout = 10000
Tx.Connect(Host, Port)
' Translate the passed message into ASCII and store it as a Byte array.
Dim data As [Byte]() = System.Text.Encoding.ASCII.GetBytes(Msg)
' Get a client stream for reading and writing.
' Stream stream = client.GetStream();
stream = Tx.GetStream()
CloseStream = True
'stream.WriteTimeout = 100
' Send the message to the connected TcpServer.
stream.Write(data, 0, data.Length)
'Tx.Connected
' Receive the TcpServer.response.
' Buffer to store the response bytes.
data = New [Byte](256) {}
' Read the first batch of the TcpServer response bytes.
Dim bytes As Int32 = stream.Read(data, 0, data.Length)
responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes)
If CloseStream = True Then
stream.Close()
End If
Tx.Close()
Return responseData
Catch ex As Exception
WriteRTBLog(ex.Message, Color.Red)
WriteRTBLog(ex.StackTrace, Color.DarkRed)
Return "Error"
End Try
End Function
If I split the big string into smaller one and call this function over and over all the data reach the other end.
Also, I need to get an ACK packet that is big too and the code must wait for and special character that indicates the end.
I was thinking in to create a Thread with a TcpListener but, Is possible to have a TcpListener in the same port of a TcpClient?
The whole idea is to send a big string that is separated by an special character and finished with another special character.
The other end receive the data, split the string using the first special character and send one ACK by every item in the split function.
And in the last ACK send the second special character to indicate the end of the communication, so my application can process the received data properly.
I think I'm drowning in a glass of water.

Is a return statement necessary for try catch

I put a try/catch block around some email sending logic. If the email succeeds, it gives a confirmation message, if it fails, it gives a failure message. Visual Studio is warning me that the function doesn't return a value on all code paths. Do I need to put return statements in each the Try and Catch blocks? If I do, for example put Return statements of False or Null at the end of the Try and Catch, will the other code preceding the Return statements still execute?
Function Sendmail(ByVal subject As String, ByVal msg As String, ByVal fromAddress As String, ByVal toAddress As String)
Try
Dim message As New MailMessage
message.From = New MailAddress(fromAddress)
For Each s As String In toAddress.Split(New [Char]() {";"c})
message.To.Add(New MailAddress(s))
Next
message.Subject = subject
message.Body = msg
message.IsBodyHtml = False
Dim client As New SmtpClient
client.Send(message)
pnlEmailSuccess.Visible = True
Catch ex As Exception
pnlEmailSuccess.Visible = False
pnlEmailError.Visible = True
lblErrorMsg.Text = ex.ToString
End Try
End Function
To answer your question, No you do not need a return statement in a Try/Catch. If you are not returning a value you don't need to write it in a function. Instead of a writing this in a function you could write it in a sub statement or a sub procedure. Here's a link to learn more about sub procedures.
VB.NET expects that the last statement executed in a function is a Return that will send a value back to the calling procedure. When the code encounters a Return statement, it immediately terminates execution of the code and returns the value specified, which is why it's usually the last statement in the function (see below for example). VB.NET is just warning you that there is a possibility (in your case, a certainty, as there's only one exit point from the function) that the function won't be returning a value. As another example of when this might happen, consider a function that has two different paths by which the code could exit:
Function IsThisFive(ByVal x as Integer) as Boolean
If x = 5 Then
Return True 'One code path exits here, with return value
Else
MsgBox("This is not five!")
End If
' Other code path exits here if x <> 5 -- no return value specified
End Function
To answer your question then, no, you don't need a return value inside both the Try and Catch blocks. You do, however, need one at the end of the block after End Try and before End Function. The code will run through Try..Catch..End Try construct, then Return a value.
If you don't need it to return a value, why not make it a sub rather than a function? A sub isn't expected to return a value, eliminating the problem. :-)
If you still wanted it to be a function, one common convention in programming is to only have a single exit point from a subroutine or function. This makes it easier to follow program flow when debugging or reading code.
You could do something like this:
Function SendMail(ByVal subject As String, ByVal msg As String, ByVal fromAddress As String, ByVal toAddress As String) as Boolean
Dim maiLSent as Boolean = False
Try
'send mail code
mailSent = True
Catch
'exception handling code here
mailSent = False
End Try
Return mailSent ' Only exit point from function is here
End Function
I added it to a timer with Try-Catch rather than continuously running. Worked perfectly.

Web Service saving a string value from a function

I was just wondering if a Web Service can save something i send to it as a string without resetting it everytime i call the WS?
<WebMethod()> _
Public Function sendLCDBrightnessLevel(ByRef command As String) As String
'This reads a number for the LCD brightness level and store it
'The phone will call this function every 5 minutes to see what the value is
'android phone->WS
Dim lcdLevel As String = ""
If command <> "READ" Then
lcdLevel = command
Return "Stored: " & lcdLevel
Else
Return lcdLevel
End If
End Function
Would lcdLevel retain the value in command if the app just checks it?
Example:
I send it 30 for the command and since its not READ it stores it in lcdLevel. Once the Android phone gets around to the "every 5 minutes" check, will it read 30 or will it be nothing?
I'm thinking that i need to move Dim lcdLevel As String = "" outside the function since its at the start of the function call each time? Do i just need to place that outside the function in order to keep the value stored or is there something else i also need to do?
Thanks!
<WebMethod()> _
Public Function sendLCDBrightnessLevel(ByRef command As String) As String
'This reads a number for the LCD brightness level and store it
'The phone will call this function every 5 minutes to see what the value is
'android phone->WS
Dim lcdLevel As String = ""
Dim path As String = "c:\temp\lcdValue.txt"
If command <> "READ" Then
lcdLevel = command
Dim objWriter As New System.IO.StreamWriter(path, False, Encoding.UTF8)
objWriter.WriteLine(lcdLevel)
objWriter.Close()
Return "Stored: " & lcdLevel
Else
Dim objReader As New System.IO.StreamReader(path, Encoding.UTF8)
lcdLevel = objReader.ReadToEnd
objReader.Close()
Return lcdLevel
End If
End Function
Guess this is the only way to store a value easily in a WS?
Seems to work as i needed it too.