-
Oct 18th, 2009, 05:04 PM
#1
Thread Starter
New Member
Receiving data from serial port
Hello. I am new to vbasic and am working with the mscomm controls. My goal is to receive data from an Oregan Scientific WMR-968 weather console. So far I have figured out the protocol and am receiving input fine from it. My problem is parsing the information. The station sends variable length packets beginning with FF FF followed by the data and then a checksum. Here are some examples I obtained from Device Monitor(there are many other types, these are only a few):
FF FF 00 00 39 00 01 00 20 00 58 (Anemometer and Wind Data)
FF FF 06 40 23 02 37 07 8B 21 17 00 06 70 (Inside Temp, Humidity, etc)
FF FF 0E 48 54 (sequence number)
FF FF 02 31 73 01 25 00 CA (extra sensors)
I have been able to find documentation on what all of this means and am having no trouble decoding it. I'm just having trouble parsing the data and breaking it up into seperate chunks. I've looked into using the Split() function and the Mid and Left functions but it doesn't seem to be working very well for me.
I have researched this forums here and have found some helpful posts such as:
http://www.vbforums.com/showthread.p...03#post3376003
But this post doesn't seem to be working well for variable length packets.
Any help would be greatly appreciated. If you would like snippits of code I have already done or any other information that might help please feel free to ask me.
Thanks in advance!
-EndlessNameless
-
Oct 18th, 2009, 09:32 PM
#2
Thread Starter
New Member
Re: Receiving data from serial port
-
Oct 18th, 2009, 11:32 PM
#3
Re: Receiving data from serial port
Can you use the checksum as your end of packet identifier? If not, is there a consistant length of time (dead space) between packets sent?
<--- Did someone help you? Please rate their post. The little green squares make us feel really smart!
If topic has been resolved, please pull down the Thread Tools & mark it Resolved.
Is VB consuming your life, and is that a bad thing??
-
Oct 19th, 2009, 02:10 AM
#4
Thread Starter
New Member
Re: Receiving data from serial port
CDDRIVE,
Thank you for the response. To be honest, you were the one who I was hoping would respond to this as you seem quite good with mscomm. As far as using the checksum, that is what I was planning on doing, but I'm having a bit of trouble parsing the data. Is there a method you could suggest? I am able to input the serial data into a variable array, but it can sometimes be hit or miss whether I happen to sync up properly to receive the data. So breaking the data into chunks so I am able to deal with it is what I'm having trouble with.
The data does not appear to be taking any fixed amount of time. When I first connect and send RTS I am liable to receive 4-8 packets all at once giving me updates from all the sensors connected to the weather station. Then after that I might have to wait 30-40 seconds and then receive anywhere from 1-4 packets depending on what is updating.
Most of the code I am using so far is code you wrote for another user with a similar problem, and for the most part it works, but I believe it was intended for a fixed length 8 byte packet.
Thank you so much for the help, and sorry if I seem anxious to get this figured out, but I've been bumping my head against this wall for quite a while now. I feel like it's something very simple I'm just not getting.
I am also able to feed the mscomm input into a normal string variable and then output that into a text box, but that automatically converts it to ASCII characters which is no good for my purposes. Of course, this is what it is supposed to do, so it's not a problem. Just not what I'm wanting.
I know that this has been done already with C++ for linux (I have the source code here, but C++ is not my strong suit by any means), but I would really like to make this work with my own software with VB6. This is frustrating because I've worked with mscomm before, but I was only working with an ASCII protocol which made things very simple.
Thank you very much for your time and patience. It is very much appreciated.
-
Oct 19th, 2009, 10:15 AM
#5
-
Oct 19th, 2009, 02:35 PM
#6
Fanatic Member
Re: Receiving data from serial port
Hi,
Your data is binary. There will be a specific pattern defined by the vendor that indicates the start and end of data. My guess is that this is the FFFF characters (one to start, and one to end a packet). If my guess is correct, then you simply break each packet sequence into complete packets, starting and ending with -- whatever --, and use a loop to extract individual bytes from each packet. Since the entire data stream may consist of one or more complete packets, followed by an incomplete packet, you will need to retain that incomplete packet, so that later data may be appended to it.
I have lots of code in my book, Visual Basic Programmer's Guide to Serial Communications 4 (see www.hardandsoftware.net for information) that does similar things. I do not have a code example that works with your weather station, though the general approach that I've suggested certainly will work.
Dick
-
Oct 19th, 2009, 03:13 PM
#7
-
Oct 19th, 2009, 03:16 PM
#8
Fanatic Member
Re: Receiving data from serial port
Yes, I've known Jan for over 12 years. We've never met in person, though. She and I exchange email, actual books, and links.
Dick
-
Oct 19th, 2009, 04:53 PM
#9
Junior Member
Re: Receiving data from serial port
I've been using MSComm for over 10 years. I cheat and start a timer (50ms to 100ms) when I get the OnComm Event. Once the timer is done, i check the comm object input buffer. Then I turn the timer off.
This only works if the device doesn't transmit any faster. The great thing about this method is that it is simple and works great. Although technically it sucks
Just make sure you have something to validate the input. The problem with fixed length is that you end up buffering the transmitted chracters, so if you ever get out of synch because it becomes a real pain the butt. The best is probably use a terminating character such as crlf.
Good luck.
-
Oct 19th, 2009, 06:33 PM
#10
-
Oct 19th, 2009, 07:54 PM
#11
Hyperactive Member
Re: Receiving data from serial port
-
Oct 19th, 2009, 10:07 PM
#12
Thread Starter
New Member
Re: Receiving data from serial port
Well, while I thank you all for the replies I regret it hasn't been of much help. I may need to do what CDDRIVE suggested and repost with a different title.
-
Oct 19th, 2009, 10:53 PM
#13
Re: Receiving data from serial port
Originally Posted by DickGrier
Hi,
Your data is binary. There will be a specific pattern defined by the vendor that indicates the start and end of data. My guess is that this is the FFFF characters (one to start, and one to end a packet).
Dick
Actually, I think that this post by Dick should get more consideration. All your examples started each packet with FF FF. You can structure your parsing rules around this. If not, why not?
<--- Did someone help you? Please rate their post. The little green squares make us feel really smart!
If topic has been resolved, please pull down the Thread Tools & mark it Resolved.
Is VB consuming your life, and is that a bad thing??
-
Oct 19th, 2009, 11:21 PM
#14
Re: Receiving data from serial port
EN, I just realized that you were never specific in what you wanted to do with the parsed data. Do you want to display each packet in a separate control, like multiple labels or text boxes, or just put the data on separate lines in a TextBox? Is the use of InStr, Mid, Spit etc. your problem? The library covers their use fairly well and there must be zillions of posts here regarding their use. I would think that InStr and or Spit should be used to search and parse for FF FF.
<--- Did someone help you? Please rate their post. The little green squares make us feel really smart!
If topic has been resolved, please pull down the Thread Tools & mark it Resolved.
Is VB consuming your life, and is that a bad thing??
-
Oct 20th, 2009, 02:45 AM
#15
Thread Starter
New Member
Re: Receiving data from serial port
Well. One of my main problems is I am still learning. My ultimate goal is to read the incoming data and display it to graphs and gauges. A typical weather program. Making my own weather software has been a long time goal of mine as far as programming. So far I have programmed a voice operated light control console using a basic stamp, vbasic6 and various voice activation programs such as e-Speaking (nice piece of software for the price). Now my next step is this weather station.
I have found the protocol to my weather station here - http://www.netsky.org/WMR/Protocol.htm - so I know what the data structure is. I've been puzzling this over for months now and working on it here and there.
Other software that does what I intend to do can be found here - http://www.sharewareplaza.com/SB-Wea...oad_34384.html (this is what we currently use to read data from our weather station) - and a linux open source version written in c++ can be found here - http://azug.minpet.unibas.ch/~lukas/wmr918/index.html -
Basically I know generally how it is done, but am running into snags with fine details (as is so often the case). I've tried using the split, mid and left functions, but they don't seem to be working so well with integers. I tend to get a lot of out of range errors when using these functions to put data into arrays. Am I wrong in thinking they are made for text strings? Forgive the dumb questions, but as I've said I'm still fairly new to everything.
Thanks for the patience guys.
-
Oct 20th, 2009, 09:28 AM
#16
Hyperactive Member
Re: Receiving data from serial port
I too use the basic stamp, and the "sx".
I use pbasic, sxbasic mainy.
Parsing Well, I use ASCII characters it's ez.
Did you see msdn "FAQ:Transmitting and Receiving Binary Data with MSComm Control"?
CDRIVE and DickGrier, are bang on,
Code:
Private Type myComm
Dun As Boolean
mybits() As Byte
End Type
Dim ByteDataArr() As myComm
This is in the MSComm OnComm event,
FF FF is start, so store packet in ByteDataArr(3), and ByteDataArr(2).Dun = True
Now out of the MSComm OnComm event,
if ByteDataArr(2).Dun = True and Addchecksum(ByteDataArr(2)) then ...... else dump_packet
The Project I'm on has me tide down now, but asp I'll be back working on the sx Project.
.
-
Oct 20th, 2009, 04:44 PM
#17
Re: Receiving data from serial port
Originally Posted by 5ms?
Now out of the MSComm OnComm event,
if ByteDataArr(2).Dun = True and Addchecksum(ByteDataArr(2)) then ...... else dump_packet
What is Addchecksum?
<--- Did someone help you? Please rate their post. The little green squares make us feel really smart!
If topic has been resolved, please pull down the Thread Tools & mark it Resolved.
Is VB consuming your life, and is that a bad thing??
-
Oct 20th, 2009, 05:03 PM
#18
Hyperactive Member
Re: Receiving data from serial port
A Function name, no a good name so maybe,
check_checksum, checksum_Check, checksum_OK, Validate_Checksum or IsChecksum_OK
-
Oct 20th, 2009, 05:10 PM
#19
Hyperactive Member
Re: Receiving data from serial port
I like,
Public Function ChecksumIs_OK(Index As Long) As Boolean
Last edited by 5ms?; Oct 20th, 2009 at 05:17 PM.
-
Oct 20th, 2009, 05:22 PM
#20
Hyperactive Member
Re: Receiving data from serial port
Is it that you are trying to read bytes but using an integer variable? That will give you problems of a weird nature.
Slower than a crippled Vista
More buggy than a fresh XP install
Look! Down the road, some 50 miles behind the drunken snail.
It's Ubuntu!
-
Oct 20th, 2009, 06:23 PM
#21
Re: Receiving data from serial port
Originally Posted by AsmIscool
Is it that you are trying to read bytes but using an integer variable? That will give you problems of a weird nature.
If you're referring to this...
Originally Posted by 5ms?
I like,
Public Function ChecksumIs_OK(Index As Long) As Boolean
then (Index As Long) does not point to or refer to the Byte value. I would think that it references its (Index) only. Admittedly, I'm not a wiz-bang with functions.
<--- Did someone help you? Please rate their post. The little green squares make us feel really smart!
If topic has been resolved, please pull down the Thread Tools & mark it Resolved.
Is VB consuming your life, and is that a bad thing??
-
Oct 21st, 2009, 09:17 AM
#22
Hyperactive Member
Re: Receiving data from serial port
Originally Posted by CDRIVE
If you're referring to this...
then (Index As Long) does not point to or refer to the Byte value. I would think that it references its (Index) only. Admittedly, I'm not a wiz-bang with functions.
CDRIVE, you're bang on,
This Pseudocode, An illustration of, Out of the MSComm OnComm event
Now out of the MSComm OnComm event,
Code:
if ByteDataArr(2).Dun = True and Addchecksum(ByteDataArr(2)) then ...... else dump_packet
Should be
Code:
if ByteDataArr(2).Dun = True and ChecksumIs_OK(2) then ...... else dump_packet
-
Oct 22nd, 2009, 06:35 AM
#23
Lively Member
Re: Receiving data from serial port
In general these types of data are sent in frames with a particular gap in between. I am using comm from the time of QuickBasic3, I saw that the gap detection is the best way of separating frames.
To do this I'm entering a procedure when the first data receive event occurs. This can be detected either by mscomm1_oncomm (especially if you are using high baud rates, e.g. above 38400) or by polling using a timer of, say 50ms.
When the procedure is entered set the gap counter, perform a do loop, in every loop wait for some ms depending on baud rate and check for new data is received. If received then refresh gap counter, if not received count gap counter down. When gap counter is zero assume that the frame is terminated. Then you can do anything with the received data, for your case check for the first two bytes FF FF, calculate and check checksum, according to length of the frame decide which data is received etc.
The critical point in this logic is to decide for a loop counter which will result 1ms. I'm doing it at the beginning of the program checking the computer speed for 1 second and setting a value for the loop counts. It is not precise, but precision is not required for this system. If you are interested I can send sample code.
Sabri
-
Oct 22nd, 2009, 05:44 PM
#24
Re: Receiving data from serial port
What's the status of this thread? Are you making progress?
<--- Did someone help you? Please rate their post. The little green squares make us feel really smart!
If topic has been resolved, please pull down the Thread Tools & mark it Resolved.
Is VB consuming your life, and is that a bad thing??
-
Oct 22nd, 2009, 09:13 PM
#25
Thread Starter
New Member
Re: Receiving data from serial port
Yes, definitely making progress. Sorry I haven't been replying for the last couple days. My plate has been rather full. So far the info I've gotten from everyone has been very helpful. Especially 5ms?'s referral to the FAQ:Transmitting and Receiving Binary Data with MSComm Control. I still have a bit more work to do with it, and still a couple hurdles to get over (I've never used files for binary access, what a trip this has turned out to be), but I'm getting there slowly-but-surely. When I am done I will mark the thread as resolved and post the code I'm using to make it work for you all the look over.
Once again, thank's everyone for the help. If you have any more suggestions, then please feel free to keep them coming. Every little bit helps. Especially when it's a personal project I'm working on that I'm not trained for.
-
Oct 22nd, 2009, 09:19 PM
#26
Thread Starter
New Member
Re: Receiving data from serial port
kiymik,
I am very interested in seeing any code you have to do this. What you say makes sense. I shouldn't have too much problem with high baud rates as the rate of the instrument I am reading from is only 9600. Thanks in advance for the information. It is much appreciated.
-
Oct 22nd, 2009, 09:51 PM
#27
Re: Receiving data from serial port
This code might be useful to you. I simulated MSComm by putting your data in a textbox as it would if MSComm inputted it, as one long data stream. I then separated each line based on "FF FF" in the Command1_Click event.
Set the TextBox to Multiline in Properties and make the TextBox about 6 inches wide and 6 inches high.
Code:
Option Explicit
Dim myData As String
Dim sepLines() As String
Private Sub Form_Load()
Command1.Caption = "Split Lines"
myData = "FF FF 00 00 39 00 01 00 20 00 58 " '(Anemometer and Wind Data)
Text1.Text = myData
myData = "FF FF 06 40 23 02 37 07 8B 21 17 00 06 70 " '(Inside Temp, Humidity, etc)
Text1.Text = Text1.Text & myData
myData = "FF FF 0E 48 54 " '(sequence number)
Text1.Text = Text1.Text & myData
myData = "FF FF 02 31 73 01 25 00 CA " '(extra sensors)
Text1.Text = Text1.Text & myData
End Sub
Private Sub Command1_Click()
sepLines = Split(Text1.Text, "FF FF") ' "FF FF" Delimiter
Text1.Text = sepLines(1) & vbNewLine
Text1.Text = Text1.Text & sepLines(2) & vbNewLine
Text1.Text = Text1.Text & sepLines(3) & vbNewLine
Text1.Text = Text1.Text & sepLines(4) & vbNewLine
End Sub
<--- Did someone help you? Please rate their post. The little green squares make us feel really smart!
If topic has been resolved, please pull down the Thread Tools & mark it Resolved.
Is VB consuming your life, and is that a bad thing??
-
Oct 23rd, 2009, 12:05 AM
#28
Addicted Member
Re: Receiving data from serial port
Could you not insert CrLf every 116 characters to break up each line. That would include 4 bits for FF at each end and 112 data bits.
-
Oct 23rd, 2009, 12:56 AM
#29
Thread Starter
New Member
Re: Receiving data from serial port
CDDRIVE,
Well, I seem to be running into the same problems again. I think a good part of these problems are due to me not clarifying exactly whats going on in previous posts. This is a bad habit of mine, forgive me. Not to mention I'm still fairly new to forums.
Well here's the deal. I've tried something very much along the lines of the code you suggested to me on post #27. The problem is that the examples I put in my first post were taken from a Serial Device Monitor program which displays them in the format you see. But when I'm trying to work with variables derived from MsComm's input, I'm having a lot of trouble getting them to stay in that format. I can read them as ASCII fine, but keeping them in a number format has proven difficult for me.
Earlier tonight I thought I had a stroke of genius. I decided to make a hybrid of code I have read of yours on another post mentioned earlier in this thread and code I had found from the FAQ also mentioned above and I came up with this. It takes the decimal derived from the binary and attempts to input it to a text file.
Code:
Private Sub Form_Load()
MSComm1.CommPort = 1
MSComm1.Settings = "9600,n,8,1"
MSComm1.RThreshold = 2
MSComm1.InputMode = comInputModeBinary
MSComm1.PortOpen = True
End Sub
Private Sub MSComm1_OnComm()
If MSComm1.CommEvent = comEvReceive Then
Dim InBuffer
Dim DimensionedByteArray(36) As Byte ' Can handle up to 36 Bytes
Dim intCount As Integer
Dim intDecimal As Integer
Dim strFilePath As String
Dim FileNum As Integer
InBuffer = MSComm1.Input
For intCount = 0 To (LenB(InBuffer) - 1)
DimensionedByteArray(intCount) = CByte(InBuffer(intCount))
intDecimal = DimensionedByteArray(intCount)
txtBuf.Text = txtBuf.Text & " " & intDecimal & vbNewLine ' Display Decimal number
FileNum = FreeFile
strFilePath = "c:\filedata.txt"
Open strFilePath For Input As #FileNum
Do While Not EOF(FileNum)
Line Input #FileNum, intDecimal
Loop
Close FileNum
Next intCount
Debug.Print TypeName(intDecimal) ' Confirm InBuffer data is Integer
End If
End Sub
Well, much to my dismay I realized that I can't input an integer with a file opened in this manner (type mismatch). Is there something wrong with my code? I figure it would be okay to use if I put a massive IF statement in there saying If intDecimal = 0 then strNumber = "0" and so on all the way through 256. Then I could input strNumber to the file. But that much code? There has to be an easier way.
I feel I would have no problem using your split command If I could figure out a way to use it with the kind of variables I'm inputting. See, you're treating the inputs as regular ASCII strings, and Split has no problem with those. But when I try to keep it in a number format it generally doesn't assign anything to the variable array, although I don't seem to get any kind of error. Is there a way to do the same thing, but keep the data in a decimal or even binary format?
I hope I'm making sense here.
I do feel like I'm making progress. And my understanding is growing rapidly of what I'm dealing with. But I'm still hitting hurdles, it seems. Well, I suppose I'll get it eventually. This one has just been a little hard for me to whip.
Thanks again for all the help.
Last edited by EndlessNameless; Oct 23rd, 2009 at 03:24 AM.
-
Oct 23rd, 2009, 01:51 AM
#30
Hyperactive Member
Re: Receiving data from serial port
Originally Posted by CDRIVE
If you're referring to this...
then (Index As Long) does not point to or refer to the Byte value. I would think that it references its (Index) only. Admittedly, I'm not a wiz-bang with functions.
Wasn't looking at anyones code in particular mate. It is just a common mistake that I am embarrassingly quite familiar with.
Seems like such a trivial task when you have done it before. First time makes you lose a few follicles though.
Slower than a crippled Vista
More buggy than a fresh XP install
Look! Down the road, some 50 miles behind the drunken snail.
It's Ubuntu!
-
Oct 23rd, 2009, 02:37 AM
#31
Thread Starter
New Member
Re: Receiving data from serial port
Oh, and I apologize for my code coming in as a paste and not under a code format. Sorry about that.
-
Oct 23rd, 2009, 02:41 AM
#32
Re: Receiving data from serial port
yes, you can use CStr() to convert the Integer value, to be represented by string.
CStr(100) will be = "100"
You can also use the Hex$() to convert them to hexadecimals. (it will be "64")
Code:
For intCount = 0 To (LenB(InBuffer) - 1)
DimensionedByteArray(intCount) = CByte(InBuffer(intCount))
intDecimal = DimensionedByteArray(intCount)
txtBuf.Text = txtBuf.Text & " " & intDecimal & vbNewLine ' Display Decimal number
FileNum = FreeFile
strFilePath = "c:\filedata.txt"
Open strFilePath For Input As #FileNum
Do While Not EOF(FileNum)
Line Input #FileNum, intDecimal
Loop
Close FileNum
Next intCount
Debug.Print TypeName(intDecimal) ' Confirm InBuffer data is Integer
End If
Well, im not quite understand this part of the code. You are walking thru the InBuffer() array in the For ... Next loop, thats right. But why are you opening the file at each byte, then try to read that intDecimal thing (that is might wont work since you cant directly read into integer value types). To make it to work do it like this:
Code:
'...
Dim strFilePath As String, sInputVal as String
'...
Line Input #FileNum, sInputVal
intDecimal = CInt(Int(sInputVal))
But i'm still not sure about what are you loading up.
-
Oct 23rd, 2009, 02:58 AM
#33
Thread Starter
New Member
Re: Receiving data from serial port
Jim,
Hello and thank you for the response. Basically this is patch work of me just trying to 'get it to work'. Bad form, I know, but I'm fairly new to vbasic6. I stumbled upon the first part of this code when I was searching for a way to do this. It is located here:
http://www.vbforums.com/showthread.p...03#post3376003
When I ran this code with a few modifications, I was able to print out the decimal values of the binary to a text box, which I figured would work fine for my purposes. But I'm having a lot of trouble parsing the data any further. Then I had the FAQ named FAQ:Transmitting and Receiving Binary Data with MSComm Control from MSDN suggested to me and it proved useful as well.
I noticed in the FAQ that they were using a file to store data after it was received, so I figured why not. If I can write each of the decimal numbers to a different line in a text file the same way I did the text box, I can use the file to read and parse the data from.
Basically it didn't work and I'm still open to suggestions. Remember I am still very new to vbasic. I have the basics, of course, but some of my knowledge is lacking, so I'm sort of learning as I go.
CStr() and CInt() are both new functions to me though, so I will certainly try this out.
Thanks so much for the input!
-
Oct 23rd, 2009, 03:09 AM
#34
Hyperactive Member
Re: Receiving data from serial port
Have you tried using a gridcontrol and write your data to that. It is a bit difficult to understand your problem when you say 'it didn't work'. That really doesn't give any information about how it didn't work.
Slower than a crippled Vista
More buggy than a fresh XP install
Look! Down the road, some 50 miles behind the drunken snail.
It's Ubuntu!
-
Oct 23rd, 2009, 03:17 AM
#35
Thread Starter
New Member
Re: Receiving data from serial port
Originally Posted by EndlessNameless
Well, much to my dismay I realized that I can't input an integer with a file opened in this manner (type mismatch)..
It was a type mismatch error on intDecimal. Jim Davis did a fairly good job of explaining what I need to do to remedy that specific problem, though. At least it looks doable.
As far as using a gridcontrol, no I've not tried it. I will do some research on it and see what I come up with. Thank you for the suggestion.
-
Oct 23rd, 2009, 03:37 AM
#36
Re: Receiving data from serial port
Writing out to file, then reading back, and all this hassle because of a tiny-mini parsing? No way! I would use arrays instead of that. Later, when you parsed one or more packets, you can log the results into a debug file of course, but thats not play in the parsing process. So, i would remove those file operations, and use an array instead of that.
I have the basics, of course, but some of my knowledge is lacking,
I would say that parsing packets from a device might be not a basic operation, and might takes some hours to you to understand how it will work. As long as you ask, i'm sure we can help you with that process.
-
Oct 23rd, 2009, 03:42 AM
#37
Thread Starter
New Member
Re: Receiving data from serial port
Jim,
Ok, noted. I'll do that. I was having trouble with arrays when I was trying to use them before, but I will look them up again and make sure I have them right, then write up what I think is the right code. If I have problems I'll be sure to ask about them. Thanks for the suggestions.
-
Oct 23rd, 2009, 10:15 AM
#38
Lively Member
Re: Receiving data from serial port
First measure computer speed, the code operates well on quite different pc's with different speeds. There are some protections against wrong calculation, this is why it is long . Wait1 is a global variable defining the number of loops to obtain 1ms at the end, can be single or long. The L = L lines are dummy here, just to do something within the loop, you can remove it and get a more precise WCou1, but the probability of wrong calculation on different computers increases (because of paging mechanism of CPU operation).
HTML Code:
' Calculate loop counts for 1ms
Private Sub CalcWait1()
Dim T1 As Single, T2 As Single
Dim L As Long, M As Long, N As Long
While Timer > 86395: Wend
M = 0
T1 = Timer
While Abs(Timer - T1) < 0.001: Wend
T1 = Timer + 0.1
N = 999
Do
For L = 1 To N
L = L
L = L
L = L
L = L
L = L + 0
Next L
M = M + 1
Loop Until Timer >= T1
If M > 1000 Then
N = 99999
ElseIf M > 100 Then
N = 9999
ElseIf M > 10 Then
N = 999
Else
N = 99
End If
M = 0
T1 = Timer
While Abs(Timer - T1) < 0.001: Wend
T1 = Timer + 1
Do
For L = 1 To N
L = L
L = L
L = L
L = L
L = L + 0
Next L
M = M + 1
Loop Until Timer >= T1
T2 = Timer
L = 0
Do
L = L
L = L
L = L
L = L
L = L + 1
Loop Until Timer > T2
T2 = Timer - T1 + 1
Wait1 = (CDbl(M) * (N + 1) + L) / T2 / 1000
End Sub
Within MSComm1_OnComm you can now read the whole frame. The CommBusy is a global boolean that you have to be sure it is false at start, otherwise MSComm1_OnComm will never execute. The procedure actually starts when a receive event occurs, at the end the message returns in global variable RcvStr string. In this example 2ms wait loops are used to detect 50ms gap. This method has the advantage of receiving very long high speed messages with a small buffer. In one of my applications I'm using 115200 baud and receiving more than 100000 characters at once, every 2ms I have to deal with only about 25 characters. If a DoEvents last for 100 ms (that is quite a long time) up to 1150 characters may be filled in buffer, so buffer has to be selected accordingly (no need for your case). For more critical applications length restrictions may be inserted into the code to avoid crash.
Code:
Private Sub MSComm1_OnComm()
Dim I As Integer, J As Long, L As Long, M As Long
Dim A As String
Dim C() As Byte, LWCou As Integer
If MSComm1.CommEvent <> comEvReceive Then Exit Sub
If CommBusy Then Exit Sub
CommBusy = True
RcvStr = ""
M = Wait1 * 2 ' 2ms loop counts
Do
DoEvents
If MSComm1.InBufferCount > 0 Then
C = MSComm1.Input
A = ""
For I = 0 To UBound(C)
A = A & Chr(C(I))
Next I
RcvStr = RcvStr & A
LWCou = 0
End If
For L = 1 To M ' 2ms wait
L = L
L = L
L = L
L = L
L = L + 0
Next L
LWCou = LWCou + 1
If LWCou > 25 Then Exit Do ' 50ms no data
Loop
CommBusy = False
End Sub
You can periodically check whether RcvStr has data in it. Besides you also have to check CommBusy to be false to assure that the receiving procedure is completed and message is valid.
You wrote that the fields of the message was known. Most probably they are not using floating point representation. So you can make a simple calculation by ascii values of the characters in string. Example, for 2 byte data in 3'rd and 4'th bytes of RcvStr,
Temperature = 256& * Asc(Mid(RcvStr,3,1)) + Asc(Mid(RcvStr,4,1))
Of course high and low bytes may be reverse
Sabri
-
Oct 23rd, 2009, 10:21 AM
#39
Lively Member
Re: Receiving data from serial port
I forgot to remind you that receive mode must be binary and receive threshold=1.
If you face with any problem please inform me, sometimes I'm stuck to some settings of my own for years and forget to tell about them.
Sabri
-
Oct 23rd, 2009, 12:27 PM
#40
Re: Receiving data from serial port
Code:
For L = 1 To M ' 2ms wait
L = L
L = L
L = L
L = L
L = L + 0
Next L
To wait 2 mseconds, why dont you use the Sleep() api call? Why the unnecessary high cpu load, i dont get it.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|