[RESOLVED] [2005] Reading Serial Port
Im currently working on serial port RS232 communication, im able to set configurations thru serial port to my device, but having problems reading from the port. So im posting the same questions in a few VB forum, with the hope to obtain various valuable comments and suggestions..
I'm sending out command in ascii form, for example:
I want to set the "run" state of spectrum analyzer, its command is Q1 CR
therefore, inside a button event handler, i wrote:
Try
SerialPort1.Write(Chr(81) & Chr(49) & Chr(13))
Catch ex As Exception
MsgBox(ex.ToString)
End Try
As for reading from the serial port part, the problems come where, i put the below source codes, and the results is that the value is changing extremely fast like overflow that i cant really read the values measured. The values received from the spectrum analyzer are integer value. like, -70, etc...sometimes the value remain constant... how do i set the timer so that the port will poll for new incoming data at certain interval, say 1second,... and it discards the same incoming value as the present one, and only display an incoming data which is different from present.
But then, im confused because the fast changing figure are not really numbers we can read, instead i get something like, n ? E, etc.. What should i do with them so that i can read the actual value.
Besides, if i want to display the incoming data in an an real time graph, what should i use inside the toolbox?
'Read signals
Private Sub Button8_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button8.Click
SerialPort1.WriteLine(Chr(82) & Chr(51) & Chr(13) & vbCrLf)
End Sub
Private Sub DataReceived( _
ByVal sender As Object, _
ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) _
Handles SerialPort1.DataReceived
TextBox3.Invoke(New _
myDelegate(AddressOf updateTextBox3), _
New Object() {})
End Sub
Public Delegate Sub myDelegate()
Public Sub updateTextBox3()
End Sub
Your help is very much appreciated!
Re: [2005] Reading Serial Port
The sub updateTextBox3 is empty?
Try this:
VB Code:
Public Sub updateTextBox3()
TextBox3.AppendText(serialport.ReadLine)
End Sub
This reads up to the NewLine value.
You can specify this value in the serialport settings
eg SerialPort1.NewLine = vbCr
or whatever the terminating character that is used by the analyzer.
Use a multiline textbox to see the exact nature of your incoming data.
Or you could also just read a byte at a time....
VB Code:
Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
'fires when data is received in the input buffer
If SerialPort1.BytesToRead > 0 Then
Do
updateTextBox3(SerialPort1.ReadByte)
If SerialPort1.BytesToRead = 0 Then
Exit Do
End If
Loop
End If
End Sub
Check the format of the bytes you are receiving and convert them to the format that you require.
I am not sure what you want exactly, but if you want to put data into a graph convert the incoming ascii to integer. MSDN help has plenty of information on character formatting etc.
Re: [2005] Reading Serial Port
Can I have some comments regarding the codes below. Where the mistakes are? and how to append read data to textbox?
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
If SerialPort1.IsOpen Then
SerialPort1.Close()
End If
Try
With SerialPort1
.PortName = "COM1"
.BaudRate = 9600
.Parity = IO.Ports.Parity.None
.DataBits = 8
.StopBits = IO.Ports.StopBits.Two
End With
SerialPort1.Open()
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Dim WithEvents SerialPort As New System.IO.Ports.SerialPort
Dim rxbyte As New ArrayList
Dim i As Integer
Public Delegate Sub myDelegate()
Public Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As _
System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
If SerialPort1.BytesToRead > 0 Then
Do
rxbyte.Add(SerialPort1.ReadByte)
TextBox1.Invoke(New myDelegate(AddressOf updateTextBox1), _
New Object() {SerialPort1.ReadByte})
Exit Do
Loop
End If
End Sub
Public Sub updateTextBox1()
With TextBox1
.AppendText(rxbyte(i))
End With
End Sub
End Class
Re: [2005] Reading Serial Port
In the DataReceived event sub you need to change to this....
VB Code:
TextBox1.Invoke(New myDelegate(AddressOf updateTextBox1), _
New Object() {})
and also this....
VB Code:
Public Sub updateTextBox1()
Dim i As Integer
For i = 0 To rxbyte.Count - 1
With TextBox1
'Option Strict On
'CInt to convert Objects in arraylist to integer.
'Chr to convert the integers into Ascii characters
.AppendText(Chr(CInt(rxbyte(i))))
End With
Next
End Sub
everything should work correctly now.
hope this helps.
Re: [2005] Reading Serial Port
thanks but i still cant read..
From my device, which is spectrum analyzer manual, i have some reading data command, but i wonder how to write the command so that the data reading event can read. and does it affect the data reading event? hereby include the url of reading output level for my device:
http://www.geocities.com/sandrea83/3...32commands.doc
Re: [2005] Reading Serial Port
Here's a suggestion... open Hyper Terminal, connect to the device and try some simple command first such as R1 and see if you can get any response from the device. If there's no response whatsoever, either your com port settings are incorrect or the command wasn't understood by the device or the device is malfunctioning. If you can communicate with the device via hyper terminam, there is'nt any reason why you can't in your program.
Re: [2005] Reading Serial Port
im confused what a hyper terminal is actually ? and how to use it? if i were to program it to read based on those commands inside the word file, what should i do? put those command in write command inside the event handler of a button? or write it inside DataReceived event?
Re: [2005] Reading Serial Port
Quote:
Originally Posted by wence
im confused what a hyper terminal is actually ? and how to use it? if i were to program it to read based on those commands inside the word file, what should i do? put those command in write command inside the event handler of a button? or write it inside DataReceived event?
HyperTerminal is a software come bundled with the OS. If you're running WinXP, your can start it by:
Start > All Programs > Accessories > Communications > Hyper Terminal
Open it up, enter in necessary parameters for port settings and connect.
Once connected, you can type in commands to send to your device and it will display any response back on the screen ... sort of like a chat window.
Now to answer your second question: if you have your command stored in a text file, you can use StreamReader class to read the file into an array, then refer to the appropriate element in this array to send your command. However, it can get messy because you will have to keep track of which command stored in what element. Another suggest is to declare your commands as constant variables with thin your program at class level, so that when you want to send a command, you just use the variable. Something like:
VB Code:
Private Const Cmd1 As String = "R1"
Private Const Cmd2 As String = "R2" & ChrW(13) & "W0"
'........ blablabla ......
Then later on when you want to send a command to the device, just use Cmd1, Cmd2, ...
However, your top priority is to get the thing to work... Once you get the communication established, you can always fine tune your app later.
Re: [2005] Reading Serial Port
thanks stanav,ill try wif hyper terminal next week...i dont hav problem wif writing to the port, but reading data is a problem..therere in fact a few commands for read data...wonder where should i put my command for reading data?
for example, to send a command to read data: SerialPort1.WriteLine(Chr(82) & Chr(51) & Chr(13))
VB Code:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
SerialPort1.WriteLine(Chr(82) & Chr(51) & Chr(13))
end sub
or
Public Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As _
System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
SerialPort1.WriteLine(Chr(82) & Chr(51) & Chr(13))
end sub
so far ive tried put such command inside the event handler of a button but eventually the device hang..
Re: [2005] Reading Serial Port
Hi,
This link could be usefull, about reading serial port;
http://msdn.microsoft.com/library/de...onnections.asp
Wkr,
sparrow1
Re: [2005] Reading Serial Port
Quote:
Originally Posted by wence
thanks stanav,ill try wif hyper terminal next week...i dont hav problem wif writing to the port, but reading data is a problem..therere in fact a few commands for read data...wonder where should i put my command for reading data?
for example, to send a command to read data: SerialPort1.WriteLine(Chr(82) & Chr(51) & Chr(13))
VB Code:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
SerialPort1.WriteLine(Chr(82) & Chr(51) & Chr(13))
end sub
or
Public Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As _
System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
SerialPort1.WriteLine(Chr(82) & Chr(51) & Chr(13))
end sub
so far ive tried put such command inside the event handler of a button but eventually the device hang..
It really depends on how you want to read the data from your device. To make it a little more clear to you, in order to read the device's data, you have to tell it to give you the data. That's why you have to send the commands to the device. Although there are devices that automatically send out data, communication is only 1-way, such as most telephone switch systems and all you have to do is read the data at your convenience on these devices, however I don't think your device belongs to this group.
Now back to your questtion, there are basically 2 ways to read data from a device: timed interval or continuous. For timed interval reading, you can use a timer, and send a command at the timer_tick event. For continuous reading, in your form load event, after open your comport, send a command. Then in your updateTextbox sub, after reading any data returned, you want to send a command to the device again. This will create an infinite loop of send and receive asynchronously.
Re: [2005] Reading Serial Port
Hi Stanav,thanks for your advices. i think my program got problem on the datareceived part. this morning, i try with hyperminal, it works. For example,i set a certain mark frequency in my device, then i write a command "L0 CR" to the serial port, then i disconnect COM1 at my program, connect COM1 at the hyperterminal instead, the hyperterminal screen read the frequency value which i set earlier, like 1223.444. Although i not able to read to the signal strength value yet.
So hyperterminal is only for reading, and you cant write to device using hyperterminal? What would be the biggest problem if hyperterminal reads but my program doesnt?
thanks..
Re: [2005] Reading Serial Port
Quote:
Originally Posted by wence
Hi Stanav,thanks for your advices. i think my program got problem on the datareceived part. this morning, i try with hyperminal, it works. For example,i set a certain mark frequency in my device, then i write a command "L0 CR" to the serial port, then i disconnect COM1 at my program, connect COM1 at the hyperterminal instead, the hyperterminal screen read the frequency value which i set earlier, like 1223.444. Although i not able to read to the signal strength value yet.
So hyperterminal is only for reading, and you cant write to device using hyperterminal? What would be the biggest problem if hyperterminal reads but my program doesnt?
thanks..
Hello Wence,
Try this code. It's taken from one of my working apps. I trimmed it a bit so that it only contains relevant code for serial port stuff. You can modify it to send different commands according to your needs.
VB Code:
'don't for get to put "Imports System.IO.Ports" at top of the code page
'Declare a comport object with class level scope
Private WithEvents comPort As New IO.Ports.SerialPort
'In form_load, open comport
Private Sub frmMain_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
OpenComPort()
'Then send request to read data
SendRequestCommand("L0" & ChrW(13)) 'Modify your command string as needed
End Sub
Private Sub OnDataReceived(ByVal sender As Object, _
ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) _
Handles comPort.DataReceived
Try
txtDataReceived.Invoke(New myDelegate(AddressOf UpdateTextBox), New Object() {})
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
'This is the delegate used to invoke your updateTextBox sub
Public Delegate Sub myDelegate()
Public Sub UpdateTextBox()
Dim strInData As String = ""
'Read one byte at a time
While comPort.BytesToRead > 0
strInData &= ChrW(comPort.ReadByte())
End While
'Do whatever you want with the data
txtDataReceived.Text = strInData
txtDataReceived.Refresh()
System.Threading.Thread.Sleep(100)
SendRequestCommand("L0" & ChrW(13)) 'Again, change the command to fit your need.
End Sub
Private Sub OpenComPort()
CloseComPort()
Try
'Initialize com port. You need to substitute these settings with the correct parameters for your device
With comPort
.PortName = "COM1"
.BaudRate = 9600
.Parity = IO.Ports.Parity.Odd
.DataBits = 7
.StopBits = IO.Ports.StopBits.Two
.ReadBufferSize = 64
.ReadTimeout = 500
.ReceivedBytesThreshold = 5 'Adjust this settings according to
' the expected length of the returned data. You can play with
' it a bit to get optimized performance.
.Handshake = IO.Ports.Handshake.None
.RtsEnable = True
.DtrEnable = True
.Encoding = System.Text.Encoding.ASCII
End With
'Open com port
comPort.Open()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Private Sub CloseComPort()
If comPort.IsOpen() Then
comPort.Close()
End If
End Sub
Private Sub SendRequestCommand(ByVal cmd As String)
If comPort.IsOpen() Then
comPort.DiscardInBuffer()
comPort.Write(cmd)
Else
MsgBox("COM port is closed!")
End If
End Sub
Hope this helps.
Re: [2005] Reading Serial Port
thanks lots stanav. I'll try on it.
Re: [2005] Reading Serial Port
Hi Stanav, i really appreciate your help. It works! I can display the frequency which i set in the device on the textbox. However, i still cant read the signal measured by the device. I can see that the serialport1.readbyte command has to come in the updatetextbox sub, not in the datareceived event.
I have a few question here:
1) What does these commands mean:
comPort.DiscardInBuffer()
and why has to be &= instead of = only?
2)Is it possible i put different textboxs and display different data received from the device all at the same time?
3)I try a function which is data memory output copy wif hyper terminal. and as a result, i get a whole content in characters which i dont understand, the character font is terminal if not mistaken. and i wonder why i could read the set frequency value straight away wif ht, but not wif the data memory i get?
Regards...