I am trying to create vb.net program to get data from scales using serial port.
I don't know scales model, just Display model: IND231.
Problem is i get stupid data:
but if turn on Putty i get this:
As you see in putty there is only one line which refresh every sec, true weight is first two 00 (in middle), in my situation this line is not refreshing, but make a huge line and after 5-10 s, my program just crash.
My program code is:
Imports AxSerial
Public Class Form1
Dim Q As Queue(Of String) = New Queue(Of String)
Private Sub Form1_Load(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles MyBase.Load
For Each s In System.IO.Ports.SerialPort.GetPortNames()
lstPorts.Items.Add(s)
Next s
End Sub
Private Sub btnStart_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles btnStart.Click
Try
If lstPorts.SelectedIndex = -1 Then
MsgBox("Please select a port")
Exit Sub
Else
SerialPort1.BaudRate = 9600
SerialPort1.DataBits = 8
SerialPort1.Parity = IO.Ports.Parity.None
SerialPort1.StopBits = 1
SerialPort1.RtsEnable = False
SerialPort1.PortName = lstPorts.SelectedItem.ToString
SerialPort1.Open()
Timer1.Start()
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Private Sub SerialPort1_DataReceived(ByVal sender As System.Object,
ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) _
Handles SerialPort1.DataReceived
Q.Enqueue(SerialPort1.ReadExisting())
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles Timer1.Tick
SyncLock Q
While Q.Count > 0
txtReceived.Text &= Q.Dequeue
End While
End SyncLock
End Sub
Private Sub btnStop_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles btnStop.Click
SerialPort1.Close()
Timer1.Stop()
End Sub
End Class
This is IND321 Serial Port Parameters
SerialPort1.BaudRate = 9600
SerialPort1.DataBits = 8
SerialPort1.Parity = IO.Ports.Parity.None
SerialPort1.StopBits = 1
SerialPort1.RtsEnable = False
Im not sure with RtsEnable, i think this is FlowControl.
What i need to correct to get data like putty?
It looks like your scale/serial port is returning data in another format.
Check your scale specs. It might be e72 or some other even/odd/bits/parity combination.
Related
I'm facing a big problem here, I'm developing a app to read data from a Weight.
Everything is working perfectly, but the result is not what I expected: when reading the data from the scale, it keeps printing the data without stopping and I would like it to read a single line and whenever there is any change in the scale, just change the value and not add a new line...
The way it's printed:
My code:
Public Class Form1
Dim Q As Queue(Of String) = New Queue(Of String)
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
For Each s In System.IO.Ports.SerialPort.GetPortNames()
ComboBox1.Items.Add(s)
Next s
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Try
If ComboBox1.SelectedIndex = -1 Then
MsgBox("Please select a port")
Exit Sub
Else
SerialPort1.BaudRate = 9600
SerialPort1.DataBits = 8
SerialPort1.Parity = IO.Ports.Parity.None
SerialPort1.StopBits = IO.Ports.StopBits.One
SerialPort1.PortName = ComboBox1.SelectedItem.ToString
SerialPort1.Open()
Timer1.Start()
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, _
ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) _
Handles SerialPort1.DataReceived
Q.Enqueue(SerialPort1.ReadExisting())
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Timer1.Tick
SyncLock Q
While Q.Count > 0
TextBox1.Text &= Q.Dequeue
End While
End SyncLock
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
SerialPort1.Close()
Timer1.Stop()
End Sub
End Class
Here's a simple example using Control.BeginInvoke() to set a Control's property with some data coming from a secondary Thread.
You can use this method since you have all your code in a Form and you use
a SerialPort Component.
Otherwise, build a class to handle the SerialPort and pass a delegate to its Constructor, capture SynchronizationContext.Current and Post() to the delegate.
Or use an IProgress<T> delegate (Progress(Of String) here) and pass this delegate to the class, then just call its Report() method from the event handler.
Assuming ReadExisting() works for you and the Encoding is set correctly (it appears to be, from the results shown in the OP), you could change the code in the DataReceived handler to:
It's required to check whether the handles of the Controls involved (the Form, mainly) are created before calling Invoke() / BeginInvoke(), otherwise you may (will, at some point) get an exception that may kill the application (the IProgress<T> pattern is preferable).
Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
Dim comPort = DirectCast(sender, SerialPort)
UpdateUI(comPort.ReadExisting())
End Sub
' [...]
Private lastWeight As String = String.Empty
Private Sub UpdateUI(weight As String)
If IsHandleCreated Then
BeginInvoke(New Action(
Sub()
If Not lastWeight.Equals(weight) Then
lastWeight = weight
If TextBox1.IsHandleCreated Then TextBox1.Text = lastWeight
End If
End Sub))
End If
End Sub
Make a test with a threaded Timer, setting the Interval to a low value (e.g., 50ms).
You can also try to close the Form without stopping the Timer.
Found the soluction:
Public Class Form5
Delegate Sub SetTextCallback(ByVal data As String)
Private Delegate Sub UpdateLabelDelegate(theText As String)
Private Sub UpdateLabel(theText As String)
If Me.InvokeRequired Then
Me.Invoke(New UpdateLabelDelegate(AddressOf UpdateLabel), theText)
Else
TextBox1.Text = theText
End If
End Sub
Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
Dim returnStr As String
returnStr = SerialPort1.ReadExisting
Me.BeginInvoke(Sub()
UpdateLabel(returnStr)
End Sub)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
SerialPort1.Open()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
SerialPort1.Close()
End Sub
End Class
I am new to visual basic . I am sending data from arduino evey 1s say current. I wanted to print on text box. Here is my code on VB side . Problem i am facing here . I am getting data but Not ovwrwriting .it just print one after the other. I am using VB2010.
VB code
Imports System
Imports System.ComponentModel
Imports System.Threading
Imports System.IO.Ports
Public Class frmMain
Dim myPort As Array 'COM Ports detected on the system will be stored here
Delegate Sub SetTextCallback(ByVal [text] As String) 'Added to prevent threading errors during receiveing of data
Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
myPort = IO.Ports.SerialPort.GetPortNames() 'Get all com ports available
cmbBaud.Items.Add(9600) 'Populate the cmbBaud Combo box to common baud rates used
cmbBaud.Items.Add(19200)
cmbBaud.Items.Add(38400)
cmbBaud.Items.Add(57600)
cmbBaud.Items.Add(115200)
For i = 0 To UBound(myPort)
cmbPort.Items.Add(myPort(i))
Next
cmbPort.Text = cmbPort.Items.Item(0) 'Set cmbPort text to the first COM port detected
cmbBaud.Text = cmbBaud.Items.Item(0) 'Set cmbBaud text to the first Baud rate on the list
'SerialPort1.PortName = cmbPort.Text()
'SerialPort1.BaudRate = cmbBaud.Text()
btnDisconnect.Enabled = False 'Initially Disconnect Button is Disabled
End Sub
Private Sub btnConnect_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConnect.Click
SerialPort1.PortName = cmbPort.Text()
'Set SerialPort1 to the selected COM port at startup
SerialPort1.BaudRate = cmbBaud.Text()
'Set Baud rate to the selected value on
'Other Serial Port Property
SerialPort1.Parity = IO.Ports.Parity.None
SerialPort1.StopBits = IO.Ports.StopBits.One
SerialPort1.DataBits = 8 'Open our serial port
SerialPort1.Open()
btnConnect.Enabled = False 'Disable Connect button
btnDisconnect.Enabled = True 'and Enable Disconnect button
End Sub
Private Sub btnDisconnect_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDisconnect.Click
SerialPort1.Close() 'Close our Serial Port
btnConnect.Enabled = True
btnDisconnect.Enabled = False
End Sub
Private Sub btnSend_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
SerialPort1.Write(txtTransmit.Text & vbCr) 'The text contained in the txtText will be sent to the serial port as ascii
'plus the carriage return (Enter Key) the carriage return can be ommitted if the other end doe
End Sub
Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
ReceivedText(SerialPort1.ReadExisting()) 'Automatically called every time a data is received at the serialPort
End Sub
Private Sub ReceivedText(ByVal [text] As String)
'compares the ID of the creating Thread to the ID of the calling Thread
If Me.Current_Read.InvokeRequired Then
Dim x As New SetTextCallback(AddressOf ReceivedText)
Me.Invoke(x, New Object() {(text)})
Else
Me.Current_Read.Text &= [text]
End If
End Sub
Private Sub cmbPort_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
If SerialPort1.IsOpen = False Then
SerialPort1.PortName = cmbPort.Text 'pop a message box to user if he is changing ports
Else 'without disconnecting first.
MsgBox("Valid only if port is Closed", vbCritical)
End If
End Sub
Private Sub cmbBaud_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
If SerialPort1.IsOpen = False Then
SerialPort1.BaudRate = cmbBaud.Text 'pop a message box to user if he is changing baud rate
Else 'without disconnecting first.
MsgBox("Valid only if port is Closed", vbCritical)
End If
End Sub
Private Sub RELAY_ON_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RELAY_ON.Click
SerialPort1.Write("1")
End Sub
Private Sub RELAY_OFF_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RELAY_OFF.Click
SerialPort1.Write("0")
End Sub
End Class
Arduino Code.
float Output_Current ;
void TakeReading()
{
newaverage = analogRead(A5);
Output_Current = 0.0336666666667*newaverage - 17.17;
}
void loop()
{
Serial.println( Output_Current );
delay(1000);
}
I created a little program to get weight from scales via COM port. But then I turn on program. It's start to loop (creating long list) SV 0 KG in Label. And if weight increase it's also loop, for e.g. SV 0 KG, SV 50 KG, SV 48 KG, SV 0 KG and etc..
So my question is how to stop loop and always show one value?
And second question can I use Replace("SV", " ") or there is other better method?
Dim myPort As Array
Delegate Sub SetTextCallback(ByVal [text] As String)
Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
myPort = IO.Ports.SerialPort.GetPortNames()
cmbBaud.Items.Add(9600)
cmbBaud.Items.Add(19200)
cmbBaud.Items.Add(38400)
cmbBaud.Items.Add(57600)
cmbBaud.Items.Add(115200)
For i = 0 To UBound(myPort)
cmbPort.Items.Add(myPort(i))
Next
cmbPort.Text = cmbPort.Items.Item(0)
cmbBaud.Text = cmbBaud.Items.Item(0)
btnDisconnect.Enabled = False
End Sub
Private Sub btnConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConnect.Click
SerialPort1.PortName = cmbPort.Text
SerialPort1.BaudRate = cmbBaud.Text
SerialPort1.Parity = IO.Ports.Parity.None
SerialPort1.StopBits = IO.Ports.StopBits.One
SerialPort1.DataBits = 8
SerialPort1.Open()
btnConnect.Enabled = False
btnDisconnect.Enabled = True
End Sub
Private Sub btnDisconnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDisconnect.Click
SerialPort1.Close()
btnConnect.Enabled = True
btnDisconnect.Enabled = False
End Sub
Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
SerialPort1.Write(txtTransmit.Text & vbCr)
End Sub
Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
ReceivedText(SerialPort1.ReadExisting())
End Sub
Private Sub ReceivedText(ByVal [text] As String)
If Me.rtbReceived.InvokeRequired Then
Dim x As New SetTextCallback(AddressOf ReceivedText)
Me.Invoke(x, New Object() {(text)})
Else
Me.rtbReceived.Text &= [text]
End If
End Sub
Private Sub cmbPort_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbPort.SelectedIndexChanged
If SerialPort1.IsOpen = False Then
SerialPort1.PortName = cmbPort.Text
Else
MsgBox("Valid only if port is Closed", vbCritical)
End If
End Sub
Private Sub cmbBaud_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbBaud.SelectedIndexChanged
If SerialPort1.IsOpen = False Then
SerialPort1.BaudRate = cmbBaud.Text
Else
MsgBox("Valid only if port is Closed", vbCritical)
End If
End Sub
Private Sub rtbReceived_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles rtbReceived.TextChanged
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDisconnect.Click
rtbReceived.Text = " "
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
SerialPort1.Write(txtTransmit.Text & vbCr)
End Sub
I'm writing a program for an internship and need some advice. I've done my research but have mostly returned fruitless... I need to loop the "buttonOneClick for one second iterations. The program will send a "P" character, wait one second, send a p, wait one second, etc... Also I need to write the information it receives to an excel spreadsheet. Any help/critiquing of existing code would be greatly appreciated.
Here's what I have:
Public Class Form2
Dim buttonOnePush As Boolean = False
Dim buttonTwoPush As Boolean = False
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
' Send strings to a serial port.
Using com5 As IO.Ports.SerialPort =
My.Computer.Ports.OpenSerialPort("COM5")
com5.WriteLine("P")
End Using
End Sub
Function ReceiveSerialData() As String
' Receive strings from a serial port.
Dim returnStr As String = ""
Dim com5 As IO.Ports.SerialPort = Nothing
Try
com5 = My.Computer.Ports.OpenSerialPort("COM5")
com5.ReadTimeout = 10000
Do
Dim Incoming As String = com5.ReadLine()
If Incoming Is Nothing Then
Exit Do
Else
returnStr &= Incoming & vbCrLf
End If
Loop
Catch ex As TimeoutException
returnStr = "Error: Serial Port read timed out."
Finally
If com5 IsNot Nothing Then com5.Close()
End Try
Return returnStr
End Function
Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
If IsNumeric(TextBox1.Text) AndAlso IsNumeric(TextBox2.Text) Then
TextBox1.Text = CDec(TextBox2.Text)
End If
End Sub
Private Sub TextBox6_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox6.TextChanged
If IsNumeric(TextBox6.Text) AndAlso IsNumeric(TextBox3.Text) Then
TextBox6.Text = CDec(TextBox3.Text)
End If
End Sub
Private Sub TextBox7_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox7.TextChanged
If IsNumeric(TextBox7.Text) AndAlso IsNumeric(TextBox4.Text) Then
TextBox7.Text = CDec(TextBox4.Text)
End If
End Sub
Private Sub TextBox8_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox8.TextChanged
If IsNumeric(TextBox8.Text) AndAlso IsNumeric(TextBox5.Text) Then
TextBox8.Text = CDec(TextBox5.Text)
End If
End Sub
Private Sub TextBox15_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox15.TextChanged
If IsNumeric(TextBox15.Text) AndAlso IsNumeric(TextBox16.Text) Then
TextBox15.Text = Hex(TextBox16.Text)
End If
End Sub
Private Sub TextBox14_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox14.TextChanged
If IsNumeric(TextBox14.Text) AndAlso IsNumeric(TextBox11.Text) Then
TextBox14.Text = Hex(TextBox11.Text)
End If
End Sub
Private Sub TextBox13_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox13.TextChanged
If IsNumeric(TextBox13.Text) AndAlso IsNumeric(TextBox10.Text) Then
TextBox13.Text = Hex(TextBox10.Text)
End If
End Sub
Private Sub TextBox12_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox12.TextChanged
If IsNumeric(TextBox12.Text) AndAlso IsNumeric(TextBox9.Text) Then
TextBox12.Text = Hex(TextBox9.Text)
End If
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
buttonTwoPush = True
buttonOnePush = False
Me.Close()
Form1.Close()
End Sub
End Class
Use a Timer to issue that command at one second intervals. Drag a Timer over to your form from the toolbox, and double click on it to get a _Tick method.
Set the .Interval member of the timer in your form's constructor, and use the .Start and .Stop methods to control it.
For the Excel piece, you'll need to add a reference to the project for the Microsoft Excel 12.0 (or 14.0 if you have Excel 2010) Object Library. Find this under the COM tab of the Add Reference dialog which you get by right clicking on the project in the Solution Explorer. See this page for an exhaustive reference (scroll down to the bottom of the page for a quick example in VB.NET).
After searching around I am still having issues with reading data from a serial port in VB.Net/VS2010. I know the Serial Port works, I can write to the port fine but when reading from it, nothing happens. I have only been programming for the last 3 weeks so am still trying to get my head around it all.
The program must run to capture data from a door logger, I will then be outputting the data to a database (not yet implemented - I want to get this part sorted first).
I have tried using several terminal programs as well as another device which outputs data onto the serial line, with nothing displaying in the textbox tbxIn.
Any help would be greatly appreciated.
Code is below:
Imports System.IO.Ports
Imports System.IO.Ports.SerialPort
Public Class Form1
Dim comPort As IO.Ports.SerialPort = Nothing
Dim sComPort As String = ""
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
GetSerialPortNames()
End Sub
Sub GetSerialPortNames()
' Show all available COM ports.
For Each sp As String In My.Computer.Ports.SerialPortNames
lstPorts.Items.Add(sp)
Next
End Sub
Private Sub lstPorts_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lstPorts.SelectedIndexChanged
sComPort = lstPorts.SelectedItem
Button1.Enabled = True
End Sub
Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
' Open the serial port using the OpenSerialPort method
Button1.Enabled = False
Button2.Enabled = True
Try
comPort = My.Computer.Ports.OpenSerialPort(sComPort, 9600, IO.Ports.Parity.None, 8, 1)
' comPort.DtrEnable = True
comPort.ReadTimeout = 500
Do
comPort.WriteLine("Go")
Dim sIncomming As String = comPort.ReadLine()
tbxIn.Text = sIncomming & vbCrLf
Loop
Catch ex As TimeoutException
tbxIn.Text &= "Error: Serial Port Read Timeout" & vbCrLf
End Try
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
comPort.Close()
Button1.Enabled = True
Button2.Enabled = False
End Sub
Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
tbxIn.Text = e.ToString
End Sub
End Class
PRetty sure this will get you what you need. You DON't need the Serial1 component on the designer. Remove that and use this code:
Private comPort As IO.Ports.SerialPort = Nothing
Private sComPort As String = ""
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
GetSerialPortNames()
End Sub
Sub GetSerialPortNames()
' Show all available COM ports.
For Each sp As String In My.Computer.Ports.SerialPortNames
lstPorts.Items.Add(sp)
Next
End Sub
Private Sub lstPorts_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lstPorts.SelectedIndexChanged
sComPort = lstPorts.SelectedItem
Button1.Enabled = True
End Sub
Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
' Open the serial port using the OpenSerialPort method
Button1.Enabled = False
Button2.Enabled = True
Try
comPort = My.Computer.Ports.OpenSerialPort(sComPort, 9600, IO.Ports.Parity.None, 8, 1)
' comPort.DtrEnable = True
'must add handler
AddHandler comPort.DataReceived, AddressOf SerialPort1_DataReceived
comPort.ReadTimeout = 500
Do
comPort.WriteLine("Go")
Dim sIncomming As String = comPort.ReadLine()
tbxIn.Text = sIncomming & vbCrLf
Loop
Catch ex As TimeoutException
tbxIn.Text &= "Error: Serial Port Read Timeout" & vbCrLf
End Try
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
comPort.Close()
'remove handler
RemoveHandler comPort.DataReceived, AddressOf SerialPort1_DataReceived
Button1.Enabled = True
Button2.Enabled = False
End Sub
Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs)
tbxIn.Text = e.ToString
End Sub