|
I will keep that in mind. I'm bookmarking your site. Lots of interesting articles
|
|
|
|
|
Hi Luc,
I'm happy to report I have this thing working both ways with the PCs. I'm sending and receiving bytes and they are changing controls on the application as I wanted. I do have a question, as I copied that part of the code and only understood it well enough to make it work, but I do need more pointers as explanations are not that clear (at least for me) on the tutorials I found (I intend to learn C later--don't like the syntax). The code below works as is. It does what I want and I can have it send/receive data (if required I can modify the chip software as it is easier for me )
I want to make this program able to receive 2 data bytes (or more) instead of just one, using the delegation method (which I copied here and works fine here with one byte at a time). Those comments on the serial declarations and routines are what I understood from the explanations (please correct me if I'm wrong!)
Imports System.Byte
Imports System
Imports System.IO.Ports
Imports System.IO
Imports Microsoft.VisualBasic
Imports System.ComponentModel
Imports System.Threading
Imports Microsoft.Win32
Imports System.Runtime.Remoting.Messaging
Public Class Form1
Dim LEDOUT1, LEDOUT2 As Byte
Dim LEDIN1, LEDIN2 As Byte
Dim ADIN As Integer
Dim LEDMSGOUT As Byte
Dim PWMOUT As Byte
Dim LEDMSGIN As Byte
Dim AD1, AD2 As Byte
Private mySerialPort As New SerialPort
Private comBuffer As Byte()
Private Delegate Sub UpdateFormDelegate()
Private UpdateFormDelegate1 As UpdateFormDelegate
Private Sub mySerialPort_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs)
UpdateFormDelegate1 = New UpdateFormDelegate(AddressOf UpdateDisplay)
Dim n As Integer = mySerialPort.BytesToRead
comBuffer = New Byte(n - 1) {}
mySerialPort.Read(comBuffer, 0, n)
Me.Invoke(UpdateFormDelegate1)
End Sub
Private Sub UpdateDisplay()
INCOMING.Text = CStr(comBuffer(0))
If INCOMING.Text = "50" Then
If OvalShape1.BackColor = Color.Gray Then
OvalShape1.BackColor = Color.Red
Else
OvalShape1.BackColor = Color.Gray
End If
End If
If INCOMING.Text = "32" Then
If OvalShape2.BackColor = Color.Gray Then
OvalShape2.BackColor = Color.Red
Else
OvalShape2.BackColor = Color.Gray
End If
End If
End Sub
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
End
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim OUTPUT(3) As Byte
If LEDOUT1 = 0 Then
LEDOUT1 = 1
Else
LEDOUT1 = 0
End If
LEDMSGOUT = 40 + LEDOUT1 + LEDOUT2
OUTPUT(0) = LEDMSGOUT
OUTPUT(1) = PWMOUT
mySerialPort.Write(OUTPUT, 0, 2)
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim OUTPUT(3) As Byte
If LEDOUT2 = 0 Then
LEDOUT2 = 1
Else
LEDOUT2 = 0
End If
LEDMSGOUT = 40 + LEDOUT1 + LEDOUT2
OUTPUT(0) = LEDMSGOUT
OUTPUT(1) = PWMOUT
mySerialPort.Write(OUTPUT, 0, 2)
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
AddHandler mySerialPort.DataReceived, AddressOf mySerialPort_DataReceived
With mySerialPort
.PortName = "COM1"
.BaudRate = 9600
.DataBits = 8
.Parity = Parity.None
.StopBits = StopBits.One
.Handshake = Handshake.None
End With
Try
mySerialPort.Open()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Private Sub TrackBar1_Scroll(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TrackBar1.Scroll
Dim OUTPUT(3) As Byte
PWMOUT = TrackBar1.Value
OUTPUT(0) = LEDMSGOUT
OUTPUT(1) = PWMOUT
mySerialPort.Write(OUTPUT, 0, 2)
End Sub
End Class
As I said, it works fine with the laptop but I'd like the ability to receive (at any time, as it is happening here) 2 bytes or more at a time.
|
|
|
|
|
Hi,
that looks pretty good.
Here are some comments on your design and coding style:
1.
if you have independent functions in the peripheral, it would be better to have a "command language" so you can send individual commands, and don't have to repeat values that already are in effect. An example, using ASCII for simplicity could be:
L0 = led off
L1 = led on
M0 = motor off
M1 = motor on
etc.
2.
if you need combinations of data values (your current LEDMSGOUT), you should really isolate that functionality and put it in a separate method, maybe even a separate class. So every time you repeat yourself (as in LEDMSGOUT = 40 + LEDOUT1 + LEDOUT2 ) your reflex should be: this ought to be a method. Reason: less code, better readability, easier to change when the interface is modified, etc.
3.
there is a nice XOR operator, ideal to toggle LED states for instance. (LED = LED Xor 1 )
4.
when combining bits logically (rather than really adding numbers), it is better/cleaner/safer to use the OR operator, hence LEDMSGOUT = 40 Or LEDOUT1 Or LEDOUT2
5.
Why do you use uppercase for comments? IMO it makes them harder to read...
And then some pointers on multi-byte receive:
1. your code is somewhat ready for it, but it probably doesn't work well.
2. you may think of messages, the serial port doesn't care at all, all it knows are individual bytes. For instance, if you send several 10-byte messages and then read the input buffer at arbitrary points in time, you might get 4, then 12, then 3, then ... bytes. That is what makes receiving much harder.
3. the main problem is timing: DataReceived will (or may) fire as soon as one byte is coming in; it does not care about the number of bytes received, and is unaware of message lengths. It may however also be a bit late. Also, your sender in general may insert transmission delays right in the middle of a message when more important things need to be handled first (stepper motor probably has higher priority interrupts).
4. There are a couple of approaches one can take:
4a. by far the easiest is: use textual, not binary data, and define the language as having a message terminator (a special char that won't appear inside any message), then set NewLine to that char, and just do ReadLine (probably in a separate thread or backgroundworker, in a loop; i.e. don't use DataReceived event at all). The obvious special character is \n itself (careful, the default value of SerialPort.NewLine is system dependent, and may well be "\n\r" i.e. CRLF.
4b. a hack, works fine if there is a guaranteed gap in between messages: insert a delay (Thread.Sleep) that is sufficient to receive all bytes of a message, and only then actually read the incoming data. This enforces message alignment, provided you do it right (which includes: don't read more than one message at a time). However it is a hack, once it goes wrong, it may stay out of sync forever.
4c. read whatever is available (as you do now), however inside the event handler, copy it to a message buffer, and only signal the app when a full message is present (That basically is what ReadLine does for text).
4d. what would NOT be good is always handling one character at a time; that would work at low baud rates, it would be too much processor load at high comm rates.
5. you should design and code defensively, i.e. also consider comm problems may occur, such as a character getting lost or damaged. The general approach is to define a "protocol", probably message oriented, probably with message validation (some kind of checksum), and most likely with a mandatory acknowledge/come-again reply.
|
|
|
|
|
Wow! Luc, thanks again. Lots of great advice. I'm in for some modifications to this code. As I said I'm new to VB (about 6 months) and it is a whole different animal than embedded controllers. The comments in caps are a bad habit I picked up in the 8 bit era of computing. Hard to get rid of...
I think the quick solution before polishing the code as you point out is to do 4c. My circuit uses a PIC with internal hardware UART and PWM so it doesn't take much time to push bytes to the internal buffer (200 bytes) or set the duty cycle, so my software will be free to do the actual work (mostly delaying byte output.) I'll keep it at 9600 baud for now. I'll up the speed once the code is polished and convert everything to text values as you recommend. My bytes insistance was just because I'm used to do it that way when I have chips talking to each other and their peripherals (translation: I don't know better!)
I will keep learning more about VB. It is fun despite being huge compared to what I knew about the BASIC language (used to know all instructions of the top of my head.) Lots more going on with .NET and Windows. Thanks for all the help in getting my application going.
Best,
Juan
|
|
|
|
|
Hi Juan,
you're welcome. And good luck with the project.
FWIW: I once did a 9600Bd serial port plus a separate 9600Bd CAN-like protocol on some PICs (16F84 = 64 bytes of RAM, no UART), all four comm channels in software, and without interrupts (too slow!); together with two Macs, they were controlling my digital railroad setup. So, yes I know there is a huge difference between PCs and small embedded systems...
|
|
|
|
|
Hello !
I'm working on vb.net 2010 .I have a form with some labels : Label1,Label2,Label3.....and i want to access a label using name as string.i'm using the code :
For i=1 to 31
DirectCast(Me.Controls.Item("Label" & i) , Label).ForeColor=Red
Next
But this code produce an error : Object reference not set to an instance of an object.
What can i do ?
Thank you.
|
|
|
|
|
Not sure, however I would suggest you try
DirectCast(Me.Controls("Label" & i) , Label).ForeColor=Red
|
|
|
|
|
This error occurs when you are accessing an attribute of an object when the object itself does not exist.
alejx wrote: Me.Controls.Item("Label" & i)
Ensure that the values you are trying to access here exist.
|
|
|
|
|
I would loop through the controls from the forms collection and check each controls type to see if it is a label and then change it color as shown in the code snippet below
For Each Control In Me.Controls
If TypeOf Control Is Label Then
Control.forecolor = Color.Red
End If
Next
or you could do it like this
Dim l As Label = DirectCast(Controls.Item("Label1"), Label)
l.ForeColor = Color.Red
Lobster Thermidor aux crevettes with a Mornay sauce, served in a Provençale manner with shallots and aubergines, garnished with truffle pate, brandy and a fried egg on top and Spam - Monty Python Spam Sketch
|
|
|
|
|
Hi I want to scan from ADF (Feeder) in my scanner. How to make this?
modified 9-Jan-12 13:20pm.
|
|
|
|
|
Have you checked to see if the scanner has any SDK's? that would be my first place to check
Lobster Thermidor aux crevettes with a Mornay sauce, served in a Provençale manner with shallots and aubergines, garnished with truffle pate, brandy and a fried egg on top and Spam - Monty Python Spam Sketch
|
|
|
|
|
I want to scan with all scanners not only in my scanner.
|
|
|
|
|
Take a look at the response to this question[^].
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
I'm using vb2008
Is there is any suggestion to create guitar tuner using Vb.net
|
|
|
|
|
Here's a C# article on the subject but I don't think it would be to hard to convert.
FFT Guitar Tuner[^]
C# Conversion Article[^]
Lobster Thermidor aux crevettes with a Mornay sauce, served in a Provençale manner with shallots and aubergines, garnished with truffle pate, brandy and a fried egg on top and Spam - Monty Python Spam Sketch
|
|
|
|
|
I'm working on vb.net and I don't know how to use C#.
thank you for your help!
|
|
|
|
|
The second link is about converting C# to VB.NET
Also have a look at this Code Converter[^]
Lobster Thermidor aux crevettes with a Mornay sauce, served in a Provençale manner with shallots and aubergines, garnished with truffle pate, brandy and a fried egg on top and Spam - Monty Python Spam Sketch
|
|
|
|
|
Thank you. but I'm confusing, I don't knwo how to use it. any sugggestion ?
|
|
|
|
|
Seriously?? It was spelled out to you step-by-step. All you had to do was come up with the full path to the solution file (.SLN) and type that into the last command line!
|
|
|
|
|
Please I want to make sign up & Lodin form
to my program with VB.net
I make program linked to database MySQL.
I want password saved in database is Encrypted
Thanks for All
my email
taherhamdy_76@yahoo.com
|
|
|
|
|
Without wanting to sound rude.
What have you tried? what are you having trouble with? I got alot of hits from google
vb.net login form tutorial[^]
Lobster Thermidor aux crevettes with a Mornay sauce, served in a Provençale manner with shallots and aubergines, garnished with truffle pate, brandy and a fried egg on top and Spam - Monty Python Spam Sketch
|
|
|
|
|
Hello everyone. I have a simple request. I need a simple source code sample of how I would make a p2p style multi player game in Vb 2010. I know it would use a network stream and everything streamed would be in a class. But Ive never worked with network streams before so a very simple code sample would help me a lot. A simple input box, type in IP, connect type sample would be great. Thanks in advance.
|
|
|
|
|
Yes, you will need to do some stuff with network streams. The only network games I've written were over LANs (my home network). That's a lot easier, since you don't have to worry about security issues (at least at my house ), and you don't have to worry about dynamic ip addresses and all that...
It is possible, but a little tricky. First, it's a good idea to do all of the network communications asyncronously (such as with a backgroundworker. I have a link to a vb source code I wrote to help me with developing a couple of network programs I wrote a while ago. It basically encapsulates all of the details of the network stuff in a class. You can take a look at it and how it works.
You can take a look at http://lance.mckendree.edu/~klschaefer/temp/NetworkHelper.vb[^]. As the name suggests, it makes doing network stuff a little easier, but feel free to learn how it works and expand on it. If you haven't done any network stuff at all, I would suggest making a simple chat program just so you can get something under your belt.
I would consider what I've done to be a server/client program, so one of the machines is designated as a "server" and the other as a "client", although beyond initially setting up the connection, that designation pretty much doesn't do anything: both can send and receive exactly the same.
Anyways, I hope this helps!
|
|
|
|
|
thanks, its looks great. Ill have to play with it some.
|
|
|
|
|
am dev. a school man. so i need to computer student performance but the problem is how to get the highest in class base on their percentage
i have ther percentage but som have thesame perc so how to know who is 1st,2nd 3rd ....
am using vb.net
just a clue i need
|
|
|
|
|