reading serial port till it reachesa certain chr
reading serial port till it reachesa certain chr
reading serial port till it reachesa certain chr
reading serial port till it reachesa certain chr
reading serial port till it reachesa certain chr
reading serial port till it reachesa certain chr reading serial port till it reachesa certain chr reading serial port till it reachesa certain chr reading serial port till it reachesa certain chr reading serial port till it reachesa certain chr reading serial port till it reachesa certain chr reading serial port till it reachesa certain chr reading serial port till it reachesa certain chr
reading serial port till it reachesa certain chr reading serial port till it reachesa certain chr
reading serial port till it reachesa certain chr
Go Back  Xtreme Visual Basic Talk > > > reading serial port till it reachesa certain chr


Reply
 
Thread Tools Display Modes
  #1  
Old 04-21-2008, 08:41 AM
Dasco Dasco is offline
Newcomer
 
Join Date: Mar 2008
Posts: 18
Default reading serial port till it reachesa certain chr


Hello,
how can I do that?
i send a command and the reply has a stop character ( chr 13) but the length is variable.
I want to read the buffer till it reaches chr(13) then send the next command.
any help is more than appreciated.
Reply With Quote
  #2  
Old 04-21-2008, 09:14 AM
the master's Avatar
the master the master is offline
Tachikoma
 
Join Date: Mar 2003
Location: Mansfield, UK
Posts: 4,596
Default

I take it you are using the MScomm control. You need some kind of buffer. You keep adding all your data to the buffer in the oncomm event. On each event check your buffer to see if chr(13) is in it

Something a bit like this
Code:
dim strInputBuffer as string Private Sub MSComm1_OnComm() 'Make sure the event is a receive event If MSComm1.CommEvent = comEvReceive Then 'Add the new data to the buffer strInputBuffer = strInputBuffer & MSComm1.Input 'Now check if it contains your character If InStr(1, strInputBuffer, vbCr) > 0 Then 'Chr(13) (AKA vbCr) has been received! 'Clear your buffer strInputBuffer = "" 'Now do whatever you need to do here End If End If End Sub
__________________
"That which seems simple is often overlooked" ~ me
Halloween 2014 Yard Haunt
Halloween Special FX
Reply With Quote
  #3  
Old 04-22-2008, 04:26 AM
Dasco Dasco is offline
Newcomer
 
Join Date: Mar 2008
Posts: 18
Default

thanks the master,
I rewrote your example in een doeven loop :

strInputBuffer = strInputBuffer & MSComm1.Input
Do
DoEvents
Loop Until InStr(1, strInputBuffer, vbCr) > 0
received = strInputBuffer
Text2.Text = received
strInputBuffer = " "

it is not working!!
what did i do wrong here??
Reply With Quote
  #4  
Old 04-22-2008, 06:19 AM
the master's Avatar
the master the master is offline
Tachikoma
 
Join Date: Mar 2003
Location: Mansfield, UK
Posts: 4,596
Default

Theres a few things wrong with that code. First you add more data to the buffer then go into your loop. You loop will only end when the CR character appears in the buffer but you havnt coded away to get it into the buffer (now you can a never ending loop).

You would normally use "do while" instead of "loop while". A loop while will cause the loop to run at least once. You dont need it to run if the character was there in the first place so you run doevents for no reason.

Is there a reason you are using the variable called "received"? If its because you use it elsewhere in the code then thats fine but for the bit youve shown me it would be better to just put the contents of strInputBuffer into the textbox.

Why are you using a loop? Using a loop means your app will be using 100% CPU until the data finishes arriving. Rather than keeping a loop going its better to wait for the control to tell you when it has data like in the origional example i provided
__________________
"That which seems simple is often overlooked" ~ me
Halloween 2014 Yard Haunt
Halloween Special FX
Reply With Quote
  #5  
Old 04-22-2008, 06:58 AM
Dasco Dasco is offline
Newcomer
 
Join Date: Mar 2008
Posts: 18
Default

this is my complete code:
If Dir("c:\mine\") = "" Then
MkDir "c:\mine\"
End If
Open "c:\mine\commands.txt" For Input As #1
Open "c:\mine\mine.txt" For Output As #2
Line Input #1, a
'The very first line
'MsgBox a
If MSComm1.PortOpen = True Then
Do Until EOF(1)
Line Input #1, a
send = a
MSComm1.Output = send & Chr(13)
Text1.Text = send

If MSComm1.CommEvent = comEvReceive Then

strInputBuffer = strInputBuffer & MSComm1.Input

If InStr(1, strInputBuffer, vbCr) > 0 Then

Text2.Text = strInputBuffer

strInputBuffer = ""
End If
End If
Print #2, send & Chr(32) & Text2.Text
Loop
Close #1
Close #2
End If
intMsg = MsgBox("Done!! log file : c:\mine\mine.txt")
Text2.Text = "Finished"
Text1.Text = "Finished"
End Sub

as you see i am trying to open a command file , send the content line by line and read the reply and log send and received data.
the problem occurs when i am reading the file because the length of reply is variable.
I want to be able to show the value in textbox ( and eventually save the data in a file) that i get from mscomm.input till chr(13) occurs.
I am doing something very wrong , but what is it ?
Reply With Quote
  #6  
Old 04-22-2008, 08:30 AM
the master's Avatar
the master the master is offline
Tachikoma
 
Join Date: Mar 2003
Location: Mansfield, UK
Posts: 4,596
Default

Right, I see why you think you need a loop but you dont. There is a more efficient way to do what you want.

You need a start sub (probably cmdStart_click or something like that). In that sub you open both files then call another sub called something like "SendNextLine"

In the SendNextLine sub you only need to read 1 line from the file and send it out of the comm port.

Now in the MSComm1_OnComm event you buffer the input as described in post #2. Where i have put "'Now do whatever you need to do here" you put some code to check if there are anymore lines in the file. If not then close the files. If there are then call that "SendNextLine" sub again.

If you want to log the data that comes back then the best place to do it would be just before clearing the buffer in the code from post #2.

The basic idea is that you send a line then stop and wait. You dont need a loop because the MSComm control will tell you when it has data. When that data comes in you keep buffering it until you know its complete. Once its complete you can log the data and send 1 more line.

Edit: When you open a file you shouldnt use a set number. You should get a unique number by calling FreeFile and storing its return value in a variable
__________________
"That which seems simple is often overlooked" ~ me
Halloween 2014 Yard Haunt
Halloween Special FX
Reply With Quote
  #7  
Old 04-22-2008, 12:36 PM
Dasco Dasco is offline
Newcomer
 
Join Date: Mar 2008
Posts: 18
Default

ok now i am lost!!
how can i open a file and read the data line buy line without using a loop?
and what did you mean in EDIT part?
so it would be something like this :
Private Sub Command1_Click()
nFileNum = FreeFile
nFileNumout = FreeFile
If Dir("c:\mine\") = "" Then
MkDir "c:\mine\"
End If
Open "c:\mine\commands.txt" For Input As nFileNum
Open "c:\mine\mine.txt" For output As nFileNumout

CallSubroutine "SubA"
End Sub

Public Sub SubA()

lLineCount = 1
Do While Not EOF(nFileNum)
Line Input #nFileNum, sNextLine
If MSComm1.PortOpen = True Then
MSComm1.Output = SNextLine &chr(13)
Loop

Close nFileNum

End Sub

End Sub
dim strInputBuffer as string

Private Sub MSComm1_OnComm()

'Make sure the event is a receive event
If MSComm1.CommEvent = comEvReceive Then

'Add the new data to the buffer
strInputBuffer = strInputBuffer & MSComm1.Input

'Now check if it contains your character
If InStr(1, strInputBuffer, vbCr) > 0 Then

'Chr(13) (AKA vbCr) has been received!
Print #2, SNextLine & Chr(32) & strInputBuffer
'Clear your buffer
strInputBuffer = ""

'Now do whatever you need to do here
End If
End If
End Sub
??????
Reply With Quote
  #8  
Old 04-22-2008, 01:32 PM
the master's Avatar
the master the master is offline
Tachikoma
 
Join Date: Mar 2003
Location: Mansfield, UK
Posts: 4,596
Default

You seem to have understood the bit in my edit correctly.

I think you are nearly there. Just to double check, are you wanting to get a seperate reply for each line in the file? (thats how i understood it)

You cant load a file line by line without some kind of loop. The loop im suggesting doesnt look like a loop at all because its not a do-loop or a for-next loop etc. The way it works is that you send a single line. When you get the reply from that line you send the next line. This results in a kind of loop. Sending a line means you get a reply and when you get a reply you send a line (until the end of the file ofcourse)

I think you almost have it. You just dont send all the lines in a loop

Tip: When posting VB code use the [ VB ] [ /VB ] tags
__________________
"That which seems simple is often overlooked" ~ me
Halloween 2014 Yard Haunt
Halloween Special FX
Reply With Quote
  #9  
Old 04-22-2008, 04:20 PM
Dasco Dasco is offline
Newcomer
 
Join Date: Mar 2008
Posts: 18
Default

yes i need a separate reply for each line
basically what i want is:
open the data file to be sent ( and a log file) , read only one line , sends it and wait for the reply and stop buffering when it receives chr(13) and log them in the (opened) file.
if i am not mistaking the subA from the code from my previous msg goes thru the whole file line by line till the end of the file and then stops.
now the question is if i put the loop in my main sub I have to include the sending and receiving ( and buffering the received data) in my main sub and there is where my problems start.
this is what i came up :
Code:
dim strInputBuffer as string Private Sub Command1_Click() nFileNum = FreeFile nFileNumout = FreeFile If Dir("c:\mine\") = "" Then MkDir "c:\mine\" End If Open "c:\mine\commands.txt" For Input As nFileNum Open "c:\mine\mine.txt" For Output As nFileNumout If MSComm1.PortOpen = True Then Do Until EOF(nFileNum) Line Input #nFileNum, send If MSComm1.CommEvent = comEvSend Then MSComm1.Output = send & Chr(13) MSComm1.CommEvent = comEvReceive If MSComm1.CommEvent = comEvReceive Then strInputBuffer = strInputBuffer & MSComm1.Input If InStr(1, strInputBuffer, vbCr) > 0 Then Print #2, SNextLine & Chr(32) & strInputBuffer strInputBuffer = "" End If End If End If Loop End If Close nFileNum Close nFileNumout End Sub

Last edited by webbone; 04-22-2008 at 11:02 PM. Reason: added code tags and indented, also added missing End If's
Reply With Quote
  #10  
Old 04-23-2008, 02:12 AM
the master's Avatar
the master the master is offline
Tachikoma
 
Join Date: Mar 2003
Location: Mansfield, UK
Posts: 4,596
Default

I think you were closer with the code you had before.

Lets think about it a different way. Think of it as a conversation because thats basicly what it is. Your PC and whatever is connected to it are "talking" to each other. Now, if you were talking to me you would ask a question and wait for a reply. You wouldnt ask me a whole bunch of questions without letting me reply to 1. This is why you dont use a loop (meaning do-loop, for-next etc). Your program is asking all the questions in 1 go. Your program should only be sending 1 line at a time. When you first open the file you run the sub that sends a line then do nothing. You dont need to loop or run any more code. Your app will just sit and wait.

The device will get the line that you sent to it and create a reply. When it sends that reply back the MSComm_oncomm event will fire. Think of this as me replying. On these forums you post a question and wait for me to reply. When i reply you read it then ask another question. Your program should do the same. When the oncomm event is fired the MScomm control is telling your app that it has a reply. Now your code becomes active again. It reads the reply from the comm control and logs it to a file. When its done what it needs to do it sends the next line from the file and the whole process starts again.

What you are doing at the moment is whats known as "polling". You have a loop that repeatedly checks the comm control for data. So, if there is no data then you still check anyway. When you post a question on here you dont sit there pressing F5 non-stop until someone replies do you? That method means your program is stuck in a loop using 100% CPU until the data is returned. Its not very efficient.

The reason for events is that you dont have to check if something has happened. It tells you. Its like getting an email notification that someone has replied to your thread. You dont need to check the forums at all. They send an email (raise an event) when there is a new post.

From what youve said you want you shouldnt have any loop commands in your code. You know that sending a line will get a reply. If you send a line when you get a reply then you have indirectly created a loop

I hope that clears thing up a bit
__________________
"That which seems simple is often overlooked" ~ me
Halloween 2014 Yard Haunt
Halloween Special FX
Reply With Quote
  #11  
Old 05-01-2008, 02:24 PM
the master's Avatar
the master the master is offline
Tachikoma
 
Join Date: Mar 2003
Location: Mansfield, UK
Posts: 4,596
Default

You shouldnt use a loop. What you are trying to do involves sending a line and getting a reply. If you try to add a loop then you will most likely end up with currupt data and it will get very confusing.

You should only send the second line when you get a reply from the first. There is no loop involved. Its the event of your reply coming back that causes the next line to be sent.

I dont know of any other way to explain it but there shouldnt be a loop in your code


Edit:
Quote:
Originally Posted by passel View Post
Thanks. I didn't catch that at all (obviously ).
{Replace=clint999}Dasco{/Replace}
I missed that too. Apologies to Dasco if you understood it before
__________________
"That which seems simple is often overlooked" ~ me
Halloween 2014 Yard Haunt
Halloween Special FX

Last edited by the master; 05-02-2008 at 12:36 PM.
Reply With Quote
  #12  
Old 05-01-2008, 09:09 PM
passel's Avatar
passelreading serial port till it reachesa certain chr passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,024
Default

clint999,

It's called Event driven programming.
Your code runs a million or more times faster than the serial port transfers data, or that a user interacts with the program, so you have a long time to wait, in cpu years for anything to happen.
So, rather than waste time polling in a loop, you place code in handlers (subs) that will be called by the Windows operating system when events that you are interested in happen.

So, the process involves placing code in the various event handlers that you are interested in.
You start the program.
When an event happens, if you have code in that event handler, it gets executed.

For this application, it looks like you are interested in starting a process when the user presses a button, so you put code to start your process in a button event.
When the button is pressed, you open the files, open the port, read the first command from the input file, send the command out the port, and then leave the button event (the process is started).

When data associated with the command is returned through the serial port, the OnComm() event is triggered (see "the master"'s code in post #2).
In this event you add code to check to see what form of comm event it was, and if you have data, copy the data into a buffer. If your terminating character wasn't received (you have to wait for more data), then leave the OnComm event handler to wait for the next event.
Once the terminating character is received, process the data in the buffer, clear the buffer, then check to see if there is another command to be read from the input file.
If so, send the command out the port, and leave the OnComm event handler to wait for the next set of data to be transmitted back through the comm port. Continue this way until there are no more commands in the input file.
Once there are no more commands to read in from the file and send out the port, you can end the process by cleaning up (close the input and output files, close the port, etc) and leave the OnComm event handler for last time (for this process).
pseudo code
Code:
Sub Button Open files Open port Read first command from Input File Send first command out Serial Port End Sub Sub OnComm() ' Mostly refer to "the master"'s example in post #2. ' Re-outlining the logic described above. If event is arrivial of data. Append the data to the input buffer If the terminating character is in the buffer process the buffer (copy to output and textbox, etc) clear the buffer (for the next response) If not End of Input File Then Read next command from File Send command out the port Else 'No more commands Close Input and Output files Close Port End If End If 'terminating character found End If 'Data has arrived End Sub

As "the master" says, looking at the above logic, there is no loop structure in the code you write.
You are processing a sequence of steps, many of which are repeated based on the number of commands in the file.
"While life may be repetitive, it's not a loop"
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.

Last edited by passel; 05-01-2008 at 09:19 PM.
Reply With Quote
  #13  
Old 05-02-2008, 04:05 AM
Timbo's Avatar
Timboreading serial port till it reachesa certain chr Timbo is offline
Green-Eyed

Super Moderator
* Guru *
 
Join Date: May 2001
Location: Bangkok, Thailand
Posts: 10,261
Default

clint999 just liked to copy other people's posts (notice the past tense )
__________________
"He's not the Messiah. He's a very naughty boy!" - Brian's mum

Can't find the answer? >> Try something new!
Become a Professional
Reply With Quote
  #14  
Old 05-02-2008, 12:05 PM
passel's Avatar
passelreading serial port till it reachesa certain chr passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,024
Default

Thanks. I didn't catch that at all (obviously ).
{Replace=clint999}Dasco{/Replace}
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
Reply With Quote
  #15  
Old 05-08-2008, 07:51 AM
Dasco Dasco is offline
Newcomer
 
Join Date: Mar 2008
Posts: 18
Default

I tried and I get the first line and receive a reply back but then program stops
how can i read the next line?
here is my code :
Private Sub Form_Load()
Form1.Caption = "Test"
With MSComm1
.CommPort = 1
.RThreshold = 1
.RTSEnable = True
.Settings = "9600,n,8,1"
.SThreshold = 1
End With
Text1.Text = "Sent"
Text2.Text = "Recieved"
nFileNum = FreeFile
nFileNumout = FreeFile
If Dir("c:\mine\") = "" Then
MkDir "c:\mine\"
End If
Open "c:\mine\commands.txt" For Input As #1
Open "c:\mine\mine.txt" For Output As #2
End Sub
Private Sub Command1_Click()
Dim received As String
Dim send As String
MSComm1.InputLen = 20
If MSComm1.PortOpen = False Then MSComm1.PortOpen = True
Line Input #1, send
Text1.Text = send
If MSComm1.PortOpen = True Then
Do Until EOF(1)
Line Input #1, a
send = a
MSComm1.Output = send & Chr(13)
Text1.Text = send
Print #2, send & Chr(32) & received
'lLineCount = 1
'End If
'End If
'End If
Close #1
Close #2
End Sub

Private Sub Command2_Click()
End
End Sub

Private Sub MSComm1_OnComm()
Dim strInputBuffer As String
If MSComm1.CommEvent = comEvReceive Then
strInputBuffer = strInputBuffer & MSComm1.Input
If InStr(1, strInputBuffer, vbCr) > 0 Then
received = strInputBuffer
Text2.Text = received

End If
End Sub
and one more thing :
how can get filter the chr(13) from my replies?
so in my log file no chr(13) will be seen
thanks
Reply With Quote
  #16  
Old 05-08-2008, 08:44 AM
the master's Avatar
the master the master is offline
Tachikoma
 
Join Date: Mar 2003
Location: Mansfield, UK
Posts: 4,596
Default

Ok, its looking a little better but that loop is still there. There are some other problems too which i will explain then show you the completed code.

First off you dont have "Option Explicit" at the top of your code. You have undefined variables. If you put "Option Explicit" at the top then VB will throw an error when you try to use a variable that has not been defined. Those errors are good because they will force you to write better code.

Your variable scope is wrong. What i mean by this is that a variable declared in 1 sub cannot be accessed by another function unless you pass it as an argument. "Option Explicit" would also help you to see that

Code:
private sub sub1() dim myVariable as integer end sub private sub sub2() 'MyVariable does NOT exist here or anywhere else except within sub1 end sub

Once the sub exits you will lose all the data in any variables that were declared within that sub. That means that if the same sub is called again then your variables will be empty. Your buffer will not work because of this reason. If you want to declare a variable for use only in 1 sub but you want it to retain its data between calls then use "Static" instead of "Dim".

I see you have some variables which need to be used accross more than 1 sub for example "received" is declared in Command1_Click but you also reference it in MSComm1_OnComm. In the OnComm event there is no such variable. In this case you must declare your variable in the declarations section (above all subs and functions). Now it will retain its data as long as the form is open and it will be accessible by all subs and functions in that form.

You are off to a good start by using FreeFile to get unique file IDs but you have still used 1 and 2 for the file operations themselves. Because you use the same files accross multiple subs you will need to declare the variables that hold the file IDs in the declarations section but you must also use them when performing file operations

Example
Code:
nFileNum = FreeFile Open "c:\mine\commands.txt" For Input As #nFileNum

You only need to use your files after you click the command button so it makes more sense to open them in the command1_click event. Opening them in form_load will not affect how your program runs but it means you have files open (and probably blocked from being deleted etc by other apps) when you dont need them.

In your command1_click sub you should be reading 1 line of data from the file then sending it to the comm port. Leave it at that for that sub. "MSComm1.Output..." should be your last line in that sub.

In command2_click its better to use "unload me" instead of "end".

When you do your check to see if the input buffer contains a Cr you have to remember to empty it. If you do not clear the buffer after receiving a Cr then all other comm receive events will act asif a Cr was returned because there is still one there from before.

To answer your question about removing the Cr. You can use Instr() to get the position of the first Cr then Left() to get all characters before that position.
Code:
strInputBuffer = Left(strInputBuffer, InStr(1, strInputBuffer, vbCr) - 1)

After you have logged the reply and cleared the buffer etc then check if you are at the end of the file. If yes then close the files and your done. If not then load the next line and send it. Now, same as before, you leave it at that, no loops or anything. When the reply comes back it will be buffered and either cause another reply to be sent or close the files.

Take a look at the Standards and Practices Tutorial. It a big read but its definately worth it. Especially checkout "Scope".

Now for the final code. I obviously cant test this properly because i dont have your device but as far as i can see it should work.
Code:
Option Explicit Dim nFileNum As Integer Dim nFileNumout As Integer Private Sub Form_Load() Form1.Caption = "Test" With MSComm1 .CommPort = 1 .RThreshold = 1 .RTSEnable = True .Settings = "9600,n,8,1" .SThreshold = 1 End With Text1.Text = "Sent" Text2.Text = "Recieved" If Dir("c:\mine\") = "" Then MkDir "c:\mine\" End If End Sub Private Sub Command1_Click() Dim send As String nFileNum = FreeFile Open "c:\mine\commands.txt" For Input As #nFileNum nFileNumout = FreeFile Open "c:\mine\mine.txt" For Output As #nFileNumout MSComm1.InputLen = 20 If MSComm1.PortOpen = False Then MSComm1.PortOpen = True Line Input #nFileNum, send Text1.Text = send MSComm1.Output = send & Chr(13) End Sub Private Sub Command2_Click() Unload Me End Sub Private Sub MSComm1_OnComm() Static strInputBuffer As String Dim send As String If MSComm1.CommEvent = comEvReceive Then strInputBuffer = strInputBuffer & MSComm1.input If InStr(1, strInputBuffer, vbCr) > 0 Then strInputBuffer = Left(strInputBuffer, InStr(1, strInputBuffer, vbCr) - 1) Print #nFileNumout, strInputBuffer Text2.Text = strInputBuffer strInputBuffer = "" If EOF(nFileNum) Then Close #nFileNum Close #nFileNumout Else Line Input #nFileNum, send Text1.Text = send MSComm1.Output = send & Chr(13) End If End If End If End Sub

Tip: When posting VB code use the [ VB ] [ /VB ] tags. It makes your code a lot easier to read

Edit: Ive just changed the lines that get free file IDs. You must open the first file before getting an ID for the second otherwise the first one is still considered "free" and you will end up with 2 identical IDs
__________________
"That which seems simple is often overlooked" ~ me
Halloween 2014 Yard Haunt
Halloween Special FX
Reply With Quote
  #17  
Old 05-09-2008, 04:03 PM
Dasco Dasco is offline
Newcomer
 
Join Date: Mar 2008
Posts: 18
Default

I see that i was pretty close but nevertheless i needed that extra help
thanks alot guys and specially the master
i tried it and it is working
I was wondering how can i detect which com port is available and how to implement it in scroll down box.
Reply With Quote
  #18  
Old 05-10-2008, 05:14 AM
the master's Avatar
the master the master is offline
Tachikoma
 
Join Date: Mar 2003
Location: Mansfield, UK
Posts: 4,596
Default

Im glad its working. As for the available comm ports i believe that the MSComm control can only handle 1 to 10. The simplest way to check the availability is to set the comm control to the port and try to open it. Success means its available and an error means its not. You can use a for-next loop to check all comm ports 1 to 10 but i think that will be fairly slow and it will lock your app up while trying each one.

Usually the way people do it is to have a combo box that lists all comm ports whether or not they are available or even exist. When you try to open the port then it either works or a message box opens up saying "The selected port cannot be accessed" or something similar. This way would be slightly more annoying if the user has to keep trying ports until they find the correct one but usually they will be using COM1 or COM2 and they should know which port their device is connected to anyway so they wont want to wait for your app to check all 10 when they know they want COM2
__________________
"That which seems simple is often overlooked" ~ me
Halloween 2014 Yard Haunt
Halloween Special FX
Reply With Quote
  #19  
Old 05-10-2008, 05:08 PM
mkaras's Avatar
mkarasreading serial port till it reachesa certain chr mkaras is offline
Ultimate Contributor

Retired Leader
* Expert *
 
Join Date: Mar 2004
Location: Beaverton, OR
Posts: 1,874
Default Filling a Commport Menu List

There are various ways to present an available Comm Port list to a user of your program. One method I have used is as shown in the first attached image attachment below. The initial design of the menu would follow the structure in the Menu Design Wizard as I have shown in the second image attachment below.

Within the Form_Load() event of the form with the menu you include a call such as follows to fill in the list of the available Comm Ports:
Code:
Private Sub Form_Load() ' build the available COMM port list Call FillPortList

The subroutine that fills in the Comm Port List is shown below. This attempts to map up to 16 Comm ports because the current versions of MSComm are capable of dealing correctly with ports 1 - 16. As a port is found it is added to the menu item list using a Load command to attach another item. Note how this uses the .Tag property of each entry to store the actual Comm port number for later easy reference.
Code:
' ' routine to populate the comm port menu with the available comm ports ' (Note that this stores the comm port number values into the .Tag property ' for later port number reference). ' ' (Only call this once from the FORM load event). Private Sub FillPortList() Dim pNum As Integer Dim PIdx As Integer PIdx = 0 For pNum = 1 To 16 ' scan the available COMM ports If COMAvailable(pNum) = True Then ' found a port If PIdx = 0 Then ' use default first menu item mnuPort(0).Caption = "COM" & Format(pNum, "0") mnuPort(0).Tag = Format(pNum, "0") Else Load mnuPort(PIdx) mnuPort(PIdx).Caption = "COM" & Format(pNum, "0") mnuPort(PIdx).Tag = Format(pNum, "0") End If PIdx = PIdx + 1 End If Next pNum End Sub

The above menu population routine uses a subroutine that checks to see if a Comm port is available for use by this program. The code for this subroutine is shown below. Note that this subroutine will not report Comm ports that are unavailable due to being open in another application. Also note that this code is placed into a module and makes use of an API call to check on the Comm port availability.
Code:
' ' Module of code to check if a particular COMM port number is ' available for use by this program ' Option Explicit ' API Declarations Public Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As SECURITY_ATTRIBUTES, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long ' API Structures Public Type SECURITY_ATTRIBUTES nLength As Long lpSecurityDescriptor As Long bInheritHandle As Long End Type ' API constants Public Const FILE_SHARE_READ = &H1 Public Const FILE_SHARE_WRITE = &H2 Public Const OPEN_EXISTING = 3 Public Const FILE_ATTRIBUTE_NORMAL = &H80 ' Return TRUE if the COM exists, FALSE if the COM does not exist Public Function COMAvailable(COMNum As Integer) As Boolean Dim hCOM As Long Dim ret As Long Dim sec As SECURITY_ATTRIBUTES '// try to open the COM port hCOM = CreateFile("\\.\COM" & COMNum & "", 0, FILE_SHARE_READ + _ FILE_SHARE_WRITE, sec, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0) If hCOM = -1 Then COMAvailable = False Else COMAvailable = True '// close the COM port ret = CloseHandle(hCOM) End If End Function

Inside the form where the Comm port selection menu is used a menu item event handler is used to support the user click of a particular port. This takes care of placing a check mark on the selected entry.
Code:
' ' routine that responds to a menu click of the Comm port ' selection menu. ' Private Sub mnuPort_Click(newIdx As Integer) Dim Port As Integer Dim M As Menu ' disable all current menu checks For Each M In mnuPort M.Checked = False Next RegisterPort (Val(mnuPort(newIdx).Tag)) End Sub

The above code calls another subroutine that takes care of making the program aware of which Comm port is in use. This example shows the actual check mark being set on the current menu entry, setting a global form variable to the current port number, showing the selected port number in a status bar box, and saving the setting into a program parameters INI file for later restore the next time the program is run.
Code:
' ' routine to register the entry port number into the program ' and check the menu list item if the port is a legitimate one ' in the menu. This will also display the port number on the ' status bar panel ' Private Sub RegisterPort(newPort As Integer) Dim newIndex As Integer newIndex = FindPortIndex(newPort) If newIndex >= 0 Then mnuPort(newIndex).Checked = True End If ' set the global port number variable PortNum = newPort If newPort > 0 Then StatusBar.Panels(3).Text = "485 - COM" & Format(newPort, "0") & ":" Else StatusBar.Panels(3).Text = "485 - <none>" End If 'put the new port number into the program parameter file Dim IniFileName As String IniFileName = Replace(App.Path & "\" & App.Title & ".ini", "\\", "\") Call PrivIniRegister("PROG OPTIONS", IniFileName) Call PrivPutInt("485_PORT", newPort) End Sub

One of the subroutines in the above code is worth noting here. (The others are application specific and will not be included here). This subroutine is one that uses the .Tag properties of the menu items to find which menu index corresponds to a particular comm port number. This would be called as shown above but would also be called by program initialization code that initially sets the check mark in the menu list when the INI file entries are parsed.
Code:
' ' routine to find the port list index for the desired comm port ' (Returns -1 if the item is not present) ' Private Function FindPortIndex(intPort As Integer) As Integer Dim strPort As String Dim M As Menu strPort = Format(intPort, "0") For Each M In mnuPort If M.Tag = strPort Then FindPortIndex = M.Index ' found so exit Exit Function End If Next FindPortIndex = -1 ' not found so exit with -1 value End Function
Attached Images
File Type: jpg CommMenu.JPG (9.5 KB, 8 views)
File Type: jpg MenuEdit.JPG (25.8 KB, 8 views)
Reply With Quote
  #20  
Old 07-01-2008, 09:55 PM
Dasco Dasco is offline
Newcomer
 
Join Date: Mar 2008
Posts: 18
Default

How can i force the routine ( data transfer) to repeat itself every "N" seconds?
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
reading serial port till it reachesa certain chr
reading serial port till it reachesa certain chr
reading serial port till it reachesa certain chr reading serial port till it reachesa certain chr
reading serial port till it reachesa certain chr
reading serial port till it reachesa certain chr
reading serial port till it reachesa certain chr reading serial port till it reachesa certain chr reading serial port till it reachesa certain chr reading serial port till it reachesa certain chr reading serial port till it reachesa certain chr reading serial port till it reachesa certain chr reading serial port till it reachesa certain chr
reading serial port till it reachesa certain chr
reading serial port till it reachesa certain chr
 
reading serial port till it reachesa certain chr
reading serial port till it reachesa certain chr
 
-->