Home
Archives
About us...
Advertising
Contacts
Site Map
 

ruby in steel

 

VISUAL BASIC COMMUNICATIONS #1

In the first of a regular Visual Basic column, we explain how to take control of the serial port with VB6
by Dermot Hogan

Requirements:
Visual Basic 6 (service pack 5)

 

Download The Source Code:
vb1src.zip

 

See also, Part Two and Part Three

Normally, 'digital' data input into a PC is just that – you use your digits; just two of them in my case, as I have never graduated beyond the two fingered school of typing. However, there are other ways to get data into and out of your PC – infra-red ports, network cards, the USB (Universal Serial Bus) and of course the good old-fashioned serial and parallel ports. The serial port and parallel port are typically used to connect either a modem or a printer to your PC. However, you can use them for other purposes. For example, you can use the parallel port to control other hardware – train sets, automated dog walkers and other such useful devices. You can also use the serial port to perform the same functions – and that is what I’ll be looking at this month.

Since the serial and parallel ports can perform the same types of functions in controlling external devices (other than printers and modems, of course), why use one rather than the other? Well, as with most things, it’s horses for courses. The parallel port is better at transferring lots of data – it has eight signal lines compared with a serial port’s one. The parallel port also produces data signals directly at the usual logic levels of 3V or 5V. With the serial port you have to decode the data stream into characters and it operates at a rather inconvenient 10V. You have to use a level converter to get down to logic chip voltages. On the other hand, the serial port can operate over much larger distances than a parallel port – and most importantly - it has fewer wires.

At first sight, the idea of fewer wires being better might seem crazy. But unless you like long sessions with a soldering iron, fewer is definitely better: it takes a lot, lot longer to debug wires than it does a program – believe me, cut-and-paste isn’t too good when you're working with solder-and-chips. If you’ve just spent a few days swearing at a particularly obscure software problem, then a few soldered connections might seem trivial by comparison. However, digital hardware has one characteristic that may not be apparent to programmers – it isn’t digital! Glitches, cross-talk, voltage spikes and things that go bump in the night are par for the hardware course. Not for nothing does the excellent book on ‘how to do it’ electronics, “The Art of Electronics” by Horowitz and Hill, contain the word ‘art’!

Null modem

Here are two computers connected in different ways. The first uses two modems and the public telephone system, while the second eliminates both the modems and the telephone network.


A) two computers connected via the public network


B) two computers connected via a null-modem cable

 

Comm with two m’s

There’s another good reason for using the serial port rather than the parallel port. First, the parallel port is often used for its original purpose – printing. And with Windows 98 and beyond, it can be quite difficult to persuade the operating system that you really don’t want to have a printer; with Windows XP, you need the device driver kit to communicate directly with a parallel port. But also, many PCs have two serial ports as well as a dedicated mouse port. This means that you can connect the two ports ‘back-to-back’ for testing. This is important – testing communications hardware can be tricky. Just making sure that your cable is wired up ok and that the PC end of things is working is a major step towards a successful project. Finally, Visual Basic comes with a ready made component for handling communication ports, the MsComm control.

MsComm is a simplification of the underlying API calls for controlling a communication port. And, while it does quite a bit of what I want it to do, it has some restrictions which mean I’ll have to move to using the full API calls later on. But for now, I’ll use MsComm to test out the serial ports and, just as importantly, the wire between them. To do this, I’ll set up one communication port, COM1 say, to write data to the other port, COM2.

The way to do this is to connect the two ports together using a ‘null-modem cable’. This rather odd term comes from the idea that two serial ports are normally connected together over the telephone network using a two modems, one at either end. If you want to connect two computers locally, then it’s expensive to use your telephone company to do the job; it’s cheaper and easier to use a simple cable. Actually, while the cable may be cheap, it’s not that simple. The intricacies of a null-modem cable are as good a place as any to sort out what all those pins do in a serial port. You have to understand these or the operation of the MsComm control (and its limitations) won’t make very much sense.


Here’s the basic communications program with communications events caused by RTS and DTR switching shown in the EventLog window.

Communicating - the basics

Serial communication is a heart quite a simple idea. There are three pins that are important. Data is transmitted over one pin (Transmit Data or TXD for short) and received over another pin (Receive Data or RXD). The data is sent sequentially as a series of on-off pulses down the wire, so a byte will take eight bits or pulses to transmit. In fact, there are one or two other bits needed as well for synchronisation and error checking, but that’s the basics. The third wire that’s needed is the Ground wire (GND) – these are electrical signals and so need a return path. While you can get away with just three wires, it’s often useful to have other control signals to make things easier for the software. There are six other signals: Ring Indicator (RI) is set by a modem when it detects an incoming call. Carrier Detect (CD) is again set by the modem when it detects another modem as the originator of the incoming call. For a null-modem, RI and CD can are ignored.

This leaves four other signals which come in pairs. Request To Send (RTS) and Clear To Send (CTS) are used by the PC to signal that it is ready to write or read data respectively. Data Terminal Ready (DTR) and Data Set Ready (DSR) do a similar sort of job (there are actually finer details of what these signals should be used for – but that needn’t bother us here). So for our null-modem purposes there are three pairs of wires – and these need to be ‘crossed over’ for the two ports to communicate. That is, the RCD pin of one port must be connected to the TXD pin of the second and so on. This means that when COM1 transmits data (on TXD) COM2 will receive data on RCD. The complete wiring between the two connectors looks like:

COM1
COM2
RCD
2
TXD
3
TXD
3
RCD
2
DTR
4
DSR
6
GND
5
GND
5
DSR
6
DTR
4
RTS
7
CTS
8
CTS
8
RTS
7

If you’re confident with a soldering iron you can get the parts separately and wire them up or if you’d rather leave it to an expert, get a ready made cable – though check out the type of ports of the back of your PC first. Older PCs tend to have one 25 pin port and one 9 pin port – all of the above wiring refers to the more modern 9-pin varieties.

OK, so assuming you’re equipped with a suitable null-modem cable and you’ve plugged it into the two ports what next? One way to check that everything is working OK is to use two HyperTerminal sessions, one connected to COM1 the other to COM2 with exactly the same speed settings. You should be able to type from one screen to the other with no trouble. Another way (more interesting, of course!) is to use a Visual Basic program.

I’ve written a simple program using mostly the default settings of the two communication ports to illustrate how events are communicated back to Visual Basic. In the program COMMS.VBP, there are two text boxes that display the input received on the respective port and two sets of buttons that toggle DTR and RTS. There’s also an Initialize button that opens the ports and sets off a polling loop. The code initially sets COM1 and COM2 up in a similar manner with both RTS and DTR off:

With MSComm1
.DTREnable = False
.RTSEnable = False
.CommPort = 1
.PortOpen = True
End With

Once set up the program just polls for input:

Do While MSComm1.PortOpen And MSComm2.PortOpen
s1 = MSComm1.Input
s2 = MSComm2.Input
If s1 <> "" Then
Port2.Text = Port2.Text & s1
ElseIf s2 <> "" Then
Port1.Text = Port1.Text & s2
Else
DoEvents
End If
Loop

There are two things to notice about this simple loop. First, the loop condition tests to see if the ports are still open. If you don’t do this, you will get an annoying error when you close the program. For some reason, Visual Basic seems to close the ports before unloading the form. Secondly, the DoEvents keyword ‘releases’ the program to look for other things – such as a button click or a communication event.

In the DTR (and RTS) toggle code, you’ll see this:

With MSComm1
.PortOpen = False
If .DTREnable = False Then
.DTREnable = True
Else
.DTREnable = False
End If
.PortOpen = True
End With

These communication events (DSR corresponding to DTR and CTS corresponding to RTS) events are detected in the OnComm event code:

Private Sub MSComm1_OnComm()
EventLog.Text = EventLog.Text & "Port1: " _ & CommEventText(MSComm1.CommEvent) & vbCrLf
End Sub

and just written to the EventLog window.

All this looks pretty neat and simple but there’s a ‘gotcha’: to set a control signal (say, RTS) you have to close the port, set RTS and then reopen it. This is disastrous if you are communicating with some hardware that isn’t really a modem – you can lose data in the small interval while the port is closed.

The problem is that the operating system uses these control wires to signal to the modem that your program is ready (that’s the main use of DTR) and it uses the RTS/CTS wires to implement hardware flow control. Normally, you’d be quite happy with this – but not if you want to control your patent dog-walker (or train set) directly. I’ll look at this next month.


Going Further...

Pins and Names

The diagram shows the pin connections (pinouts) of a 9-way serial port. Each pin has a two of three letter mnemonic as follows:

Pin #
Mnemonic
Full name
1
CD
Carrier Detect
2
RCD
Receive Data
3
TXD
Transmit Data
4
DTR
Data Terminal Ready
5
GND
Ground
6
DSR
Data Set Ready
7
RTS
Request To Send
8
CTS
Clear To Send
9
RI
Ring Indicator

 

Copyright © 2005 Dermot Hogan

June 2005

 


Home | Archives | Contacts

Copyright © 2006 Dark Neon Ltd. :: not to be reproduced without permission