You are on page 1of 7

Serial I/O (RS232)

All Intel PCs have one or two serial ports usually referred to as Com1 and Com2.
These comm ports provide voltages and pin outs consistent with RS-232C. Normally,
these ports are used for mice, modems, printers, and the like.

Under DOS, it was possible to directly access these ports. However, Windows 95 and
above forbid direct hardware access. Therefore, this page exists to help get around
windows.

Generic References | Visual Basic | MS Access | Delphi | C++ Builder | Windows API

Generic References

Most of this was gathered by searching Altavista for rs232 (notice that I used lower
case).

• I suggest starting with this good Tutorial.


• Here is the complete standard including the pin out, timing, and signal
descriptions.
• Voltage Specs
• Free Application Software
• Did you know that RS means Recommended Standard? This site also
compares Simplex/Duplex and DTE/DCE. Free software shows how to write
Windows 95 programs which access the serial port -
comm32.zip/comm32.cpp (4kb)
• The Visual Basic help file explains how to use Comm.drv to access serial
ports. (Search on serial.)
• ' Open the serial port
• MSComm1.CommPort = 2 ' Set the port number
• MSComm1.Settings = "56000,N,8,1" ' Set UART parameters
• MSComm1.PortOpen = True ' Required, might lock port
• MsComm1.Output = "Text string" ' Send data
• Buffer$ = Buffer$ & MSComm1.Input ' Read data

• Another tutorial and links to various rs232 related sites.


• Books and lots of very good links.
• While Windows does not normally allow you to directly access the hardware,
WIN95IO.dll privides a simple work around. Unfortunately, the distribution
package does not provide any examples, just 4 function prototypes. The
following 2 examples may help.

vbOut &H378, MyData%


temp% = vbInp &H378

See http://www.softcircuits.com/ and www.planet-source-code.com/vb for VB


tips.

• Many hints are available from comp.lang.basic.visual.misc.


• Hardware kits and book are available from Peter Anderson.
• The comp.arch.hobbyist FAQ contains many links on how to interface to the
Serial Port, Parallel Printer, and Joystick, as well as links to information on IR
Standards.
• Boondog Automation provides a number of related tutorials describing how to
build your own hardware interfaces and how to write interface software. They
also sell a parallel I/O, 8255-based ISA card - either as a kit or assembled.
• Information on various UARTs, includes links, pin-outs, and an overview.
• MarshallSoft provides a good FAQ explaining the UART with links to vendor
specs. They also provide shareware libraries for a number of programming
languages.
• This system.ini patch from Newsgroups:
microsoft.public.win95.msdosapps may help you run DOS applications
under Windows 95 et al.
• Portmon is a free GUI/device driver combination that monitors and displays
all serial and parallel port activity on a system.
• Reynolds Electronics appears to be a basic PC hobby store. It has all sorts of
Basic Stamp, PIC, and data aquisition info.
• B&B Electronics provides a variety of serial I/O devices (including a USB
Data Acquisition Module - 8s/4d 12-bit ADC, 4 10-bit DAC, 8 digital I/Os,
and software), books, and a pretty good free Technical Library.
• ePanorama.net provides a large number of links to all kinds of useful
information - serial, parallel, IR, usb, firewire, keyboard, mouse, joystick.
• Isolated Full Duplex RS232C Interface provides schematics and a PC board
for a self powered interface circuit the optically isolates the TxD and RxD
lines from the PC serial port.

Visual Basic 6.0

You will use Comm.drv, MSComm.ocx, or MSComm32.ocx, depending on which


compiler you are using. For example, in VisualBasic 6.0 Professional or Enterprise
editions, first add the MSComm32.ocx to the Toolbox (add the Microsoft Comm
Control 6.0 component), then add the control to your form and press F1 (Help).

Visual Basic Programmers Guide to Serial Communications by Richard Grier.


Richard's page provides free ActiveX serial components for those that don't have
MSComm32.ocx.

VB 6.0 provides VBTerm, a sample terminal emulation application under


..\samples\VB98\MSCOMM.

You can open a port as a file. This example, from comp.lang.basic.visual.misc, opens
the printer

Open "LPT1" For Output As #1


Print #1, "Text" & chr$(ascii char)
Close #1

MS Access 97 SR-2
I developed the following code to read barcodes from a reader connected to the serial
port. This first section is an attempt to open the port as a file (this works with most
languages - but not with MS Access); the second section is based on
MSCOMM32.ocx (which mostly works). This discussion is included here because
MS Access uses VBA - Visual Basic for Applictions.

MS Access 97 SR-2 - Fails

On my system, the following code causes Access to hang.

Private Sub ReadPort_UIButton_Click()


Dim temp As String
Open "com1:" For Input As #1 Len = 3
Input #1, temp ' This line hangs
Close #1
End Sub
I tested several variations with the same result

• Without Len = 3
• With temp as a variant
• Both "com1" and "com1:"
• Both Input and Binary

MS Access 97 SR-2 - Works

On the other hand, this works ... sort of.


Private Sub OpenPort_UIButton_Click()
ComPort_ActiveXCtl.CommPort = 1
' 9600 baud, no parity, 8 data, and 1 stop bit.
ComPort_ActiveXCtl.Settings = "9600,N,8,1"
ComPort_ActiveXCtl.InputLen = 0 ' Read entire buffer
ComPort_ActiveXCtl.PortOpen = True ' Opens the port
ComPort_ActiveXCtl.RThreshold = 12
End Sub

Private Sub Form_Unload(Cancel As Integer)


If ComPort_ActiveXCtl.PortOpen = True Then
ComPort_ActiveXCtl.PortOpen = False
End If
End Sub

Private Sub ComPort_ActiveXCtl_OnComm()


Select Case ComPort_ActiveXCtl.CommEvent

Case comEvReceive ' Received RThreshold # of chars.


Test_UIEdit = ComPort_ActiveXCtl.Input
End Select
End Sub
The trick is to know that ControlName_OnComm() is called when RThreshold is
not zero. Unfortunately, this doesn't work so well because barcodes came in various
length and RThreshold=12 only works with 12-character barcodes. With these
modification, any length barcode will work.
• Set the threshold to one (1)
• When the first character is read, set a timer and add the character to the
barcode
• As each additional character is read, re-start the timer
• When the timer expires, call the function of your choice and pass the
completed barcode. (The example below just writes it to a component.)
• Finally, stop the timer and clear the string Barcode

' Global Variables for the Barcode Scanner


Dim Global_Barcode As String
Dim Start_Time As Date

'********************************************

' Start of Barcode reader code

Private Sub Form_Load()


Start_Time = 0
Global_Barcode = ""
ComPort_ActiveXCtl.CommPort = 1
' 9600 baud, no parity, 8 data, and 1 stop bit.
ComPort_ActiveXCtl.Settings = "9600,N,8,1"
ComPort_ActiveXCtl.InputLen = 0 ' Read entire buffer
ComPort_ActiveXCtl.PortOpen = True ' Opens the port
ComPort_ActiveXCtl.RThreshold = 1 ' Call **_OnComm
' for each
character
End Sub

Private Sub ComPort_ActiveXCtl_OnComm()


Select Case ComPort_ActiveXCtl.CommEvent

Case comEvReceive ' Received RThreshold # of chars.


If Start_Time = 0 Then
Start_Time = Timer
Else
If Timer - Start_Time > 200 Then ' in case of failure
Form_Timer
Exit Sub
End If
End If
Global_Barcode = Global_Barcode &
ComPort_ActiveXCtl.Input
TimerInterval = 80 ' call Form_Timer 80 ms
' after last character
End Select
End Sub

Private Sub Form_Timer()


TimerInterval = 0 ' Disable the timer
Start_Time = 0
Barcode_UIEdit = Global_Barcode
Global_Barcode = ""

Barcode_UIEdit_Change
End Sub

Private Sub Form_Unload(Cancel As Integer)


If ComPort_ActiveXCtl.PortOpen = True Then
ComPort_ActiveXCtl.PortOpen = False
End If
End Sub

' End of Barcode reader code

'********************************************
Notes:

• In the help, the case statement has many options. To simplify this example, I
removed all but the one that reads the data.
• The only available timer is attached to the form. Therefore, it is hard to
encapsulate this in a library.
• MS Access 97 SR-2 will not display the MSComm help when you click on a
command and press F1 ... unless you FIRST locate and open
"C:\WIN98\HELP\COMCTL2.HLP". (Your path may be different.)
• This code requires that MSCOMM32.ocx is installed on every machine that
uses this feature. Simply copying the file is NOT sufficient. There are no
instructions on how to do it correctly. Copying it installs the TypeLib resistry
key, but not the several CLSID's or the License.
• I had everything working perfect. When I tried to demonstrate the code to my
boss, NONE of the case constants were defined ... Well they were 2 hours
before! (And they work fine now.)

Delphi

Due to their size, the Delphi notes are here.

C++ Builder

C++ Builder uses the same API calls as Delphi. In addition, the it uses the came
components.

_bios_serialcom

With Borland C, you can use _bios_serialcom() in bios.h to perform serial I/O.
#include <bios.h>
unsigned temp;
// Open serial port at 1200 baud, 8 data bits,
// No parity, 1 stop bit
temp = _bios_serialcom(_COM_INIT, 0,
_COM_CHR8 | _COM_NOPARITY | _COM_STOP1 |
_COM_1200);
temp = _bios_serialcom(_COM_RECEIVE, 0, 0); // Read a
character
temp = _bios_serialcom(_COM_SEND , 0, '*'); // Write a
character
It is unclear which compilers provide bios.h. On 9-24-01, I found references that both
Microsoft Visual C++ and Watcom C++ also claim to support _bios_serialcom().
However, a search of my Visual C++ 6 system found neither bios.h nor
_bios_serialcom(). Therefore, I assume that Microsoft has dropped the support.
At any rate, I will NOT provide copies of bios.h to anyone.

Virtual Integrated Design provides various RS-232 circuits and free software
examples.

Accessing the RS232 Port in DOS using BIOS.H functions provides a summary of the
allowed options/contants. There is also a program showing how to use bioscom to
access ports.

Microsoft provides a Simple Example Using _bios_serialcom(). The article states that
this interface tends to loose data. In order to improve the reliability, the comport needs
to call an interrupt routine which moves the data to a buffer. This was easy under
DOS, but generally not allowed under Windows.

Windows API

Search the SDK help for Communications (I used the SDK that came with Delphi 5).

Use CreateFile to open a handle to a communications resource, such as com1 or lpt1.

Test the returned handle to verify that the port is not locked by another process.

Use GetCommState to determine the current settings, SetCommState to change the


settings.

You can use BuildCommDCB to pass common parameters (baud, parity, etc.) to the
DCB as a string. But you'll still need SetCommState to actually change the settings.

See the DCB help for the supported constants.

Some additional commands - TransmitCommChar, PurgeComm,


FlushFileBuffers

Microsoft Platform SDK - Communication Overview, Communication Functions

The only property which is remembered between disconnects is the Baud Rate.
Parity, StopBits and the like are reset each time the connection is opened.
Unfortunately, both SetCommState and SetCommConfig are extremely slow. As a
result, it is not practical to disconnect the comport between uses.

Warning

Some versions of MSComm32.ocx leak memory.


Author: Robert Clemenzi - mailto:clemenzi@cpcug.org?subject=Languages -
SerialIO.htm

URL: http:// cpcug.org / user / clemenzi / technical / Languages / SerialIO.htm

You might also like