Receive and Display Serial Data in Visual Basic?

hi all,

i got a problem to receive the data from sensor into my visual basic

this is my code for arduino

int trigPin = 3;
int echoPin = 2;

void setup(){
Serial.begin(19200);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}

void loop(){
int Duration, Distance;
digitalWrite(trigPin, HIGH);
delayMicroseconds (1000);
digitalWrite(trigPin, LOW);
Duration = pulseIn(echoPin, HIGH);
Distance = (Duration/2) / 29.1;
Serial.print(Distance);
Serial.println(" cm");
delay(500);
}

this is my code for visual basic

Imports System.IO
Imports System.IO.Ports
Imports System.Threading

Public Class Form1
Dim myPort As Array
Delegate Sub SetTextCallBack(ByVal

What happens if you just use the serial monitor instead of the VB?

(please use code tags when posting code)

Hello, I think your problem is that:

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:

//in the Form constructor:
this->serialPort1->DataReceived += gcnew SerialDataReceivedEventHandler(this, &Form1::DataReceivedHandler);

...

private: System::Void DataReceivedHandler(Object^ sender, SerialDataReceivedEventArgs^ e)
{
	Monitor::Enter(this);
		
	try
	{
		while (this->serialPort1->BytesToRead > 0)
		{
			if ( Math::Min(this->serialPort1->BytesToRead, this->serialPort1->ReadBufferSize) > 0)
			{
				String^ input = this->serialPort1->ReadExisting();
				this->textBox2->AppendText( input );
			}
		}
	}
	
	catch ( Exception^ e )
	{
		this->label1->Text = e->Message;
	}
	
	finally
	{
		Monitor::Exit(this);
	}
}

Not sure if that will help you...

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?

hi all,

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.

i am beginner in this thing.so i need to change to another data type.is it?

hi all,

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.

Ah it's a timer. What is the interval of the timer?

And look into asynchronous serial port methods too - synchronous is ugly.

i am beginner in this thing.so i need to change to another data type.is it?

Yes. The same one that the Serial Monitor uses and that the Arduino outputs - String.

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?

thanks for your reply.

            System.Threading.Thread.Sleep(250)

What it the unit for 250? Is this sleeping for 6+ minutes or 1/4 of a second?

Instead of a timer, use a button with a click event. Step through the code using the debugger.

Instead of something complicated for the Arduino to do (read a ping sensor), make it do something simple:

  if(Serial.available())
  {
    char val = Serial.read();
    Serial.print("Hey, Joe!");
  }

Instead of a one letter message to the Arduino, send a bunch of stuff:

            SerialPort1.Write("Hey, what a beautiful day. Isn't it great to be alive?")

Then, pay attention to the RX LED on the Arduino. Is it actually receiving anything when you click the button in the VB app?

im a beginner in vb programming.

But, apparently not to crossposting.

i have no idea what to do now.

Well, I have an idea.

What it the unit for 250?

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?

Well, I have an idea.

you already told me on the other post. i tried it but still not working. do you have another idea? let just discuss here.

the RX led on arduino is blinking when i click any button on vb app but the RX led doesn't blink.

Does she? Or doesn't she? Only her hairdresser knows for sure.

Please do not cross-post. This wastes time and resources as people attempt to answer your question on multiple threads.

Threads merged.

  • Moderator