Can someone help me with the sourcecode?
Printable View
Can someone help me with the sourcecode?
Maybe. If you first post the Code you need help with...
I want to receive 3 values and display it in VB can you help with the source code, an example code will help
I have no idead on the code because I dont know how to do vb6 with serial communication. where to start? how to use mscomm?
google will get you several examples as will a search of this site
To receive serial input you have to use the MSComm control.
You go to Project->Components and add 'Microsoft Comm Control 6.0' to your toolbox.
Now you have MSComm available and can put one to your Form for usage.
Check the parameters and settings.
To receive characters you set the .RThreshold property to 1.
This has the effect that for every received character the OnComm() event of the control will fire.
Assume your control is Named MSComm1, then you might use this very basic code to receive characters:
Instread of debug.print a$ you would probably do something else with the three received characters.Code:Private Sub MSComm1_OnComm()
Static a$
a$ = a$ + MSComm1.Input
If Len(a$) = 3 Then
debug.print a$
a$=""
End If
End Sub
Don't forget to either check the oncomm to see why it fired or check the inbuffercount before issuing the input command otherwise you could be trying to read when there is nothing there to read.
Yes. That'd be the next step of higher sophistication using a Select Case to react on distinct reasons of the OnComm() to have fired.
But the above simple code still would work fine. If there is no .Input available, well, then there is none. It will wait for the next valid character, until they are three.
What I mean is that I will receive 3 different values in uart in ASCII and convert each of them to another value. Is the code still fit? or it needs a modification
And also the value that I will be receiving comes from a source that keeps on transmitting.
Depends on how you are sending them. If you can put a \ character in between each part, you could receive one packet and split it up
I'am sending them in different line. Like:
342
345
423
I use the this format in sending. I would like to assign variable to each of them.
OR should I send the data in this format 345\324\435?
PLease help
Here's a sample for you.
If you are able to send this format
234/345/456
123/345/678
everything is rather easy, provided you send complete lines with 3 numbers each.
After the third number a vbCrLf must be sent to definitely delimit a group of 3 numbers.
In OnComm you can do then:
Code:Private Num1%, Num2%, Num3%
Private RLine$
Private Sub MSComm1_OnComm()
RLine = RLine + MSComm1.Input
If Len(RLine>2) Then
If Right(RLine,2) = vbCrLf Then ' a complete record with three numbers has been received now
dim a$()
a = Split(RLine, "/") 'split the line into the three numbers
Num1 = a(0) 'get first number
Num2 = a(1) 'get second number
Num3 = a(2) 'get third number
RLine = "" 'reset the receiver variable for the next line
End If
End If
End Sub
WHAT is VbCrlf? I'am receiving it from a micro-controller with c programming.
It is a carraige return linefeed combo as would typically be at the end of a line.
Hex 0D 0A
Dec 13 10
If I send it through this format:
345
235
453
How to do it?
if that is what you are going to be getting everytime e.g. 3 values each 3 digits long and each on a new line you could simply check the length and then use the mid() function.
Something like this
Code:Private Sub MSComm1_OnComm()
Static a$
dim b$,c$,d$
a$ = a$ + MSComm1.Input
If Len(a$) = 15 Then
b$=mid(a$,1,3)
c$=mid(a$,6,3)
d$=mid(a$,11,3)
a$=""
End If
End Sub
Yes, but this does not synchronize. If you mis one of the first characters, all of the following received values'd wbe wrong.
Have you any influence of how you send the numbers? Can you modify the C-code in the microprocessor as to determine how the numbers are sent?
True, but that gives a general idea. Personally I would use handshaking where the PC responds to the connected device telling it that everything is fine or that it should resend or some other such thing.
I would also use US and RS [e.g. CHR(31) and CHR(30) ] characters in the datastring rather than CR+LF
Assuming of course that the code on the other device can be modified.
yes I have influence,
so the horizontal format like 124/563/452 is better?
I could put a carriage return in the end. Would it be enough?
I would also use US and RS [e.g. CHR(31) and CHR(30) ] characters in the datastring
What do you mean by this?
They are just standard characters used for formatting
CHR(31)= Unit Seperator character.
CHR(30)=Record Seperator character.
In your sample of data above the US would be where the / is and the RS would be at the end of the group.
Of course the / and a CR will work just fine
Yes. I'd prefer the "/" and Cr ore better Cr Lf sequence, because you can put that literally in any textbox to get a readable display, or being debug.printed for control purposes without problem.
US and RS have often no visible correspondence.
I advise to use "/" to separate numbers and Cr Lf to terminate the record.
Then you can easily split it up as I showed before.
I would use just the CR rather than CRLF.
btw the reason for using US and RS is that they will never be typed from the keyboard and as a result will not occur in most data streams where as , / CRLF are all common place. This is one reason why these characters were assigned this purpose in the ASCII standard.
/ can be part of a date, so I always use \
Yes, which can be part of a pathname.
You could also use comma, colon, semicolon or any other character which you are sure will never be part of a number.
If you might get decimal numbers you should not use dor or comma.
If you are sure the numbers are never a date you can use "/" no problem.
In many cases it makes no difference to use Cr or Cr-Lf, only that when printed out the Cr-Lf is a standard sequence to advance to a new line. If you would receive records from your hardware with, say, hyperterm, it will always write to the same line again, because Cr only jumps backt to the beginning of the line. The Lf, however advances the cursor to the next line.
That's why I would prefer Cr-Lf. If in doubt you can receive your data with Hyperterm (which is a standard windows gimmick) to see if the sender provides valid data.
Yep all of this is true. This is also the major reason I have standardized my programs to use US,RS,EOT. Typically the only time you will run into these characters is during a binary transfer for which I use a different method.
I used to use comma a lot as well as CR. I also used Tab ~ | > and others
IMO the CRLF is just 1 additional character to transmit and process, limits your options for parsing the incoming data and requires a tiny bit more processing. Not a biggie for sure.
btw not sure about hyperterm but most terminal programs can be set to advance to the next line on a CR or a LF or a CRLF.
I rarely use hyperterm as I have written my own terminal program many years ago which works like a champ with many features that hyperterm does not have.
Depends on how fast it is sending, It there is a pause between sends of 1 second or more then you would likely not have much problem. If the pause it shorter then the chance of an issue increases and if no noticable pause then quite likely to have a major problem as is,
You would need to first check for the terminator as above but not by using the Right() function. Instead you would use instr() to see in the terminator is present and where in the string it appears. You could then use Mid() to pull out the data up to the terminator and process it. You would also need to check to see if there was more data after the terminator if so this data needs to be saved for the next cycle and that data processed needs to be removed.
In my case I normally set up a public variable for a receivebuffer. Any data which arrives gets appended to this variable. I would then check to see if my terminator character is present. If so then I would pull the data from the buffervar up to that position and place it in another var for processing. I would also check the len of the buffer var to see if it is longer than my data + the terminator(s). If not more data then I set the buffervar="" if more data then I use mid again to pick up the data after the terminator.
I then process the data in the local processing var and loop back to the top of my terminator test routine to see if there is another group of data already in the buffer. If so then the process above is repeated if not then the routine would exit and wait for more data to come into the port.
can you sum it up I cant hardly understand what you say.
Do you mean that I can still use the code as long as a delay is present in the sending of data?
Yes, you could use it if the delay is long enough.
Have you tried it?
I'd say yes. VB is considerably fast and parsing for the separators does take no time compared to the transmission of a character, which takes a fixed time. If your baud rate is below 56600 you will not get any problem with the described code. Even if processing received numbers would suppres one or two OnComm events, the characters are buffered by MSComm and read with the next firing of OnComm().
I don't know what your program is gonna do after having received three numbers. I'm sure you will perform something, before the next set of three numbers is received.
But if your processing should really take long time you'd have to see if you cannot use hardware handshake to make the transmitter wait until the receiver is ready to process more data. This depends on how the RS232 is implemented on your microcontroller. Is it 3-wire-only or is it a full Rs232 with CTS,RTS,DTR,DSR signals?
Without knowing what the other end is doing there is no way to say for sure. But keep in mind that the code is testing the right 2 characters if there is no pause in between the groups of data this will almost certianly fail.
AAfter my experience it is not likely to fail, but if you are in doubt we shall modify the code like that:
This way we only pull the valid line from the RLine buffer, leaving everything else in it.Code:Private Num1%, Num2%, Num3%
Private RLine$
Private Sub MSComm1_OnComm()
RLine = RLine + MSComm1.Input
If Len(RLine>2) Then
dim p%
p = Instr(RLine, vbCrLf)
If p Then ' a complete record with three numbers has been received now
dim a$()
a = Split(Left$(RLine,p-1), "/") 'split the line into the three numbers
If UBound(a) = 2 Then
Num1 = a(0) 'get first number
Num2 = a(1) 'get second number
Num3 = a(2) 'get third number
End If
RLine = Mid$(RLine,p+2) 'reset the receiver variable for the next line
End If
End If
End Sub
Also we make a security check so as only a valid three number line is accepted. This avoids wrong input when switching into a running stream of incoming data. After the first vbCrLf was received the reception will run fully synchronuous.
Now this is a safe way. I have already implemented receivers like this with speeds up to 56600 baud without any breaks or pause between the records.
Yep, That should work fine. The pervious method would fail in many cases where back to back transmissions were recieved.
For example your reads may get something like
12
3/456
/456CR
LF23
in which case the first method would not process the data [last 2 characters are not CRLF at anytime ] and this senario or any one of a thousand others is very likely to occur if the data is not broken up by pauses.
Yeah. Right.
First thing was more or less a hack to get things going, showing the principle sort of thing. :)
Although it is likely to work ok after the first record, because it will always be fast enough to react as soon as the LF from CrLf is received, making the Right$(RLine,2) a vbCrLf.
Only ever the first record could be too short then, as the transmission has already started earlier.
I'am only using CR at the end. Is it still ok, your code use VBCRLF?
So the output of this will be each of three digit number, like:
345 452 128
I encounter error when using the code, this error is in this section " If Len(RLine>2)"
that is a syntax error should be if Len(Rline)>2
but no the code will not work properly you must change it to suit what you are sending. This should be pretty clear.
Yes.
If you are using only Cr, there are no 2 characters at the end, so you have to use
If Len(RLine) > 1 Then...
This statement was for avoiding error if the string is empty. In this last version of the routine you can leave it away anyway (together with the matching End If of course).
It was only to avoid problems with the Right$(RLine,2), which is not used anymore in the recent version.
The INSTR() statement is the one that will need to be changed. Right now is looking for vbCRLF will never be true if sending just a cr.
Right. The Mid$() statement either. So let's resume and finally make a working procedure:
Code:Private Sub MSComm1_OnComm()
Dim p%
RLine = RLine + MSComm1.Input
p = Instr(RLine, vbCr)
If p Then ' a complete record with three numbers has been received now
dim a$()
a = Split(Left$(RLine,p-1), "/") 'split the line into the three numbers
If UBound(a) = 2 Then
Num1 = a(0) 'get first number
Num2 = a(1) 'get second number
Num3 = a(2) 'get third number
End If
RLine = Mid$(RLine,p+1) 'reset the receiver variable for the next line
End If
End Sub
"Private Num1%, Num2%, Num3%
Private RLine$"
How to declare this i get an error in this.
Is it ok if I use CR only? Compared to CRLF which better?
when you say vbCR is it the same as CR?
Is there something missing in the code, like "If Len(RLine) > 1"?
when I try the code there are no output in the textbox, what should be the output? it is something like this:
452 241 342
it should output a 3 digit right?
to output the result shoud I do it like this "text1.text=Num1"?
there are no output when I do it like this.
1: no quotes in definitions; Private does not apply inside sub routines, use Dim instead
2: Yes you can use CR or for that matter you can use any character that is not going to be part of your data. What you use is up to you. The code will have to be modified to suit the character you choose. There should be plenty of info in this thread at this point for you to figure out what you need to do.
Nonono. Don't Dim within the sub. Num1%, Num2%, Num3% and RLine MUST NOT be declared WITHIN the OnComm() event. They were meant to be declared Private within the Form. That is, the declarations
are OUTSIDE the sub, on top of the Form's code. There a Private does not give an error.Code:Private Num1%, Num2%, Num3%
Private RLine$
It was thought that further processing would happen outside the OnComm event, so the Num and RLine variables were made to be known to other subs as well (private to the form).
But to stop confusing, here is a version that would do everything within the OnComm event.
This assumes that you have 3 TextBoxes Text1, Text2 and Text3 to take the numbers. So we don't need the Num variables anymore, as we put the results directly to the textboxes.Code:Private Sub MSComm1_OnComm()
Dim p%
Static RLine$
RLine = RLine + MSComm1.Input
p = Instr(RLine, vbCr)
If p Then ' a complete record with three numbers has been received now
dim a$()
a = Split(Left$(RLine,p-1), "/") 'split the line into the three numbers
If UBound(a) = 2 Then
Text1.Text = a(0) 'get first number
Text2.Text = a(1) 'get second number
Text3.Text = a(2) 'get third number
End If
RLine = Mid$(RLine,p+1) 'reset the receiver variable for the next line
End If
End Sub
If further processing is really required, the values could be taken from the textboxes .Text properties again. This is as good as a private variable.
He did say that he just wanted to receive and display these values. No need to have anything other than the buffer declared as form level var or static.
so there is nothing missing in the code, like "If Len(RLine) > 1"?
Your right I will manipulate the data later into an equation and output the result of that equation, but for now I will test the data first by displaying it.
I tried it but there is no output in the text box. WHat could be wrong? is it the settings of the com or the code it self?
place a break point in the on comm event and see if you get there