Why does the Arduino delay receiving data from Visual Basic.NET? - vb.net

This is the Arduino code for the receiver
void loop() {
int dir = Serial.read();
if (dir == 'A') {
Motors();
}
if (dir == 'B') {
Zero();
}
}
and this Visual Basic.NET Code
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If Button1.Enabled = True Then
SerialPort1.Open()
SerialPort1.Write("A")
SerialPort1.Write(txtAngle1Mr.Text + Chr(13))
SerialPort1.Close()
End If
End Sub
okay when I click on the button , my program write "A" ON SERIAL
And if write "A" ON SERIAL
Arduino Will Run "Motors" Function
Arduino is Delaying to receive data from Visual Basic.NET and run "Motors" Function
Arduino runs "Motors" Function. but he's Delaying
why Arduino is Delaying ?
and how can I solve this ?

I solved problem
In VisualBasic.NET I was sending one value by just 1 code.
SerialPort1.Write(TextBox1.Text + Chr(13))
and in Arduino I was receving the data by just one code
int example 1 = Serial.parseInt();
the problem is
in arduino I was receving more than value and I just send one value!
I was receiving data that I did not send!
in VisualBasic I wrote this
SerialPort1.Write(TextBox1.Text + Chr(13))
in Arduino I wrote this
int example1 = Serial.parseInt();
int example2 = Serial.parseInt();
int example3 = Serial.parseInt();
int example4 = Serial.parseInt();
look. I was sending one value and the arduino was trying to receive more than one value
This is why the Arduino was late in receiving data
I hope you understand me
Thank you all

Related

How to use visual basic to read data byte-by-byte via serial communication?

I am trying to read out some serial data from my STM32 board to GUI, and also, I have trouble closing down my serial communication port.
I am using 2013 Visual Studio and chose Visual Basic as my programming language. What I wanted to send from the microcontroller is some serial data that I sent byte-by-byte. So, for example, I will be sending "<abcde>" from my microcontroller with "<" and ">" as my start and stop bit; and hopefully my visual basic GUI will read and display it.
I have tried to display it at visual basic using serialport.readexisting() with no problem, but then I need to separate each bytes by itself. In the end, I wanted my program to read and process each byte, which will be some sensor values and can display it in the VB program.
I have tried using both serialport.read() and serialport.readbyte() but I don't know why, it does not show the correct output. What I meant of not correct is that the ascii code nor characters does not represent on what I sent from the microcontroller.
Here is the time when I use readbyte().
'Visual Basic --> for serialport.readbyte()
Dim buff_rx As Byte
Private Sub SerialPort1_DataReceived_1(sender As Object, e As SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
SerialPort1.ReadTimeout = 20
Do While SerialPort1.BytesToRead > 0
Try
buff_rx = SerialPort1.ReadByte
Me.Invoke(New EventHandler(AddressOf update_dat))
Catch ex As Exception
End Try
Loop
End Sub
Public Sub update_dat(ByVal sender As Object, ByVal e As System.EventArgs)
Dim i As Integer = buff_rx
Dim s As String = ""
s = i.ToString("X2") 'if wanted to be in hex, use "X2"
Rx_text.Text = Rx_text.Text & " " & i
End Sub
Here is the part when I tried using the read() part.
'Visual Basic --> for serialport1.read()
Private Sub SerialPort1_DataReceived_1(sender As Object, e As SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
Dim bytestoread As Int16
bytestoread = SerialPort1.BytesToRead
Dim buff(bytestoread) As Byte
ReceivedText(SerialPort1.Read(buff, 0, bytestoread - 1))
End Sub
Private Sub ReceivedText(ByVal [text] As String)
If Me.Rx_text.InvokeRequired Then 'form 1 is Me'
Dim k As New SetTextCallback(AddressOf ReceivedText)
Me.Invoke(k, New Object() {(text)})
Else
Me.Rx_text.Text &= [text]
End If
End Sub
This part below is when I send the data from microcontroller
//Microcontroller side, data sending
tx3_buff[0] = '<'; //ascii code: 60
tx3_buff[1] = 'b'; //ascii code: 98
tx3_buff[2] = 'c'; //ascii code: 99
tx3_buff[3] = 'd'; //ascii code: 100
tx3_buff[4] = 'e'; //ascii code: 101
tx3_buff[5] = 'f'; //ascii code: 102
tx3_buff[6] = 'g'; //ascii code: 103
tx3_buff[7] = 'h'; //ascii code: 104
tx3_buff[8] = 'i'; //ascii code: 105
tx3_buff[9] = '>'; //ascii code: 62
The data that I was intended to send from the microcrontroller are shown on the code as well. As I mentioned before, when I used the serialport.readexisting(), I can correctly read "". But when I use either serialport.readbyte() and serialport.read() it reads:
160 16 161 33 198 18 52 68 84 200 232 16 40 200
and so on and so on which is definitely incorrect and made nonsense.
In terms of the close() problem, I put the serialport.close() inside the button function. I already tried from some forums that stated we should use begininvoke instead of only using invoke (like here: https://blogs.msdn.microsoft.com/bclteam/2006/10/10/top-5-serialport-tips-kim-hamilton/)
But it still won't work.
Here is the Close button part:
'Visual Basic --> for disconnect button
Private Sub Button5_Click_1(sender As Object, e As EventArgs) Handles Button5.Click
SerialPort1.Close()
End Sub
Everytime after I pressed this button, it will always be stuck and hanged. I need to restart the program so this problem will be solved. Any ideas for this part?
To easily summarize, here are my problems:
I have literally no idea how to use the serialport.readbyte() and serialport.read(). I really need this as I wanted to separate the data byte-by-byte so I can process it easily.
The serialport.close() button always hangs and I don't know why.
I hope someone can help me with these problems. Thank you in advance for all your help and sorry if my thread is messy!
Thank you again!
Buff_Rx is a byte array and can't be assigned to an integer:
Dim i As Integer = buff_rx

Event Handling form C# to vb.net

I inherited this code from a C# sdk and I'm trying to convert it to vb.net. As I'm a bit new to vb.net, with the aid of some online converters I managed to convert it as below:
Original Code:
private void ScanThreadPorc()
{
while (true)
{
uint evt = Win32.WaitForMultipleObjects(2, hEvent, false, Win32.INFINITE);
switch (evt)
{
case 0://return thread
return;
case 1://disable network
uint bytesRead;
uint flags;
byte[] buf = new byte[256];
if (Win32.ReadMsgQueue(hEvent[1], buf, 256, out bytesRead, Win32.INFINITE, out flags))
{
EventHandler<DecodeEventArgs> temp = DecodeEvent;
if (temp != null)
{
temp(this, new DecodeEventArgs(Encoding.Default.GetString(buf, 2, (int)bytesRead), buf[1]));
}
}
break;
}
}
}
Converted Code
Private Sub ScanThreadPorc()
While (True)
Dim evt As UInteger = Win32.WaitForMultipleObjects(2, hEvent, False, Win32.INFINITE)
Select Case evt
Case 0 '://return thread
Return
Case 1 '://disable network
Dim bytesRead As UInteger
Dim flags As UInteger
Dim buf As Byte() = New Byte(255) {}
If Win32.ReadMsgQueue(hEvent(1), buf, 256, bytesRead, Win32.INFINITE, flags) Then
Dim temp As EventHandler(Of DecodeEventArgs) = DecodeEvent
RaiseEvent temp(Me, New DecodeEventArgs(Encoding.[Default].GetString(buf, 2, CInt(bytesRead)), buf(1)))
End If
End Select
End While
End Sub
I have 2 errors on DecodeEvent that says
Public Event DecodeDevent (sender as object, e as DecodeEventArgs) is an event and cannot be called directly. Use a raise statement to raise an event.
And the second error on temp that says
temp is not an event of myapplication.mynamespace.myclass.
I have read about 10 related topics on this and other forums but I'm unable to adapt the answers to my code.
Please help. Thanks

VB.NET Convert USB as RS232

I have a hardware with USB for communicate between computer to hardware. The vendor not giving any APIs to connect to the device. They give me a protocol. But the protocol is serve for RS232 mode. I ask the vendor whether this protocol can be apply to the USB, they said 'YES'.. So, I'm thirst of idea how to use this protocol. Does anyone know? My old friend said yes I can use the USB and treat is as COM which I need to create an object. Create instance of the object which declare as a serialport as below. But it still can't get the status.
Public Sub New(ByVal intComNumber As Integer, ByVal lngBaudRate As Long, ByVal intDataLng As Integer, ByVal intStopBit As Integer, ByVal intParity As Integer)
Try
objUPSPort = New SerialPort
With objUPSPort
.PortName = ("COM" & intComNumber)
.BaudRate = lngBaudRate
.DataBits = intDataLng
.StopBits = intStopBit
.Parity = intParity
.Handshake = Handshake.None
End With
Catch ex As Exception
MsgBox("Error In Init UPSComm")
End Try
End Sub
Can someone help me identified this? This hardware is UPS. A simple command write to the port. But I get the error when get status. Below is the code to write to the UPS.
Public Function GetStatus() As String
Dim strRet As String
Dim strRecv As String
Dim byteRead() As Byte
Try
If Not IsNothing(objUPSPort) Then
objUPSPort.Open()
objUPSPort.WriteLine("Command will be here" & vbCrLf)
For i = 0 To 100000
If objUPSPort.BytesToRead >= 45 Then
Exit For
End If
Next
ReDim byteRead(objUPSPort.BytesToRead)
objUPSPort.Read(byteRead, 0, objUPSPort.BytesToRead)
strRecv = String.Empty
For i = 0 To byteRead.Length - 1
strRecv = strRecv & Chr(byteRead(i))
Next
If byteRead(38) = 48 Then
MsgBox("Power OK")
ElseIf byteRead(38) = 49 Then
MsgBox("Power Off")
Else
MsgBox("Unknown")
End If
strRet = strRecv
Return strRecv
Else
MsgBox("Error In ComPort Object")
Return String.Empty
End If
Catch ex As Exception
MsgBox("Exception In ComPort Object - " & ex.Message)
Return String.Empty
Finally
objUPSPort.Close()
End Try
End Function
I had few experiences in RS232 comm with USB, as nowadays laptops/pc they dont come with serial port no more. Serial ports usually emulated by USB, using [TTL-to-RS232 transistor, MAX like] some common supplier would use prolific as driver to emulate USB-to-RS232. First you need to know the data type, a simple string or binary.
SerialPorts is event driven, data coming thru the ports can trigger events. I assume to get UPS to send you status, first, you need to send command, as such [some pseudo];
objUPSPort.WriteLine("Command will be here" & vbCrLf)
There two ways to get the data:
Using data receive event driven :
Private Sub objUPSPort_DataReceived(sender As Object, e As IO.Ports.SerialDataReceivedEventArgs) Handles objUPSPort.DataReceived
'call ReceiveData()
End Sub
Create a pooling thread to read data periodically
Private Sub threadUPSReceive()
Do
data = objUPSPort.ReadLine() 'for string
'process the data here or call ReceiveData()
Loop
End Sub
If data stream to be read is binary (similar like yours):
Private Function ReceiveData()
Dim bRead As Integer
Dim returnStr As String = vbEmpty
bRead = objUPSPort.BytesToRead 'Number of Bytes to read
Dim cData(bRead - 1) As Byte
For Each b As Byte In cData
returnStr += Chr(b) 'put data stream in readable ascii
Next
Return returnStr
End Sub
One more thing, make sure the baudrate/stopbit/databit is set correctly.
Hope this help.

What is the equivalent of My.Resources in Visual-C++?

I need to iterate through all the resources in a project and basically output their names. I have this done in VB. But I can't figure out what the equivalent of My.Resources.ResourceManager is in VC++.
Here's the VB code.
Dim objResourceManager As Resources.ResourceManager = My.Resources.ResourceManager
Dim objResourceSet As Resources.ResourceSet = objResourceManager.GetResourceSet(CultureInfo.CurrentCulture, True, True)
Dim iterator As IDictionaryEnumerator = objResourceSet.GetEnumerator()
Private Sub go()
Dim s As String = iterator.Key
Debug.WriteLine(s)
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If iterator.MoveNext Then
go()
Else
iterator.Reset()
If iterator.MoveNext Then
go()
Else
Throw New Exception("No elements to display")
End If
End If
End Sub
And this is how far I am in VC++.
private:
Resources::ResourceManager^ rmgnr;
Resources::ResourceSet^ rSet;
public:
Form1(void)
{
rmgnr = gcnew System::Resources::ResourceManager(L"Resources ProjectCPP",Reflection::Assembly::GetExecutingAssembly());
//This is the problem as I can't find the equivalent in c++
rSet = rmgnr->GetResourceSet(CultureInfo::CurrentCulture,true,true);
Please help me figure this out.
I think you just want:
rmgnr = gcnew System::Resources::ResourceManager(GetType());
You can use something like the following for unmanaged C++:
HRSRC hResInfo = FindResource(hInstance, MAKEINTRESOURCE(resourceId), type);
HGLOBAL hRes = LoadResource(hInstance, hResInfo);
LPVOID memRes = LockResource(hRes);
DWORD sizeRes = SizeofResource(hInstance, hResInfo);
You will need to change the type and resourceId to match your resource. Not sure if its an image or icon or what kind of resource, but you would use something like:
FindResource(hInstance, MAKEINTRESOURCE(bitmapId), _T("PNG"));
For Managed C++, try something like the following:
Bitmap *MyBitmap;
String *Msg;
Reflection::Assembly *MyAssembly;
IO::Stream *ResourceStream;
MyAssembly = System::Reflection::Assembly::GetExecutingAssembly();
ResourceStream = MyAssembly->GetManifestResourceStream(ImageName);
if (ResourceStream != NULL)
{
MyBitmap = new Bitmap(ResourceStream);
Msg = String::Format("GetIcon: {0}, OK", ImageName);
}
else
Msg = String::Format("GetIcon: {0}, Failed", ImageName);
// MyBitmap countains your resource
You will need to replace ImageName with the name of your resource you are trying to grab. Again, I'm assuming its an image resource you are trying to grab.

Receiving Invalid Data From Serial Port using SerialPort.ReadExisting()

Recently we have connected one bluetooth device which receive data from our serial device. The bluetooth device further transmite this data to a Windows Mobile which is bluetooth enable. Baud rate of whole system is 19200 with 7 data bit and 1 stop bit.When we send command to serial device through bluetooth device it is accepting the command and respond accordingly. but some of data byte of string is desplay as question mark (?).
But in case we connect the serial device directly to PC, the string received is correct.
Code of vb.net program which I run in windows mobile is below:
Imports System
Imports System.IO.Ports
Imports System.Windows.Forms.TextBox
Public Class frmSelectComPort
Dim WithEvent port1 as serialport = _
New SerialPort(“Com2”,19200,Parity.Even, 7, StopBits.One)
Private Sub MnuConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MnuConnect.Click
If port1.IsOpen Then
port1.Close()
End If
port1.DtrEnable = True
port1.RtsEnable = True
port1.ReceivedBytesThreshold = 1
port1.Open()
Dim str1,strcmd,strReadSegment0 As String
Str1="09RD000001"
strchksum=23
strcmd = New String(Chr(2) + str1 + Chr(3) + strchksum) + Chr(0)
Delay(5000)
port1.Write(strcmd, 0, strcmd.Length)
System.Threading.Thread.Sleep(70)
Delay(2000)
strReadSegment0 = port1.ReadExisting
‘here I receive the following string "?09?D03?A D?
End Sub
Private Sub Delay(ByVal num As Double)
Dim i As Double
For i = 0 To num
Next
End Sub
End Class
Command Given to Serial Port is " 09RD000001 23
Response given by Serial Port is "?09?D03?A D?
But I Expect the following input from serial port : " 09RD033A DA
Kindly provide the solution ASAP
Have you tried 8 databits, no parity, 1 stop bit? As long as both ends are set the same...
The ? can indicate that the encoding needs to be set.
Dim myEnc As Encoding = Encoding.GetEncoding("Windows-1252")
port1.encoding=myEnc