How to send a data array from an Arduino to vb - vb.net

I am trying to send data bytes from an Arduino to my visual basic app, but it does not work. I've already tried several solutions but I don't get the values back, I've send to the arduino.
The code I'm using for the visual basic app:
Private Sub DataReceivedHandler(sender As Object, e As SerialDataReceivedEventArgs)
Dim bytes As Integer = 6
Dim comBuffer As Byte() = New Byte(bytes - 1) {}
'read the data and store it
SerialPort1.Read(comBuffer, 0, bytes)
Dim aryReceived(10) As Integer
For i As Integer = 1 To (bytes - 1)
aryReceived(i) = comBuffer(i)
Y(i) = aryReceived(i)
Next
a = comBuffer(1)
b = comBuffer(2)
End Sub
Private Sub Verzenden()
Dim waardes() As Byte
waardes = {X(1), X(2), X(3), X(4), X(5), X(6)}
If SerialPort1.IsOpen = True Then
SerialPort1.Write(waardes, 0, waardes.Length)
End If
End Sub
Private Sub VerzendButton_Click(sender As Object, e As EventArgs) Handles VerzendButton.Click
X(1) = 10
X(2) = 11
X(3) = 12
X(4) = 13
X(5) = 14
X(6) = 15
Verzenden()
End Sub
and the arduino code:
int x[9];
void setup() {
Serial.begin(9600);
}
void loop() {
if(Serial.available() >= 6){
for(int i = 1; i < 7; i++){
x[i] = Serial.read();
}
for(int i = 1; i < 7; i++){
Serial.println(x[i]);
}
}
}
I send 6 bytes to the arduino with the following values: 10, 11, 12, 13, 14 & 15, but sometimes I have to send the bytes twice before the debugger breaks. The values that return in a & b are not the same as I send. The code for sending the bytes works fine.
Can someone help me?

The breakpoint I've set is at the 'end sub' command of the receive event. I often get for a 51 and for b 56, but they're random at other times.
X, Y and a & b are all defined in the public.
Public Class Form1
Dim indata As Integer
Dim Setting As New My.MySettings()
Dim Opstartmodus As Byte
Dim OpstartCOMpoort As String
Dim myPort As Array
Delegate Sub SetTextCallBack(ByVal [text] As String)
Dim a As Byte, b As Byte, c As Byte, d As Byte, f As Byte, g As Byte
Dim WaardeVerzenden As Byte, X(9) As Byte, Y(9) As Byte
Edit: I've added a delay of 500 microseconds in the arduino code between the receive action and the sens action. Now, After one click on the send button, the debugger breaks immediately. Thats one problem solved! But now, I get always the following patter back: 49,48,13,10,49,49. That totaly doesn't match with the pattern I send to the Arduino:(

I found the solution;) I have Serial.println replaced by Serial.write(x,6). In the Visual Basic app I replaced the reveive event with:
Private Sub SerialPort1_DataReceived(sender As Object, e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
For i As Integer = 0 To (Bytes - 1)
Y(i) = SerialPort1.ReadByte()
Next
End Sub
The Visual Basic app does now receive the data I send from the arduino:)

Related

Why is a System.ArgumentException occurring on the second or third iteration of a cryptographic line of code?

I'm getting the following error after executing code that deals with cryptography:
An unhandled exception of type 'System.ArgumentException' occurred in mscorlib.dll
Additional information: Object of type 'System.Int64' cannot be converted to type 'System.UInt32'.
A few sources (e.g. http://truncatedcodr.wordpress.com/2012/06/20/fix-sitecore-and-net-framework-4-5/ ) where a similar error occurred say to change a value to the following in Web.config (pardon the space after the "less than" sign):
< setting name=”Login.RememberLastLoggedInUserName” value=”false” />
I have never used a Web.config file before, so this could be the solution. However, my project doesn't have one (I'm not sure if it could have one since I don't think it has a web site name) and I don't know why there were apparent successes in the previous iteration(s). Anyway, here is the portion of my code that contains the problem (I took out some irrelevant code):
Dim stream As IO.FileStream
Dim dataOffset As Int64
Dim dataSize As Int64
Dim del2 As New ChangeProgress2Delegate(AddressOf ChangeProgress2)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim fileDialog As New OpenFileDialog()
fileDialog.ShowDialog()
stream = New IO.FileStream(fileDialog.FileName, IO.FileMode.Open, IO.FileAccess.ReadWrite)
Dim t As New Threading.Tasks.Task(AddressOf Perform)
t.Start()
End Sub
Public Sub Perform()
Dim Key(15) As [Byte]
Dim Bytes(15) As [Byte]
Dim IV(15) As [Byte]
Dim userData(31743) As [Byte]
Dim encryption2 As Security.Cryptography.Aes
Dim decryptor2 As Security.Cryptography.ICryptoTransform
Dim msDecrypt2 As IO.MemoryStream
Dim csDecrypt2 As Security.Cryptography.CryptoStream
For i As UInt32 = 0 To 3
.
.
.
For j As UInt32 = 0 To (numPartitions - 1)
.
.
.
dataOffset = Convert.ToUInt32((Convert.ToUInt64(stream.ReadByte()) << 24) + (Convert.ToUInt64(stream.ReadByte()) << 16) + (Convert.ToUInt64(stream.ReadByte()) << 8) + Convert.ToUInt64(stream.ReadByte())) >> 2
dataSize = Convert.ToUInt32((Convert.ToUInt64(stream.ReadByte()) << 24) + (Convert.ToUInt64(stream.ReadByte()) << 16) + (Convert.ToUInt64(stream.ReadByte()) << 8) + Convert.ToUInt64(stream.ReadByte())) >> 2
stream.Position = dataOffset
For k = 0 To ((dataSize / 32768) - 1)
stream.Position += 976
stream.Read(IV, 0, 16)
stream.Position += 32
stream.Read(userData, 0, 31744)
encryption2 = Security.Cryptography.Aes.Create()
encryption2.Key = Key
encryption2.IV = IV
encryption2.Padding = Security.Cryptography.PaddingMode.None
decryptor2 = encryption2.CreateDecryptor(encryption2.Key, encryption2.IV)
msDecrypt2 = New IO.MemoryStream(userData)
csDecrypt2 = New Security.Cryptography.CryptoStream(msDecrypt2, decryptor2, Security.Cryptography.CryptoStreamMode.Read)
csDecrypt2.Read(userData, 0, 31744)
stream.Position -= 31744
stream.Write(userData, 0, 31744)
Debugger.Break()
Me.BeginInvoke(del2, {i + 1, j + 1, numPartitions})
Next
Next
Next
End Sub
Public Sub ChangeProgress2(ByVal partitionOrder As UInt32, ByVal partitionNum As UInt32, ByVal numPartitions As UInt32)
Progress.Value = ((stream.Position - dataOffset) / dataSize) * 100
End Sub
Public Delegate Sub ChangeProgress2Delegate(ByVal partitionOrder As UInt32, ByVal partitionNum As UInt32, ByVal numPartitions As UInt32)
In the code above, the error has been firing somewhat randomly between these three lines of code on the second or third iteration:
decryptor2 = encryption2.CreateDecryptor(encryption2.Key, encryption2.IV)
msDecrypt2 = New IO.MemoryStream(userData)
csDecrypt2 = New Security.Cryptography.CryptoStream(msDecrypt2, decryptor2, Security.Cryptography.CryptoStreamMode.Read)
I found the error. It didn't have to do with any cryptography even though the exception was firing around those lines of code. At the BeginInvoke line, I needed to convert the parameters into UInt32 so that code looked like:
Me.BeginInvoke(del2, {Convert.ToUInt32(i + 1), Convert.ToUInt32(j + 1), Convert.ToUInt32(numPartitions)})
I had to do this even though i was a UInt32, j was a UInt32, and numPartitions was a UInt32.

Using the serial port

For some time I've been working on learning how to program VB.NET. With the help of this page and the internet, I managed to create a program that sends some hex values to an interface box and get a routine response from it.
The problem here is that the communication was TCP/IP. But now I have a new box with a USB interface and now I do not have the slightest idea of how to send and receive those same hex values using the Serial port.
Below is the code. I don't know if someone could help me set it up for a serial port named COM13 or at least explain to me what to do.
This is what the program does.
Push scan
Connects to the TCP/IP of the BOX (10.2.12.65)
Sends the activation protocol E1 33
Sends the get date command 05 6c 29 f1 3c 81
Box responds back date with bytes
When the program reads the byte corresponding to 81(hex) it starts converting them into characters and adding them to a string to be displayed on the textbox on the bottom.
That's basically it. The problem is that until now I have been able to send only text strings but the box does not recognize it and it responds garbage and not the date.
Here is the code:
Imports System.Net.Sockets
Imports System.Threading
Imports System.IO
Public Class Form1
Dim client As New TcpClient
Dim transmit As NetworkStream
Dim protocol As Byte()
Dim data As Byte()
Dim ByteArrayToHexStr As String = String.Empty
Dim message As String
Dim datos_byte As Byte()
Dim respuesta As [String] = [String].Empty
Dim transision As [String] = [String].Empty
Dim Date_full As [String] = [String].Empty
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
TextBox1.Clear()
client = New TcpClient("10.2.12.65", 10001)
transmit = client.GetStream()
protocol = {225, 51} ' E1 33 in hex value
transmit.Write(protocol, 0, protocol.Length)
Thread.Sleep(45)
data = {5, 108, 41, 241, 60, 129} ' 05 6c 29 f1 3c 81 in hex value
transmit.Write(data, 0, data.Length)
data = New Byte(66) {}
Thread.Sleep(45)
Dim bytes As Int32 = transmit.Read(data, 0, data.Length)
Dim Date1 As String = String.Empty
Dim Date2 As String = String.Empty
Dim Date_temp As Integer = 0
For i As Integer = 0 To UBound(data)
Date1 = data(i)
If Date1 = "129" Then
Date_temp = i + 1
i = 1000
For k As Integer = 0 To 5
If k = 0 Then
Date1 = data(Date_temp + k)
Date_full = Chr(Date1)
Else
Date1 = data(Date_temp + k)
Date2 = Chr(Date1)
Date_full = Date_full & Date2
End If
Next
Else
End If
Next
Thread.Sleep(45)
transmit.Close()
client.Close()
TextBox1.Text = TextBox1.Text & Date_full
End Sub
End Class
Please have a look at Microsoft's example of the SerialPort class: https://msdn.microsoft.com/en-us/library/system.io.ports.serialport(v=vs.110).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-2
If you get garbage back that might indicate the baudrate is configured incorrectly. I'm not sure what you mean by 'box' but this device should have a specified baudrate which you should be able to find in its datasheet or product information.

Sorted List in Array Visual Basic [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 7 years ago.
I have a program that creates a list of 25 random numbers from 0 to 1,000. I have to buttons the first button will load a list box with the random numbers and the second button will sort the list of numbers from the smallest to largest which is where I implemented bubble sort code. Now the other list box that is supposed to hold the sorted numbers doesn't work properly it only shows one number instead of all of them.
Here is my code:
Option Strict On
Public Class Form1
Dim rn As Random = New Random
Dim Clicked As Long = 0
Dim numbers, sort As Long
Private Sub GenerateBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles GenerateBtn.Click
Clicked += 1
For x = 0 To 25
numbers = rn.Next(0, 1000)
RandomBox.Items.Add(numbers)
If Clicked >= 2 Then
RandomBox.Items.Clear()
Clicked = 1
End If
Next
End Sub
Private Sub SortBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SortBtn.Click
Dim Sorted() As Long = {numbers}
Dim Swapped As Boolean
Dim endOfArray As Integer = Sorted.Length - 1
Dim Tmp As Byte
While (Swapped)
Swapped = False
For I = 0 To endOfArray - 1
If Sorted(I) > Sorted(I + 1) Then
Tmp = CByte(Sorted(I))
Sorted(I) = Sorted(I + 1)
Sorted(I + 1) = Tmp
Swapped = True
End If
endOfArray = endOfArray - 1
Next
End While
SortBox.Items.Clear()
For I = 0 To Sorted.Count - 1
SortBox.Items.Add(Sorted(I))
Next
End Sub
End Class
Change your:
Dim Sorted() As Long = {numbers}
to
Sorted(x) = numbers
edit: Since you changed your code. You need to put back in the line that loads the Sorted Array.
For x = 0 To 25
numbers = rn.Next(0, 1000)
RandomBox.Items.Add(numbers)
Sorted(x) = numbers
If Clicked >= 2 Then
RandomBox.Items.Clear()
Clicked = 1
End If
Next
and remove the:
Dim Sorted() As Long = {numbers}
from the second part and put this declaration back in the beginning like you had:
Dim Sorted(26) as Long
The way you have will only show the latest random number. It is not any array but a single entity. Therefore only the latest will be add into the array. You need to load each number into the array as you create each one. Thus the (x) which loads it into position x.
You didn't use any arrays at all in your project...you're using the ListBox as your storage medium and that's a really bad practice.
I recommend you set it up like this instead:
Public Class Form1
Private rn As New Random
Private numbers(24) As Integer ' 0 to 24 = 25 length
Private Sub GenerateBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles GenerateBtn.Click
For x As Integer = 0 To numbers.Length - 1
numbers(x) = rn.Next(0, 1000)
Next
' reset the listbox datasource to view the random numbers
RandomBox.DataSource = Nothing
RandomBox.DataSource = numbers
' empty out the sorted listbox
SortBox.DataSource = Nothing
End Sub
Private Sub SortBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SortBtn.Click
' make a COPY of the original array that we will sort:
Dim sorted(numbers.Length - 1) As Integer
Array.Copy(numbers, sorted, numbers.Length)
Dim Swapped As Boolean = True
Dim endOfArray As Integer = Sorted.Length - 1
Dim Tmp As Integer
While (Swapped)
Swapped = False
For I As Integer = 0 To endOfArray - 1
If sorted(I) > sorted(I + 1) Then
Tmp = sorted(I)
sorted(I) = sorted(I + 1)
sorted(I + 1) = Tmp
Swapped = True
End If
Next
endOfArray = endOfArray - 1
End While
' reset the listbox datasource to view the sorted numbers
SortBox.DataSource = Nothing
SortBox.DataSource = sorted
End Sub
End Class
Also, note that you were decrementing endOfArray inside your for loop. You should only decrement it after each pass; so outside the for loop, but inside the while loop.
Additionally, you were using a Tmp variable of type Byte, but generating numbers between 0 and 999 (inclusive). The Byte type can only hold values between 0 and 255 (inclusive).
Your Bubble Sort implementation was very close to correct!

VB.Net send decimal udp

I am trying to send a single byte to a PIC from a computer (Note: the pic only accepts a single byte else it will only accept the first byte of the data send)
This shouldn't be much of a problem because I only want to manage a total of 8 LEDS so I only need it to go from 0 to 255 but I am having issues achieving this.
If I try to send the value 1 to the pic my program sends 31 if I try to send 5 it sends 35 If I try to send 255 it sends 3*2*3*5*3*5* so for every single digit I try to send it adds a 3 in front of it. I am using the following code to determine the value and to send it:
Dim t As Integer = 0
Dim result As Integer = 0
For Each chk As CheckBox In GroupBox1.Controls
If chk.Checked = True Then
result = result + 2 ^ t
End If
t = t + 1
Next
publisher.Connect(IPTo, PortTo)
Dim sendbytes() As Byte = ASCII.GetBytes(result)
publisher.Send(sendbytes, sendbytes.Length)
I think the issue is with the convert to ASCII.
I also try to receive the inputs from the PIC to my pc for this I have the following script inside a timer:
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Try
Dim ep As IPEndPoint = New IPEndPoint(IPAddress.Any, 0)
Dim rcvbytes() As Byte = subscriber.Receive(ep)
Dim translate As String
translate = System.BitConverter.ToInt32(rcvbytes, 0)
TBRcv.Text = translate
Catch ex As Exception
End Try
End Sub
ASCII.GetBytes expects a string (encoded in ASCII). Giving it an Int32 doesn't make sense.
Check out System.BitConverter.GetBytes() and System.BitConverter.ToInt32() (for the receiving end)
So the only change you'd need to make is:
Dim sendbytes() As Byte = BitConverter.GetBytes(result)
Further discussion:
What has happened is that your result (let's say 5), is first converted to string (now it's "5"), then ASCII.GetBytes will now return a byte array with a single value 0x35, because Asc("5") is 0x35.
The ASCII value of the character 1 is 0x31, etc. For reference :

How can I go about adding a ProgressBar to this code which calculates CRC32 checksum in VB.NET?

Thanks for reading - I am using the class below to calculate the CRC32 checksum of a specified file.
My question is how would I go about reporting the progress of file completion (in %) to a progressbar on a different form. I have tried (i / count) * 100 under the New() sub but I am not having any luck, or setting the progress bar with it for that matter. Can anyone help?
Thanks in advance
Steve
Public Class CRC32
Private crc32Table() As Integer
Private Const BUFFER_SIZE As Integer = 1024
Public Function GetCrc32(ByRef stream As System.IO.Stream) As Integer
Dim crc32Result As Integer
crc32Result = &HFFFFFFFF
Dim buffer(BUFFER_SIZE) As Byte
Dim readSize As Integer = BUFFER_SIZE
Dim count As Integer = stream.Read(buffer, 0, readSize)
Dim i As Integer
Dim iLookup As Integer
Do While (count > 0)
For i = 0 To count - 1
iLookup = (crc32Result And &HFF) Xor buffer(i)
crc32Result = ((crc32Result And &HFFFFFF00) \ &H100) And &HFFFFFF
crc32Result = crc32Result Xor crc32Table(iLookup)
Next i
count = stream.Read(buffer, 0, readSize)
Loop
GetCrc32 = Not (crc32Result)
End Function
Public Sub New()
Dim dwPolynomial As Integer = &HEDB88320
Dim i As Integer, j As Integer
ReDim crc32Table(256)
Dim dwCrc As Integer
For i = 0 To 255
Form1.CRCWorker.ReportProgress((i / 255) * 100) 'Report Progress
dwCrc = i
For j = 8 To 1 Step -1
If (dwCrc And 1) Then
dwCrc = ((dwCrc And &HFFFFFFFE) \ 2&) And &H7FFFFFFF
dwCrc = dwCrc Xor dwPolynomial
Else
dwCrc = ((dwCrc And &HFFFFFFFE) \ 2&) And &H7FFFFFFF
End If
Next j
crc32Table(i) = dwCrc
Next i
'file complete
End Sub
End Class
'------------- END CRC32 CLASS--------------
'-------------- START FORM1 --------------------------
Private Sub CRCWorker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles CRCWorker.DoWork
For i = CurrentInt To dgv.Rows.Count - 1
CRCWorker.ReportProgress(0, i & "/" & Total_Files)
Current_File_Num = (i + 1)
SetControlText(lblCurrentFile, Str(Current_File_Num) & "/" & Total_Files)
result = CheckFile(SFV_Parent_Directory & "\" & dgv.Rows(i).Cells(0).Value, dgv.Rows(i).Cells(1).Value)
Select Case result
Case 0 ' missing file
UpdateRow(i, 2, "MISSING")
'dgv.Rows(i).Cells(2).Value = "MISSING"
Missing_Files = Missing_Files + 1
SetControlText(lblMissingFiles, Str(Missing_Files))
Case 1 ' crc match
UpdateRow(i, 2, "OK")
' dgv.Rows(i).Cells(2).Value = "OK"
Good_Files = Good_Files + 1
SetControlText(lblGoodFiles, Str(Good_Files))
Case 2 'crc bad
UpdateRow(i, 2, "BAD")
' dgv.Rows(i).Cells(2).Value = "BAD"
Bad_Files = Bad_Files + 1
SetControlText(lblBadFiles, Str(Bad_Files))
End Select
If CRCWorker.CancellationPending = True Then
e.Cancel = True
Exit Sub
End If
Next
End Sub
Private Sub CRCWorker_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles CRCWorker.ProgressChanged
Dim val As Integer = e.ProgressPercentage
ProgressBar2.Maximum = 100
ProgressBar2.Value = e.ProgressPercentage
Debug.Print(val)
End Sub
Function CheckFile(ByVal tocheck_filepath As String, ByVal expected_crc As String) As Integer 'returns result of a file check 0 = missing 1 = good 2 = bad
If File.Exists(tocheck_filepath) = False Then
Return 0 'return file missing
End If
Dim f As FileStream = New FileStream(tocheck_filepath, FileMode.Open, FileAccess.Read, FileShare.Read, 8192)
Dim c As New CRC32()
crc = c.GetCrc32(f)
Dim crcResult As String = "00000000"
crcResult = String.Format("{0:X8}", crc)
f.Close()
End Function
It appears your .ReportProgress() call is in the New() subroutine, which is the part that makes the lookup table for the CRC calculation. The New() subroutine is called once, before the main CRC routine. The main CRC routine is the one that takes up all the time and needs the progress bar.
Shouldn't the progress bar updating be in the GetCrc32() function? Something like this:
Public Function GetCrc32(ByRef stream As System.IO.Stream, _
Optional prbr As ProgressBar = Nothing) As UInteger
Dim crc As UInteger = Not CUInt(0)
Dim buffer(BUFFER_SIZE) As Byte
Dim readSize As Integer = BUFFER_SIZE
Dim left As Long = stream.Length
If Not (prbr Is Nothing) Then ' ProgressBar setup for counting down amount left.
prbr.Maximum = 100
prbr.Minimum = 0
prbr.Value = 100
End If
Dim count As Integer : Do
count = stream.Read(buffer, 0, readSize)
For i As Integer = 0 To count - 1
crc = (crc >> 8) Xor tbl((crc And 255) Xor buffer(i))
Next
If Not (prbr Is Nothing) Then ' ProgressBar updated here
left -= count
prbr.Value = CInt(left * 100 \ stream.Length)
prbr.Refresh()
End If
Loop While count > 0
Return Not crc
End Function
In Windows Forms BackgroundWorker Class is often used to run intensive tasks in another thread and update progress bar without blocking the interface.
Example of using BackgroundWorker in VB.Net
The problem is when you use use the form in your code without instantiating it Form1.CRCWorker.ReportProgress((i / 255) * 100) there is a kind of hidden "auto-instantiation" happening and new instance of Form1 is created each time.