The DataReceived event is raised on a secondary thread when data is received from the SerialPort object. Because this event is raised on a secondary thread, and not the main thread, attempting to modify some elements in the main thread, such as UI elements, could raise a threading exception. If it is necessary to modify elements in the main Form or Control, post change requests back using Invoke, which will do the work on the proper thread.
I had a similar problem few days ago, the solution (in C++/CLI) was to use something like this:
Suppose that you put an object in front of the sensor at a distance of 5 cm. You are then sending "5 cm\r\n" to the serial port. You are asking VB to convert that to an int. Is there any real reason to send data that VB needs to discard?
How is VB supposed to know when to stop reading from the serial port? If the Arduino sends "5 cm\r\n 6 cm\r\n" before the VB app gets around to reading it, what do you expect the VB app to show in the text box?
there is no problem if using the serial monitor. i want the vb to display the distance same like appear in serial monitor. so what should i do to display that data? i have tried many code but it still not working
i want the vb to display the distance same like appear in serial monitor.
Then, why are you forcing the text received from the serial port to be converted to an integer?
Why are you expecting the SensorTextBox object's Text property setter to deal with an integer?
Dim Distance As Integer = SerialPort1.ReadExisting
SensorTextBox.Text = Distance
The Serial Monitor application makes no such demands on the data. It treats all the input as text.
im have a problem to display my ultrasonic sensor data from Arduino into visual basic. it works if using the serial monitor and i got my data in. but when im trying to display these data on visual basic, im unable to display the sensor data.
this is my code for arduino
int trigPin = 8;
int echoPin = 9;
void setup(void)
{
Serial.begin(19200);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop(void)
{
if(Serial.available()){
//Create new variable val
char val = Serial.read();
if(val != -1)
{
switch(val)
{
case 'c':
ultrasonicSensor(); //Print the Sensor data
break;
}
}
}
void ultrasonicSensor()
{
int Duration, Distance;
digitalWrite(trigPin, HIGH);
delayMicroseconds(1000);
digitalWrite(trigPin, LOW);
Duration = pulseIn(echoPin, HIGH);
Distance = (Duration/2) / 29.1;
Serial.println(Distance);
delay(500);
}
and this is the code for Visual Basic
Imports System
Imports System.IO.Ports
Imports System.ComponentModel
Imports System.Threading
Public Class Form1
Dim myPort As Array
Dim Distance As Integer
Delegate Sub SetTextCallBack(ByVal [text] As String)
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
myPort = IO.Ports.SerialPort.GetPortNames()
PortComboBox.Items.AddRange(myPort)
BaudComboBox.Items.Add(9600)
BaudComboBox.Items.Add(19200)
BaudComboBox.Items.Add(38400)
BaudComboBox.Items.Add(57600)
BaudComboBox.Items.Add(115200)
ConnectButton.Enabled = True
DisconnectButton.Enabled = False
End Sub
Private Sub ConnectButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ConnectButton.Click
SerialPort1.PortName = PortComboBox.Text
SerialPort1.BaudRate = BaudComboBox.Text
SerialPort1.Open()
Timer1.Start()
lblMessage.Text = PortComboBox.Text & " Connected."
ConnectButton.Enabled = False
DisconnectButton.Enabled = True
End Sub
Private Sub DisconnectButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DisconnectButton.Click
SerialPort1.Close()
lblMessage.Text = SerialPort1.PortName & " Disconnected."
DisconnectButton.Enabled = False
ConnectButton.Enabled = True
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Try
SerialPort1.Write("c")
System.Threading.Thread.Sleep(250)
Dim distance As string = SerialPort1.ReadExisting()
ListBoxSensor.Text = distance
Catch ex As Exception
End Try
End Sub
End Class
is there any error on my code because im unable to display the data into visual basic. please help me.
thanks.
Here's the timing for the first time you send C to the Arduino
VB: sends 'c' to the serial port
VB: sleep for 250ms
Arduino: reads serial. if 'c' call ultrasonicSensor
Arduino: writes HI to trigger pin
Arduino: sleeps for 250ms (of 1000ms)
VB: reads serial port and adds result to listbox
Arduino: completes remaining 750ms of 1000ms sleep
Arduino: writes LO to trigger pin
etc
did you try sending the c twice in a row? You may read something in the second time.
did you try sending the c twice in a row? You may read something in the second time.
do you mean like this
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Try
SerialPort1.Write("c")
SerialPort1.Write("c")
System.Threading.Thread.Sleep(250)
Dim i As UShort = SerialPort1.ReadExisting()
ListBoxSensor.Text = "" + i.ToString()
Me.Refresh()
Catch ex As Exception
End Try
i tried it but still no data displayed. yup, im using timer and the interval is 1000.
im a beginner in vb programming. can you help me fix my code. i have no idea what to do now.
The same one that the Serial Monitor uses and that the Arduino outputs - String.
i've changed the data type into string but still no data displayed in textbox. i tried with another way to get the sensor value. i send the "c" character to arduino and arduino print the sensor value.below is the code
int trigPin = 8;
int echoPin = 9;
void setup(void)
{
Serial.begin(19200);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop(void)
{
if(Serial.available()){
char val = Serial.read();
if(val != -1)
{
switch(val)
{
case 'c':
ultrasonicSensor(); //Print the Sensor value
break;
}
}
}
}
void ultrasonicSensor()
{
int Duration, Distance;
digitalWrite(trigPin, HIGH);
delayMicroseconds(1000);
digitalWrite(trigPin, LOW);
Duration = pulseIn(echoPin, HIGH);
Distance = (Duration/2) / 29.1;
Serial.println(Distance);
delay(500);
}
in visual basic, im using the timer to send the "c" character.below is the code
Imports System
Imports System.IO.Ports
Imports System.ComponentModel
Imports System.Threading
Public Class Form1
Dim myPort As Array
Dim Distance As Integer
Delegate Sub SetTextCallBack(ByVal [text] As String)
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
myPort = IO.Ports.SerialPort.GetPortNames()
PortComboBox.Items.AddRange(myPort)
BaudComboBox.Items.Add(9600)
BaudComboBox.Items.Add(19200)
BaudComboBox.Items.Add(38400)
BaudComboBox.Items.Add(57600)
BaudComboBox.Items.Add(115200)
ConnectButton.Enabled = True
DisconnectButton.Enabled = False
End Sub
Private Sub ConnectButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ConnectButton.Click
SerialPort1.PortName = PortComboBox.Text
SerialPort1.BaudRate = BaudComboBox.Text
SerialPort1.Open()
lblMessage.Text = PortComboBox.Text & " Connected."
ConnectButton.Enabled = False
DisconnectButton.Enabled = True
End Sub
Private Sub DisconnectButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DisconnectButton.Click
SerialPort1.Close()
lblMessage.Text = SerialPort1.PortName & " Disconnected."
DisconnectButton.Enabled = False
ConnectButton.Enabled = True
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Try
SerialPort1.Write("c")
System.Threading.Thread.Sleep(250)
Dim i As String = SerialPort1.ReadExisting()
ListBoxSensor.Text = i
Me.Refresh()
Catch ex As Exception
End Try
End Sub
End Class
on timer, i set the interval to 1000. but still not working. whats wrong actually?
the unit is ms.the vb app send c character and sleep for 250ms.
i;ve tried with your suggestion but still not working. if im using the button with click event, i need to use the serial port data_received event right?
the RX led on arduino is blinking when i click any button on vb app but the RX led doesn't blink. thats mean no data is sent from arduino to vb app isn't it?