Skip to main content

Past Blast

Featured Products

Windows Mobile Developer Controls
Windows Mobile Developer Controls
Stay in touch using the DEVBUSS RSS feeds.
 

News

Windows Mobile Developer Controls
Sapphire Soltuions

Microsoft eVB COMM control on your Pocket PC using eMbedded Visual Basic.

Written by David Knechtges  [author's bio]  [read 85714 times]
Edited by Derek

Page 1  Page 2 

3) Place two text boxes on the form.
4) Place a label above each text box.
5) Change one of the label's captions to Received Data and the other to Data To Transmit.
6) Rename the text box below the Received Data label to ReceivedDataTextBox.
7) Rename the text box below the Data To Transmit label to DataToTransmitTextBox.
8) Create a command button on the form and change its caption to Transmit.
9) Select the Comm control and place it on the form.
10) Set the Comm Port property to the port you are using for communications on the Pocket PC.
11) Set the settings property to 19200,n,8,1.
12) Set the Rthreshold property to 1. This will cause an OnComm event any time a character is received on the serial port.
13) Fill in the form's code as shown:

Option Explicit

Private Sub Comm1_OnComm()
  Select Case Comm1.CommEvent
  Case comEvReceive
    ReceivedDataTextBox.Text = Comm1.Input
  Case comEvSend
    ' do nothing here for now
  End Select
End Sub

Private Sub Command1_Click()
  Comm1.Output = DataToTransmitTextBox.Text
End Sub

Private Sub Form_Load()
  Comm1.PortOpen = True
End Sub

Private Sub Form_OKClick()
  App.End
End Sub

When all done, the Pocket PC project screen should look like this:

Now, run the PC program and the Pocket PC program. You will notice that data is being transferred successfully between the PC and the Pocket PC.

Try differing lengths of messages in the data to transmit box on both the PC and the Pocket PC sides and notice what happens. You will see that up to about 8 characters, the data is transmitted and received fine, but beyond that, it starts to clip off! This obviously is not the intended behavior. A little modification to the programs is necessary to prevent this behavior.

After looking at the Rthreshold property, you may be thinking that this is how to get the right lengths of data in. This would work for fixed-length messages. In other words, the program knows ahead of time how many characters it is going to receive in each message from the other device. Normally, however, this is not known and other methods must be employed. These can either be software or hardware based. Software based methods use the data that is being transferred to determine the start and end of a message. Hardware based methods can use either the clear to send/request to send lines (CTS/RTS) or the data terminal ready/data set ready lines (DTR/DSR) to indicate the start and end of messages. Normally, however, the CTS/RTS is used for a receiving device to "hold off" the transmitter while it is processing incoming data.

While working on this tutorial, I discovered that the ComEvDSR event within the Pocket PC does not work properly. Basically, I was taking the programs as shown above, and added a timer to the PC program that toggled the DTR line on the PC side every 500 ms. (The code was written as: MSComm1.DTREnable = Not MSComm1.DTREnable). When looking at the events on the PocketPC, the ComEvDSR event was not occurring, but the ComEvCD event was. This is the carrier detect event. If I did this exact thing in reverse, i.e. the Pocket PC side toggling DTR, and looking for ComEvDSR on the PC side, it worked properly. In other words, I am saying to use the DTR/DSR functionality at your own peril!

So, back to the original problem.. We can get the messages in properly using a form of CTS/RTS for our application. Let's first get the programs coded and running, then I will explain what these changes are doing.

For the PC side, add a timer to your form, set the Enabled property to False, and set the Interval property to 60. Select the MSComm control on the form and set its Sthreshold property to 1. This property will cause the comEvSend event to fire when the transmit buffer is empty. Now some new code will be added to the form. The code for the form should now look like this:

Dim InputData As String
Private Sub Command1_Click()
  MSComm1.Output = DataToTransmitTextBox.Text
End Sub

Private Sub Form_Load()
  InputData = ""
  MSComm1.PortOpen = True
End Sub

Private Sub MSComm1_OnComm()
  Select Case MSComm1.CommEvent
  Case comEvReceive
   InputData = InputData + MSComm1.Input
  Case comEvSend
    Timer1.Enabled = True
  Case comEvCTS
    ReceivedDataTextBox.Text = InputData
    InputData = ""
  End Select
End Sub

Private Sub Timer1_Timer()
  Timer1.Enabled = False
  ' all data sent, so toggle rts.
  MSComm1.RTSEnable = Not MSComm1.RTSEnable
End Sub

On the Pocket PC side, change the Sthreshold property in the Comm control to 1. Next, we will be changing the code. The code for the form on the Pocket PC side should now look like this:

Option Explicit
Dim InputData As String
Private Sub Comm1_OnComm()
  Select Case Comm1.CommEvent
  Case comEvReceive
    InputData = InputData + Comm1.Input
  Case comEvSend
    ' all data sent, so toggle RTS
    Comm1.RTSEnable = Not Comm1.RTSEnable
  Case comEvCTS
    ReceivedDataTextBox.Text = InputData
    InputData = ""
  End Select
End Sub

Private Sub Command1_Click()
  Comm1.Output = DataToTransmitTextBox.Text
End Sub

Private Sub Form_Load()
  InputData = ""
  Comm1.PortOpen = True
End Sub

Private Sub Form_OKClick()
  App.End
End Sub

Go ahead and run both programs. You should now see that anything you type on either side gets transferred properly to the other side.

Now for an explanation of what the code is doing... When a message has completed transmission, the side transmitting toggles the RTS line thereby causing a CTS event on the other side (remember that RTS and CTS are swapped in a null modem cable). This signal indicates that a message is complete, and allows the other side to begin processing it.A question you may be asking is why the code is different between the two sides to get this to work. Feel free to code them exactly the same on both sides (getting rid of the timer on the PC side) and see what the results are. Basically, what is happening is that the PC is waiting about 60 milliseconds after its transmit buffer is empty before asserting the RTS line. The Pocket PC is not doing that. If you do not wait the period of time on the PC side before asserting the RTS line, you will notice the Pocket PC side delaying by one transmit display of its data. For example, the first time on the PC you try to transmit ABC, the Pocket PC will be blank in its received data text box. The second time you try to transmit DEF, the Pocket PC will display ABC. I chose 60 milliseconds because the Windows event timer on the PC is a 55 millisecond timer. Feel free to decrease the timeout on the timer downward and see the results. It does get very interesting down around 15-25 milliseconds. I may be wrong, but I believe the reason this happens on the Pocket PC side is that it does not finish receiving its data before it gets the CTS event and then fires it anyway. The PC side, however, does not exhibit this same behavior. It finishes receiving its data and then fires the CTS event as you would expect.

If you wanted to, you could make the code the same on both sides, just use a timer on both sides, and things should work out just fine.

This basically concludes text-based communications. Now for binary communications...

Binary Communications

The Comm control on the Pocket PC supports binary communications. NOTE: The documentation provided with eVB is wrong! I ran into many problems getting this to work and decided to share how I solved this problem. Binary communications using the Comm control under eVB must be done using text-based communications and "faking out" the control, so to speak. I found a solution under MSDN on Visual Basic 4.0 for the PC. I decided to try it out on eVB, and lo and behold, it worked. Set up the Comm control as though you were using text-based communications, i.e. set the Comm control's InputMode property to comInputModeText. Set the Comm control's Rthreshold property to 1. Set the Comm control's InputLen property to 0.

The following code fragment describes how to transmit a byte:

Dim TransmitByte as Byte
MSComm1.Output = Chr(TransmitByte)

The following code fragment describes how to receive a byte stream of up to 100 bytes:

Dim TmpStr As String
Dim StrLen As Long, I As Long
Dim FileData(100) As Byte

While MSComm1.InBufferCount > 0
  TmpStr = MSComm1.Input
  StrLen = Len(TmpStr)
  For I = 1 To StrLen
    FileData(I) = CByte(Asc(Mid(TmpStr, I, 1)))
  Next I
Wend

A description of what is shown above is probably necessary now. On the transmission side, we are taking the byte to be transmitted, converting it into a character (through the Chr function), and writing it to the Output property of the Comm control. Easy enough. Just a simple conversion is all that is needed. The reception side is not as clean, though. First, the "text" data is read from the input property of the Comm control into the TmpStr string. Then, using a loop to walk through the entire string, each character is extracted from the string using the Mid function, converted to ASCII through the Asc function, and then converted to Byte through the Cbyte function. Then the Byte value is written to the FileData byte array. The while loop checking the InBufferCount property is necessary to get in any more bytes in the byte stream that may appear while we are walking through the previous set of data.

Take the code fragments above and experiment.. I used this binary based communications successfully on a project I am currently working on that takes the Pocket PC and allows it to communicate with a serial device for configuring and troubleshooting some of my company's products.

Hopefully you now have an idea of how the Comm control works using a real application and will be able to do some of your own communications!

Previous Page