Chapter 2

SERIAL COMMUNICATIONS BASICS

INTRODUCTION

For some reason, the term “serial communications” always implies some kind of high-tech, complicated communications procedure. In fact, serial communications is simply the basis for common everyday communications. When you talk, you emit vocal sounds called phonemes, which another person receives and mentally assimilates into words. When you read this book, your eyes scan from left to right, gathering the letters delimited by spaces into words. Likewise, serial communications is the basis for communication among computers.

Human vocal communication is more complex than computer communication by an order of magnitude. Computers communicate with a fixed amount of bits, at a fixed rate, with a fixed framing structure. Human vocal communications, on the other hand, is extremely dynamic.

IBM-based personal computers are equipped with quite an assortment of serial ports. The keyboard port, PS2 mouse port, RS-232 serial port, parallel port, USB port, network port, video port, and modem port are all serial communication ports. This chapter focuses on the RS-232 standard of serial communication.

There are two basic forms of serial communications, synchronous and asynchronous. With synchronous communications, the data is transmitted in sync with a clock signal. Asynchronous communications eliminates the clock and adds extra bits to indicate the start and the end of the data. RS-232 ports provided with a computer support asynchronous serial communications.

The configuration of a serial character is sometimes referred to as a frame—an appropriate term, since all the character’s communication bits are contained in it. The bits contained within the character frame are Start bit, Data bits, Parity bit, and Stop bit.

Most computers utilize an integrated circuit called a UART to handle asynchronous serial communications. UART is an acronym meaning Universal Asynchronous Receiver Transmitter. This chip typically operates at five-volt logic levels and takes care of all of the serial-to-parallel and parallel-to-serial conversion for the CPU. Both the receiver input and transmitter output are routed to an RS-232 driver chip to interface with the outside world. If you look at the asynchronous line at the UART, the idle state sits at five-volts or at a logic one. When a character is transmitted, the line goes low for one bit constituting the Start bit. This falling edge transition alerts the receiver that a character is traveling down the line.

Once the Start bit is launched, the Data bytes follow. The number of bits that make up a character can be specified as 5, 6, 7, or 8. Most serial devices transmit data using either 7 or 8 data bits. Seven Data bits are all the bits required to transmit true ASCII characters. ASCII is a character set that contains alphanumeric, formatting, and control characters similar to the characters found on standard keyboard keys. ASCII consists of 2^7, or 128 different characters. An ASCII table is included in the appendix. Eight Data bits are required to transmit bytes of information or software code.

An optional bit called the Parity bit may be transmitted along with the data to provide a small amount of error detection. Valid parity values are Even, Mark, None, Odd, and Space. Mark Parity means that a logic one called a mark in telemetry circles is transmitted as the Parity bit. Likewise, Space Parity means that a logic zero called a space is transmitted as the Parity bit. None Parity indicates that no Parity bit of any sort is transmitted. With Even Parity, the number of ones in the data byte and the Parity bit is always an even number. For Odd Parity, the number of ones in the data byte and the Parity bit is always odd. In all cases, the Parity bit is set accordingly to ensure the specified parity. The best choice for the Parity bit is none. Mark and Space Parity choices are seldom used, since they just add time on to the transmission time of the character. Given the minimum error detection offered by Even Parity and Odd Parity, the decrease in transmission time gained by the elimination of the Parity bit is the better bargain. Parity check will detect a single bit error in a character, but if an even number of bits is in error, it will be undetected. More robust error detection schemes will be investigated in later chapters.

The Stop bit is a logic one or a mark that ends the character transmission. Stop bits can be specified to be 1, 1.5, or 2 bits in length.

The Baud rate determines the electrical period of time required for each transmitted bit. This unit of measurement is named after Jean-Maurice-Emile Baudot. Baudot originated the idea of a 5-bit data character, which surpassed Morse code as the most commonly used telegraphic alphabet in the early 1900s. Quite frequently, Baud rate is erroneously used to indicate bits per second (bps). In the case of a hard-wired serial port to serial port connection, the Baud rate is identical to the rate of transfer of information (bps). There is 1 bit of information per Baud. Modern day modems, on the other hand, use sophisticated modulation schemes and compression to substantially increase the rate of information transfer. Each Baud can carry several information bits. Despite the hardware limitations of a voice-grade telephone line to somewhere below 4000 Hertz, 56K bit per second modems are common. The standard Baud rates supported by Visual Basic are 110, 300, 600, 1200, 2400, 9600, 14400, 19200, and 28800.

Serial communication data format is frequently expressed as Baud rate, Parity, Data bits, and Stop bit parameters. For example, 9600, N, 8, 1 indicates a Baud rate of 9600, no Parity, 8 Data bits, and 1 Stop bit. The framing of this type of data byte is illustrated in Figure 2.01. The whole character requires 10 bits. Therefore, at a Baud rate of 9600 with this data structure, the character throughput is roughly 960 characters per second. Figure 2.01 shows the transmittal of a byte equal to 01 hexadecimal.

Figure 2.01

 

An Electrical Industries Association (EIA) driver conditions this bit stream before interfacing with real-world devices. This driver adheres to a standard as defined by the EIA. Some of the popular standards are RS-232, RS-422, and RS-485. All personal computers come equipped with RS-232C serial ports. RS-232C stands for Recommended Standard 232, and the suffix C indicates the latest revision. The formal EIA title for RS-232C is “Interface between Data Terminal Equipment and Data Communications Equipment Employing Serial Binary Data Interchange” and is dated August 1969. The RS-232 standard defines the mechanical connection characteristics, the functional description of each line, and the electrical signaling characteristic.

Serial Pin Out Description

The RS-232 standard specifies a 25-pin D-type connector, or DB-25 as the standard mechanical connector. Twenty-two of the 25 pins are defined. A male D-connector is specified to terminate on the computer equipment referenced as “DTE” by the standard. DTE means Data Terminal Equipment and always means the computer. As you would expect, the connecting equipment referred to as “DCE” by the standard terminates with a female D-type connector. Personal computer communications requirements reduce the 22 pins of the standard down to 10 pins. These pins and associated functions for a 25-pin D-type connector are illustrated below.

DTE(computer) 25-pin male                    

      1 Protective ground

      2 TD Transmit Data                     (output)

      3 RD Receive Data                      (input)

      4 RTS Request To Send              (output)

      5 CTS Clear To Send                   (input)

      6 DSR Data Set Ready                (input)

      7 Common                                 (power supply common)

      8 CD Carrier Detect                     (input)

      20 DTR Data Terminal Ready                                 (output)

      22 RI Ring Indicator                     (input)

 

Most personal computers today have deviated from the DB-25 mechanical standard of RS-232. In lieu of the DB-25 male, a DB-9 male is typically supplied. There was a time in the early days of the personal computer when the computer had both a standard DB-25 (typically used for an external modem connection) and a DB-9 (used to accommodate devices such as the mouse). The pins and associated functions for a 9-pin D-type connector are illustrated below.

DTE(computer) 9-pin male

      1 CD Carrier Detect                     (input)

      2 RD Receive Data                      (input)

      3 TD Transmit Data                     (output)

      4 DTR Data Terminal Ready         (output)

      5 Common                                 (power supply common)

      6 DSR Data Set Ready                (input)

      7 RTS Request To Send              (output)

      8 CTS Clear To Send                   (input)

      9 RI Ring Indicator                       (input)

 

The DTE functional description of these pins is as follows.

Carrier Detect (pin 1) A modem when a carrier frequency is detected sets an output. This input monitors the modem’s carrier detect output.

RD Received Data (pin 2) Data is received from the TD of a remote device through this line. When connected to a remote device, RD will sit in a mark state derived from the TD output of the connecting device while communications is idle.

TD Transmit Data (pin 3) The data is transmitted out of this pin into the receive pin of the connecting equipment. The TD line is in a mark condition while the communications is in an idle state.

DTR Data Terminal Ready (pin 4) DTR is an output that connects to the connecting device’s DSR input. The original intent of this complementary pair of data-control lines was some form of special hardware data-handshaking feature for data-flow control. Some devices use these data-control lines to indicate that a cable exists between the two devices.

Signal Common (pin 5) This line brings the interconnecting devices to the same point of reference for zero volts.

DSR Data Set Ready (pin 6) Data Set Ready is a data-control input that is connected to the DTR of the connected device. DSR is the companion control line to DTR.

RTS Request To Send (pin 7) Request to Send is a data-flow control output that connects to the connecting device’s Clear to Send (CTS) input. Typically, RTS and CTS are used to implement a hardware data-flow control. If used for flow control, the computer (DTE) places the RTS in the mark state, indicating to the remote device that it’s ready to receive data. If the receive buffer of the DTE should become full, a space is asserted on RTS instructing the interconnecting device to temporarily stop sending data.

CTS Clear To Send (pin 8) Clear to Send is a data-flow control input that is wired to the RTS of the interconnecting device. CTS is a data-flow control companion to RTS. If a mark is asserted on CTS, the DTE will continue to transmit data. Data transmission will be temporarily halted if a space is detected on CTS.

RI Ring Indicator (pin 9) The Ring Indicator is an input that monitors a ring-signal output from a modem. This output tracks with respect to the ring signal on the telephone line.

The term handshaking is used to indicate data-flow control. Data-flow control is critical for any slow responding data-transfer application. One example is a serial-based printer. Although printers do have data-collection buffers, the print job is frequently large enough that the print buffer is quickly filled. Data-flow control acts like a traffic cop, preventing the print buffer from overspilling and distorting the printout. The electrical characteristics of RS-232 specify a zero-crossing bipolar signal. A voltage of less than –3 volts represents a mark (logic 1) on a data line. A voltage of +3 volts or more indicates a space (logic 0) on a data line. A control line represents an off with a voltage less than –3 volts and an on with a voltage greater than + 3 volts. The maximum voltages are + 15 and –15, respectively.

A throwback to the old Teletype days, the negative voltage requirement of RS-232 does appear a bit odd today. Other newer standards such as RS-422 operate electrically from 0 volts to 5 volts with differential (complementary) outputs. Here, as one output is being driven high, the other output is being driven low. Although it takes two physical outputs and thus two wires for one data bit stream, these outputs are capable of achieving some very high Baud rates over some very long distances. At 9600 Baud distances, more than 10,000 feet are possible.

The RS-232C standard also imposes a limit on cable length to approximately 50 feet. For the most part, this limitation can be ignored if a high-quality shielded cable is used. Also, the RS-232 driver chips available today have excellent line-driving capabilities. It’s not unusual to communicate several hundred feet at 9600 Baud with a good-quality shielded cable. The maximum transmission length is a function of the operating Baud rate. A greater distance of communications can be achieved at 110 Baud, compared to the distance obtained with a Baud rate of 28800.

Historically, the biggest problem with RS-232C communication has been the interconnection between devices—due to the wide assortment of adapters (such as DB9 to DB25), gender changers, and cable configurations. When dealing with an unknown configuration, the best approach is to confirm with a digital multimeter the voltage levels on pins 2 and 3 with respect to the common. The common is pin 5 on the DB-9 connector and pin 7 on the DB-25 connector. The pin that swings to a negative voltage is definitely the Transmit Data output. A typical input, when looked at with a digital multimeter, will float somewhere around 0 volts.

Serial Interconnection

The simplest connection to a write-only device, such as an Alphanumeric Display, requires only two wires (as illustrated in Figure 2.02). You could also have a serial device measuring some physical parameters configured to output a serial update at a periodical rate. In this case, the computer becomes the receiver of the information, and again, only two wires are required for the connection.

Figure 2.02

 

The most common interconnection is the 3-wire, as illustrated in Figure 2.03. If handshaking is required today, it’s typically accomplished by software through XON/XOFF Data-Flow Control Protocol. With XON/XOFF protocol, the receiver sends an XOFF character instructing the transmitter to pause the transmission and an XON character signifying that the transmission is to resume. Typically, the XON character is ASCII DC1 or 11 Hex. The typical XOFF character is ASCII DC3 or 13 Hex. An ASCII table can be found in this book’s Appendix.

Figure 2.03

Figure 2.04 illustrates the typical interconnection to a serial device with hardware handshaking. Another popular 3-wire configuration is illustrated in Figure 2.05. With this configuration, the interfacing device unnecessarily requires hardware handshaking, and feeding back the control signal to itself satisfies this requirement.

Figure 2.04

Figure 2.05

 

First Visual Basic Serial Port Examination Program

Now you’ll use Visual Basic to verify and reinforce the information presented above. Your first Visual Basic program is going to introduce you to Microsoft’s MSComm component, a little animation programming, and to the electrical characteristic of one of your computer’s RS-232 serial ports. For this first program, you will need a 9-conductor cable with a DB-9 female connector at one end and a DB-9 male connector on the other end. A stand-alone DB-9 female connector that you can solder up with test wires is also required, as is a multimeter. An oscilloscope would be ideal. Oscilloscopes show voltage with respect to time, which is perfect for looking at the dynamics of data bit-streams. Figure 2.06 shows the required components and configuration. Any variation of this is acceptable, as long as you are able to access the pins of the DB-9 connector.

Figure 2.06

 

Figure 2.07 shows the pin out of a DB-9F connector, looking at the back (solder side). If you look very closely near each solder pin, the connector manufacturer will typically place the pin number.

Figure 2.07

 

 

First Program

The software objective of this program is:

1)   Mouse click on/off the control outputs DTR and RTS.

2)   Show the status of control inputs CD, DSR, CTS, and RI.

3)   Transmit a byte at a periodic rate.

Launch Visual Basic 6. Select new Standard Exe as the project type. Change the caption for Form1 to read “Serial 1.” The following code is designed for a DB-9 Connector. If the only available serial port on your computer is a DB-25, the following code will work; however, the pin numbers should be changed to reflect the pin-out of a DB-25 DTE connector. It should also be noted that the following project is available in completed form on the CD-ROM accompanying this book.

The basic controls are sufficient for this project—with one exception: a serial port must be accessed. Microsoft has an ActiveX control available called MSComm that can nicely handle this task. You can easily add this control to your Toolbar. Click “Project” on the Menu bar. Select “Components” from the pull-down menu. In the “Component Window,” use the vertical scroll bar to search the list box for “Microsoft Comm control 6.0.” The components are arranged alphabetically. Place a check on the checkbox for “Microsoft Comm control 6.0.” Another way to add a component is by right-clicking on the Toolbox in the pop-up dialogue box and then selecting “components.” Follow the same steps to remove an unwanted component by unchecking the associated checkbox.

Once you exit Components by clicking on the OK button, a new icon of a telephone sitting on top of a modem should appear in your control Toolbox. If you place your mouse cursor over it, “MSComm” should appear as ToolTipText. Press on the MSComm icon and add this control to the form by pressing down with the left mouse button. Then, with a diagonal sweeping motion, create a box. Once you release the left button, the MSComm icon will appear on the form. The default properties are acceptable for this project. You should take the time to examine the various properties of MSComm. Highlight the property by left-clicking on it and press function key F1 to retrieve Help information. The position of the MSComm control on the form is not critical, and it won’t be visible at run time.

Next, locate the Frame Control in the Toolbox and add a Frame Control to the form that is roughly 1 inch high by 3 inches long. Change the caption on Frame to read “Control Outputs.” The Frame Control is used in this application for grouping and identification. It’s not necessary to change any properties. The form should look like Figure 2.08.

Figure 2.08

Click on a Label control and place it on the left-hand side of Frame1. Change the (name) property to “lblDTR”. The lbl is following Microsoft’s recommended naming convention. Change “lblDTR” caption to “DTR DTE pin 4”. Change lblDTR AutoSize to true. Change lblDTR BorderStyle to “1 – Fixed Single”. Change the ToolTipText to Click on to toggle state.” Add another label to Frame1 directly to the right of lblDTR and change the (name) property to “lblRTS”.

The additional required property changes to lblRTS are as follows.

Caption= RTS DLE pin 7

AutoSize= true

BorderStyle= 1 – Fixed Single

ToolTipText= Click on to toggle state

 

These two labels complete the control output group. Click on the components and arrange them to provide symmetry in the Frame1 container. Adjust the size of Frame1 until everything looks good. Notice that these labels are now part of the Frame1 container. If you move Frame1, the labels move accordingly. Change the caption of frame 1 to read “Control Outputs.”

At this point, you still have the control inputs and the transmit-out character to implement, but you can do a little coding to check out what you’ve accomplished so far. Double-click on Form1 to activate the code window. Place the following code into the Form Load event.

Private Sub Form_Load()

 MSComm1.CommPort = 2 ‘ Place your comport here 1=com1; 2=com2

 ‘ 9600 baud, no parity, 8 data, and 1 stop bit.

 MSComm1.Settings = “9600,N,8,1”

 ‘ Tell the control to read entire buffer when Input

 ‘ is used.

 MSComm1.InputLen = 1

 ‘ Open the port.

 MSComm1.PortOpen = True

 ‘ Initialize DTR and RTS to OFF

 MSComm1.DTREnable = False

 MSComm1.RTSEnable = False

 ‘use QBColor to set label colors

 lblDTR.BackColor = QBColor(12) ’12=red 10=green

 lblRTS.BackColor = QBColor(12) ’12=red 10=green

End Sub

 

In order to ensure that the Com port is turned off when the program is finished, place the MSComm1.PortOpen = false statement in the Form_Unload event.

Private Sub Form_Unload(Cancel As Integer)

MSComm1.PortOpen = False

End Sub

Next, add the output mouse-click functions. Both outputs are controlled by software that simply changes the state for each output as the label control is clicked on. The following sub Procedures lblRTS_Click and lblDTR_Click located below contain the required software. The “True” command is analogous to “on.” According to the electrical characteristics, the control output should be a positive number greater than 3 volts DC when on and a negative number less than –3 volts DC when off. The label animation software will color the label red in the off state and green in the on state. The QBColor keyword is used for this task. You can change these colors to any combination you desire.

Private Sub lblRTS_Click()

 If MSComm1.RTSEnable = True Then

  MSComm1.RTSEnable = False: lblRTS.BackColor = QBColor(12) ‘color red

  Else: MSComm1.RTSEnable = True: lblRTS.BackColor = QBColor(10) ‘color green

 End If

End Sub

Private Sub lblDTR_Click()

 If MSComm1.DTREnable = True Then

  MSComm1.DTREnable = False: lblDTR.BackColor = QBColor(12) ‘color red

  Else: MSComm1.DTREnable = True: lblDTR.BackColor = QBColor(10) ‘color green

 End If

End Sub

Hook up your serial connector test jig and set up your digital multimeter or oscilloscope. Place the negative of your scope or meter on the common (pin 5) and run the program. Blow away the smoke and take a reading—just joking! As you click on each output label, you should see the label change color and the associated pin change state. If you don’t, then verify that you’re working with the correct Com port number and double-check your test setup for crossed wires, opened wires, bad solder connections, and so on. Well, that was easy—a few minutes of programming and you already have two programmable outputs to the outside world.

Now for the programming task required for the serial port inputs. As with the control outputs, use a Frame Control to hold the labels that you will be using to represent the status of the serial port control inputs: CD, DSR, CTS, and RI. Place the new Frame Control somewhere toward the bottom of the Form, size accordingly, and change the frame caption to read “Control Inputs.”

Add a label control to the left side of Frame2 and change the (name) property to “lblCD”. Additional required property changes to lblCD are as follows.

Caption= CD DTE pin 1

AutoSize= true

BorderStyle= 1 – Fixed Single

Add another label control to Frame2 to the right of lblCD and change the (name) property to “lblDSR”. Additional required property changes to lblDSR are as follows.

Caption= DSR DTE pin 6

AutoSize= true

BorderStyle= 1 – Fixed Single

Add another label control to Frame2 to the right of lblDSR and change the (name) property to “lblCTS”. Additional required property changes to lblCTS are as follows.

Caption= CTS DTE pin 8

AutoSize= true

BorderStyle= 1 – Fixed Single

Add the last label control to Frame2 to the right of lblCTS and change the (name) property to “lblRI”. Additional required property changes to lblRI are as follows.

Caption= RI DTE pin 9

AutoSize= true

BorderStyle= 1 – Fixed Single

Programming of the inputs requires the MSComm OnComm event. On the code section of the form, open up the control list box and scroll down to MSComm. The Private Sub MSComm1_OnComm() should now be added to your code. Highlight the term OnComm with the mouse and press function key F1 to activate Help. The OnComm event is triggered whenever a communication event or an error occurs. Click on the example link in the Help window. A properly structured Select Case is there for the taking. Copy the Select Case code and paste it into the program code for MSComm_OnComm. Modify this code as illustrated in bold below with the input-control animation.

 Select Case MSComm1.CommEvent

  ‘ Handle each event or error by placing code below each case statement

 ‘ Errors

  Case comEventBreak ‘ A Break was received

  Case comEventFrame ‘ Framing Error

  Case comEventOverrun ‘ Data Lost

  Case comEventRxOver ‘ Receive buffer overflow

  Case comEventRxParity ‘ Parity Error

  Case comEventTxFull ‘ Transmit buffer full

  Case comEventDCB ‘ Unexpected error retrieving DCB]

 ‘ Events

  Case comEvCD ‘ Change in the CD line.

     If MSComm1.CDHolding = False Then

     lblCD.BackColor = QBColor(12) ‘red

    Else: lblCD.BackColor = QBColor(10) ‘green

    End If

   Case comEvCTS ‘ Change in the CTS line.

        If MSComm1.CTSHolding = False Then

       lblCTS.BackColor = QBColor(12) ‘red

      Else: lblCTS.BackColor = QBColor(10) ‘green

     End If

   Case comEvDSR ‘ Change in the DSR line.

      If MSComm1.DSRHolding = False Then

        lblDSR.BackColor = QBColor(12) ‘red

      Else: lblDSR.BackColor = QBColor(10) ‘green

     End If

  Case comEvRing ‘ Change in the Ring Indicator.

      If lblRI.BackColor = QBColor(10) Then

     lblRI.BackColor = QBColor(12)  ‘red

    Else: lblRI.BackColor = QBColor(10) ‘green

    End If

  Case comEvReceive ‘ Received Rthreshold # chars.

  Case comEvSend ‘ There are SThreshold number of characters in the                                                 ‘ transmit buffer

  Case comEvEOF ‘ An EOF character was found in the input stream

 End Select 

Before you run this code, the control inputs need to be initially colorized, so add the following code to the bottom of the Form_Load event.

 ‘ control input initialization

 lblCD.BackColor = QBColor(12) ‘red

 lblCTS.BackColor = QBColor(12) ‘red

 lblDSR.BackColor = QBColor(12) ‘red

 lblRI.BackColor = QBColor(12) ‘red

When you run the program, all the status lights for the control signals are colored red. The initialization code found in the Form_Load event accomplishes this task. At this point, all of the control inputs are floating, since they are not connected to an output. The interface integrated circuit that performs the RS-232 voltage translation for the computer contains roughly a 5000-ohm resistor on each input tied to common. This pull-down resistor ensures that the control inputs—and the Receive Data input, for that matter—are not arbitrarily bouncing around or floating when nothing is connected. In order for a control input to be considered on, the input must exceed +3 volts. If you turn on either DTR or RTS, a positive voltage is now available on that pin. Use a jumper to route this positive voltage to each control input. Each status indicator should change from red to green to red as you go from input to input.

The final task for this project is to create a periodic asynchronous byte output on the TD line. This periodic output will make it easy for an oscilloscope to sync up for a visual inspection of the RS-232 byte transmission. If you do not have a scope, you will see a change in potential with your multimeter when the byte is being transmitted. A checkbox control will be used to enable/disable this function.

Add a timer control to the form. Set the timer-interval property to 10. This will cause the timer-event property to be executed approximately every 10 milliseconds. At 9600 Baud, the width of each bit is equal to 104.16 microseconds (1/9600). The MSComm setting property for this project is 9600,N,8,1. Therefore, the transmission time for a byte is 1.0416 milliseconds (10 * 1/9600). This timing is well within the 10-millisecond interval specified for the timer.

Add a checkbox control to the form and position it to your liking. Change the caption property for Check1 to “Periodic Transmission”. Adjust the sizing of the Check1 checkbox control with your mouse so that the caption is arranged on one line. Now add the following code to the Timer1_Timer event.

Private Sub Timer1_Timer()

 ‘An inspection of Check1 property value specifies that

 ‘0= unchecked and 1 = check

    ‘if Check1 value is equal to 1 indicating that the box is checked then transmit

   ‘otherwise do nothing

 If Check1.Value = 1 Then Let MSComm1.Output = Chr(1)

 End Sub

The Chr keyword returns a string containing the character associated with the specified ASCII character code. This keyword instructs MSComm1 to transmit a byte containing 01 hex and not the ASCII character 1, which is equivalent to 31 hex.

Run the program, and with the mouse place a check on the Check1 checkbox. If you have an oscilloscope, then adjust the time base to 100 microseconds per grid division. Since oscilloscopes are configured with 10 horizontal grids, you can almost see all 10 bits of the transmitted data byte on the oscilloscope’s screen. Approximately 40 microseconds are spilled off the end of the scope’s display, because each bit time is 104.16 microseconds.

Figure 2.09 illustrates an oscilloscope view of the RS-232 voltage-translated transmitted data byte. A voltage of less than –3 volts represents a mark (logic 1) on the data line. A voltage of +3 volts or more indicates a space (logic 0) on a data line. The logic level for each bit is included in the illustration.

Figure 2.09

If you are using an oscilloscope, you should experiment by outputting different characters, Bauds, parities, and Stop bits. If you drop down into the slower Baud rates, make sure that you adjust the timer-interval rate to an appropriate value. At 110 Baud, the data character requires a transmission time of 90.9 milliseconds. If the timer rate were to remain at the 10 milliseconds interval value, the transmitted bytes begin running together and make it difficult for the oscilloscope to sync up. As an exercise, you may want to add a receive section to this program. The transmitted data can be looped back into the receive input, RD. Use a Textbox control to display the received data as an ASCII character, a decimal value, or a hexadecimal value. The MSComm input property is used to pull characters from the receive buffer.

No doubt you will agree that this first programming task was accomplished with ease. After working with the signals available on the RS-232 connector, the functions and characteristics of these signals should be clearer. The data-flow control signals are really only necessary when dealing with the transfer of large blocks of data. Actually, software data-flow control could also be used, thereby eliminating the need for hard-wired data-flow control. The serial port’s control inputs and control outputs with proper electrical conditioning could be used to interface with external devices such as switches and relays. Each serial port has two outputs and four inputs that could be used to interface with external devices.

The MSComm control is a very powerful tool to have in the Toolbox. MSComm’s event-driven communications is a very efficient technique for handling serial port interactions. Although you now have explored the primary properties of the MSComm control, you should also be aware of other properties that are available. You should step through each property of MSComm. Use the F1 function key to retrieve additional information on each property. The transmit buffer (OutBufferSize) and receive buffer (InBufferSize) can be adjusted. Four modes of handshaking can be specified. The ability to discard null characters is possible. The MSComm control certainly does make serial programming easy.

Second Serial Communication Program

Before moving on to the world of Programmable Logic Controllers, you should construct a Visual Basic program to talk to an ASCII-based acquisition board. A number of these boards are available in the market place, or you can use one of your own homegrown designs. Typically, acquisition boards are microcontroller-based circuit boards. The microcontroller uses an Intel 80C32, Motorola, Microchip, or some other Integrated circuit manufacturer’s CPU core. Acquisitions boards are used to read temperature, pressure, and other real-world sensors. A host computer polls a request, and the acquisition board sends a serial ASCII string with the information. The serial link is usually RS-232.

General Purpose Serial Link

The software objective of this program is:

1)   Provide a user interface where communication parameters are selectable and save these parameters to a configuration file.

2)   Provide a user interface where data-acquisition parameters are selectable and save these parameters to a configuration file.

3)   Data log to file.

KT32 is the data-acquisition circuit board being used as an example in this project. This board, among other functions, provides temperature information in degrees Fahrenheit. The interface is RS-232, with a data-byte structure of 9600N81.

KT32 Read Temperature Command

$T<carriage return>

RESPONSE: @+0074.63< carriage return >

NOTE: + IS SIGN OF TEMPERATURE IN DEGREES F

@-0159.69< carriage return > INDICATES AN OPEN PROBE

@+0140.18< carriage return > INDICATES A SHORTED PROBE

This software will be developed to be universal, as far as interfacing to serial devices of this type where the protocol requires a simple request/response format without error checking. The command field will be user programmable, with the command stored in a configuration file. Therefore, upon activation of the program, the previously set parameters will be loaded. In addition, a response field will be included and programmable to ensure that the received data fits the profile of the device.

Now, start a new project and call it “GPSL,” which in this case stands for “General Purpose Serial Link.” Launch Visual Basic and select Standard EXE. Save the project as “GPSL.” Make sure that you select the appropriate folder for your project.

The first task is to set up a user interface for configuring the desired communication parameters. Since this task is secondary to the data-acquisition part of the project, another form will be added to the project. By selecting “Add Form” in the Project menu, and then selecting “Form” in the subsequent dialogue box, you create the additional Form. You should see a second form in your project browser called “Form2(form2.frm)”. Change the name of the form to “Comparams”. Place “Communication Parameters” into the forms-caption property.

The communication parameters are all standards and predefined. The communication ports are 1 and 2. The Baud rates are standard rates. The number of Stop bits, Parity, and the number of Data bits are all predefined. The best tool for this task is the Option button. Option buttons are automatically linked to each other within a container so that when one is selected, all the other Option buttons within the container are deselected. This feature minimizes the required software for this configuration task.

There are five groups of parameters that need to be configured: com port, Baud rate, parity type, the number of Data bits, and the number of Stop bits.

Since the Option buttons are container interrelated, additional containers are required to provide isolation for the selection task. Otherwise, if you placed all of the required Option buttons on just the form container, only one Option button could be selected. The Frame Control is ideal for the isolation task. In addition, when the frame is moved, the associated Option buttons follow suit.

Place a Frame Control on the “Comparams” form. Visual Basic will automatically set the name of the frame to Frame1. Since the frame task is simply a container, this name won’t be altered. Change the Frame1 caption to read “Communication Port”. Place an Option button into Frame1 and name it “optCOM1”. Add three more Option buttons into Frame1 and name them “optCOM2”, “optCOM3”, and “optCOM4”. Change the caption for each of these Option buttons accordingly. The CommPort Property can be any number from 1 to 16.

 Add another Frame Control (“Frame2”) to the “Comparams” form and change the caption to “Baud Rate”. Place four Option buttons into Frame2 and name them “optBR288K”, “optBR192K”, “optBR96K”, and “optBR48K”. Change the respective captions to 28800, 19200, 9600, and 4800.

Add a third Frame Control (“Frame3”) to the “Comparams” form and change the caption to “Parity”. Place five Option buttons into Frame3 and name them “optPNONE”, “opt optPODD”, “optPEVEN”, “optPMARK”, and “optPSPACE”. Change the respective captions to None, Odd, Even, Mark, and Space.

Add yet another Frame Control (“Frame4”) to the “Comparams” form and change the caption to “Number of Data Bits”. Place two Option buttons into Frame4 and name them “optDATA8” and “optDATA7”. Change the respective captions to 8 bits and 7 bits. MSComm support bit sizes of 5, 6, 7, and 8. Seven-bit and 8-bit data sizes are the most common.

Add one more Frame Control (“Frame5”) to the “Comparams” form and change the caption to “Stop Bits”. Place three Option buttons into Frame5 and name them “optBIT1”, “optBIT15”, and “optBIT2”. Change the respective captions to 1 Bit, 1.5 Bit, and 2 Bit.

Finally, add a Command button named “cmdDONEexit” with a caption of “Done/Exit”. You can arrange these various groups of Option buttons to your liking. The book arrangement is depicted in Figure 2.10.

Figure 2.10

Temporarily add the following code shown in bold to the Form load procedure of Form1. The two statements will immediately launch Form2 when the project is started. Start the project, click the various Option buttons from group to group, and verify that only one Option button is active per group. An active Option button’s value property is True. The value property of all the inactive Option buttons for each group is false. During run time, the value property for each Option control can be either interpreted or set. Remove the temporary code when you are finished.

Private Sub Form_Load()

Comparams.Enabled = True

Comparams.Visible = True

End Sub

As you can see from the previous exercise, the Option-button control makes the programming task of setting the communication parameters very easy. Once these parameters are set and the communication link is successful, there is no reason for this form to be displayed. The parameters will be saved to a configuration file, which will automatically get loaded on program start-up. A control will be placed on Form1 to activate Form2, in order to facilitate the changing of the communication parameters. When the form is closed, the MSComm1 communication parameters and the configuration file will be updated.

Since the communication variables need to be available for both forms, a module should be added to the project. On the Menu bar, select Project/Add Module/New/Open. Notice that the new module is added to the Project window. Leave the module name as “Module1”. Within this module, the communication variables can be declared as Public and bridge the gap between forms. In addition, modules are good places to store code procedures that may be utilized in other projects.

In the general-declaration section of the recently added module, place the following statements.

Option Explicit

‘This variable sets the Communication port

Public sComPort As String

‘This variable sets the Baud rate.

Public sBaudRate As String

‘This variable sets the parity type.

Public sParity As String

‘This variable sets the number of data bits.

Public sDataBits As String

‘This variable sets the number of stop bits.

Public sStopBits As String

In the Module1, add Sub procedures ReadComParamFile and WriteComParamFile. ReadComParamFile opens a file named “ComPar.txt” and retrieves the communications parameters into Visual Basic variables for insertion into MSComm. An error handling routine is provided for a “File Not Found” error in order to load default communications parameters and create the “ComPar.txt” file. The “txt” extension makes the file readily accessible for inspection with Microsoft’s Notepad text editor. If any other error is encountered during the file read, a message box with the error type is launched and the program is subsequently ended. WriteComParamFile writes the communication parameters to a file called “ComPar.txt”.

The program flow of these procedures can be observed by placing the ReadComParamFile statement in the Form_Load procedure of Form1. Place a Breakpoint on this statement. Run the program. The Breakpoint will immediately stop execution of the program. Now you should single step through the code using the F8 function key. Place the mouse pointer over the variables to examine the content.

Public Sub ReadComParamFile()

Dim FILENUM As Byte ‘temporary scratch pad variable

Dim A As String ‘temporary scratch pad variable

FILENUM = FreeFile

‘Look for a file called “ComPar.txt”

On Error GoTo HandleError

Open “ComPar.txt” For Input As #FILENUM

Input #FILENUM, A

‘use Trim command to trim out leading and trailing spaces.

sComPort = Trim(A) ‘TRIM OUT ANY SPACES

 Input #FILENUM, A

 sBaudRate = Trim(A) ‘TRIM OUT ANY SPACES

 Input #FILENUM, A

 sParity = Trim(A) ‘TRIM OUT ANY SPACES

  Input #FILENUM, A

  sDataBits = Trim(A) ‘TRIM OUT ANY SPACES

  Input #FILENUM, A

  sStopBits = Trim(A) ‘TRIM OUT ANY SPACES

 Close FILENUM

 Exit Sub ‘Exit procedure; task complete

HandleError: ‘error handler

 Select Case Err.Number ‘ Evaluate error number error object

  Case 53 ‘ “File Not Found”

   Close #FILENUM ‘ Close open file

   ‘Load default communication parameters

   sComPort = “1”

   sBaudRate = “9600”

   sParity = “N”

   sDataBits = “8”

   sStopBits = “1”

   WriteComParamFile ‘write parameters to file

  Case Else

   ‘this path for all errors other than File not Found

   ‘Display the type of error and end program!!!

   Close #FILENUM

   MsgBox Err.Description ‘provides a description

   End ‘End program

   End Select

 End Sub

Public Sub WriteComParamFile()

Dim FILENUM As Byte

Dim A As String

 FILENUM = FreeFile

 A = sComPort + “,” + sBaudRate + “,” + sParity + “,”

 A = A + sDataBits + “,” + sStopBits

 Open “ComPar.txt” For Output As #FILENUM

 Print #FILENUM, A

 Close #FILENUM

End Sub

Run Microsoft’s Notepad to view the contents of the file. Figure 2.11 shows the contents of ComPar.txt when viewed with Notepad. Now write the code for Form2. This form makes the communication parameters user-selectable. Place the following statements in the Form_Load procedure of Form2. In the form-load event, the value for each option-button group is set according to the communication parameters. The communication parameters were previously extracted from the “ComPar.txt” file.

Figure 2.11

Private Sub Form_Load()

If sComPort = “1” Then optCom1.Value = True

If sComPort = “2” Then optCom2.Value = True

If sComPort = “3” Then optCom3.Value = True

If sComPort = “4” Then optCom4.Value = True

 If sBaudRate = “28800” Then optBR288K.Value = True

 If sBaudRate = “19200” Then optBR192K.Value = True

 If sBaudRate = “9600” Then optBR96K.Value = True

 If sBaudRate = “4800” Then optBR48K.Value = True

 If sParity = “N” Then optPNONE.Value = True

 If sParity = “O” Then optPODD.Value = True

 If sParity = “E” Then optPEVEN.Value = True

 If sParity = “M” Then optPMARK.Value = True

 If sParity = “S” Then optPSPACE.Value = True

 If sDataBits = “8” Then optDATA8.Value = True

 If sDataBits = “7” Then optDATA7.Value = True

If sStopBits = “1” Then optBIT1.Value = True

If sStopBits = “1.5” Then optBIT15.Value = True

If sStopBits = “2” Then optBIT2.Value = True

End Sub

The Form_Unload event of Form2 sets the communication parameters according to the Option buttons selected for each communications group. These values are also saved to the “ComPar.txt” file. Place the following code in Form2’s Form_Unload event.

Private Sub Form_Unload(Cancel As Integer)

If optCom1.Value = True Then sComPort = “1”

If optCom2.Value = True Then sComPort = “2”

If optCom3.Value = True Then sComPort = “3”

If optCom4.Value = True Then sComPort = “4”

 If optBR288K.Value = True Then sBaudRate = “28800”

 If optBR192K.Value = True Then sBaudRate = “19200”

 If optBR96K.Value = True Then sBaudRate = “9600”

 If optBR48K.Value = True Then sBaudRate = “4800”

 If optPNONE.Value = True Then sParity = “N”

 If optPODD.Value = True Then sParity = “O”

 If optPEVEN.Value = True Then sParity = “E”

 If optPMARK.Value = True Then sParity = “M”

 If optPSPACE.Value = True Then sParity = “S”

 If optDATA8.Value = True Then sDataBits = “8”

 If optDATA7.Value = True Then sDataBits = “7”

If optBIT1.Value = True Then sStopBits = “1”

If optBIT15.Value = True Then sStopBits = “1.5”

If optBIT2.Value = True Then sStopBits = “2”

‘save new parameters to the communication configuration file

WriteComParamFile

End Sub

On Form1, add an MSComm control. The MSComm is not in the standard toolbox. Right-click on the toolbox and select components. Look for Microsoft Comm Control 6.0 and then click on the associated checkbox. MSComm is now located in the Toolbox. Place MSComm on the form. MSComm is not visible at run time, so form placement is not critical.

Add a Command button to Form1 named “cmdChangeComParam”. Change the caption property of the command button to read, “Press to Change Communication Parameters.” Place the command button at the bottom of Form1 and change the size of the button so the entire caption field is visible. Change the caption of Form1 to read, “General Purpose Serial Link”. The form should look like Figure 2.12.

Figure 2.12

Add the following code to the cmdChangeComParam_Click() event.

Private Sub cmdChangeComParam_Click()

Form1.Visible = False

Comparams.Visible = True

Comparams.SetFocus

End Sub

This code makes Form1 not visible and changes the visibility and focus of the Comparams Form. Make sure that you add the statement Form1.Visible =True to the Comparams Form_Unload event. Otherwise, when you close out the communication parameters window or Form2, none of the project windows will be visible. You’ll be looking at the desktop. Run the program and navigate from one window to the next. Change the options as you go and verify that the options are maintained.

The next task requires data collection and storage. Since this program is targeted to be of a general-purpose nature, the ability to enter the required command must be provided. Additionally, a data-configuration file is required to store this command so it won’t be necessary to reenter the command the next time the program is run.

Data-log capability is also required where, at a specified time interval, the command is automatically issued. The response from the connected serial device is collected and stored away to a file along with a time stamp and a data stamp. Commas will be used to delimit the data and time/date information. The data-log file name will be “Data[mmm][yyyy].csv”. The bracket [mmm] indicates the first three alpha-characters of the current month. The bracket [yyyy] represents a numerical description of the current year. CSV represents a standard file extension designation, indicating that the file consists of comma-separated variables. All user-specified data-log parameters will be stored to the data-configuration file.

Add a Command button to Form1 and change the name to cmdSend. The caption for cmdSend is “Send Command”.

Add a label called “lblCommand” to Form1 next to the “Send Command” command button. Set the AutoSize property to True and the BorderStyle to “1- Fixed Single”. In the ToolTipText property, add the following text: “Double Click to enter a new Command”.

Directly below the “lblCommand” label, place a Textbox control. The Textbox should be named “tbCommand”.

Place another label control below the textbox. The name of this label is “lblReceivedData”. Set the AutoSize property to True and the BorderStyle to “1- Fixed Single”. Place a Checkbox on Form1 and name it “cbDataLog”. Change the caption to read “Auto DataLog”.

Now you need to add several Option buttons to select the data-log time interval. First, you will need to add a frame to act as a container for the Options buttons. This frame simply serves as a container, so you can stay with the default name. Set the caption property of Frame1 to “Data Log Time Interval”. Now add four Option buttons to Frame1. The names of these Option buttons are opt5Min, opt10Min, opt15Min, and opt30Min. Adjust the caption for each of these Option buttons accordingly. A layout of Form1 is illustrated in Figure 2.13.

Figure 2.13

Three setting are required to be stored in the data-configuration file. They are the command, the status of Auto Data-log, and the data-log time interval. The name of the configuration file is “DataPar.txt”. Actually, the code is almost identical to the code written to set/retrieve the communication parameter. The exceptions are the name of the file, the variable names, and the number of variables. If you were keying in this code, the best method would be to copy, paste, and modify both ReadComParamFile and WriteComParamFile.

Place the following variable declaration to the general-declaration procedure of Module1.

‘Variable for Data Log Settings

‘This variable stores the command

Public sCommand As String

‘This variable stores the whether data log is enabled

Public sDataLogStatus As String

‘This variable store the Data Log time interval

Public sDataLogTime As String

Add the following code to Module1.

Public Sub ReadDataParamFile()

Dim FILENUM As Byte ‘temporary scratch pad variable

Dim A As String ‘temporary scratch pad variable

FILENUM = FreeFile

‘Look for a file called “DataPar.txt”

On Error GoTo HandleError

Open “DataPar.txt” For Input As #FILENUM

Input #FILENUM, A

‘use Trim command to trim out leading and trailing spaces.

sCommand = Trim(A) ‘TRIM OUT ANY SPACES

 Input #FILENUM, A

 sDataLogStatus = Trim(A) ‘TRIM OUT ANY SPACES

 Input #FILENUM, A

 sDataLogTime = Trim(A) ‘TRIM OUT ANY SPACES

Close FILENUM

Exit Sub

HandleError: ‘error handler

 Select Case Err.Number ‘ Evaluate error number using error object

  Case 53 ‘ “File Not Found”

   Close #FILENUM ‘ Close open file.

   ‘Load default Data Log parameters

   sCommand = “$T”

   sDataLogStatus = “True”

   sDataLogTime = “5”

   WriteDataParamFile ‘write parameters to file

  Case Else

   ‘this path for all errors other than File not Found

   ‘Display the type of error and end program!!!

   Close #FILENUM

   MsgBox Err.Description ‘provides a description

   End ‘End program

 End Select

End Sub

Add another procedure to Module1 called “WriteDataParamFile”.

Public Sub WriteDataParamFile()

Dim FILENUM As Byte

Dim A As String

 FILENUM = FreeFile

 A = sCommand + “,” + sDataLogStatus + “,” + sDataLogTime

 Open “DataPar.txt” For Output As #FILENUM

 Print #FILENUM, A

 Close #FILENUM

End Sub

Add the following code to the Form1 Form_Load procedure after the ReadComParamFile statement.

‘Get Data Log Parameters

ReadDataParamFile

‘Initialize Project check box and option buttons

 If sDataLogStatus = “True” Then cbDataLog.Value = 1 ‘place check if true

 If sDataLogTime = “5” Then opt5Min = True

  If sDataLogTime = “10” Then opt10Min = True

  If sDataLogTime = “15” Then opt15Min = True

   If sDataLogTime = “30” Then opt30Min = True

 ‘ Show the command value

 lblCommand.Caption = “Command => “ & sCommand

 ‘hide text box

 tbCommand.Visible = False

 ‘null receive label

 lblReceivedData.Caption = “Received Data =>”

Once the following procedures are added to the Form1 code, the user interface is complete. You can run the project and change any parameter—whether it is communications options or data-log options, the selection is saved to the respective files.

Private Sub cbDataLog_Click() ‘CheckBox

If cbDataLog.Value = 0 Then

 sDataLogStatus = “False”

Else: sDataLogStatus = “True”

End If

 WriteDataParamFile

End Sub

Private Sub opt5Min_Click() ‘5Min Option button

sDataLogTime = “5”

 WriteDataParamFile

End Sub

Private Sub opt10Min_Click() ’10Min Option button

sDataLogTime = “10”

 WriteDataParamFile

End Sub

Private Sub opt15Min_Click() ’15Min Option button

sDataLogTime = “15”

 WriteDataParamFile

End Sub

Private Sub opt30Min_Click() ’30Min Option button

sDataLogTime = “30”

 WriteDataParamFile

End Sub

Private Sub lblCommand_DblClick() ‘Command label

 tbCommand.Visible = True

 tbCommand.SetFocus

  tbCommand.Text = “”

End Sub

 ‘TextBox key Press look for a carriage return

Private Sub tbCommand_KeyPress(KeyAscii As Integer)

‘Command entry completion is a carriage return character

 If KeyAscii = Asc(vbCr) Then

 ‘if only a carriage return was keyed into the textbox then close out

 ‘and leave the existing command intact

 If tbCommand.Text <> “” Then sCommand = tbCommand.Text

  WriteDataParamFile ‘save to file

  tbCommand.Visible = False ‘hide textbox

   ‘display new command

   lblCommand.Caption = “Command => “ & sCommand

 End If

End Sub

The following code sets up the communications and the data-logging aspects of the project. Essentially, there are two elements issuing information requests to the serial device: the manual command button, and the data logger. Add the following to the general declaration procedure in Module1.

‘Variable for Data Log Settings

‘This variable stores the command

Public sCommand As String

‘This variable stores the data log status (enabled/disabled)

Public sDataLogStatus As String

‘This variable store the Data Log time interval

Public sDataLogTime As String

‘Used for DataLog

Public LogDataFlag As Boolean

Public DataLogFlag As Boolean

‘Used for communication

Public CommandSentFlag As Boolean

Add the following as additional procedures to Form1.

Private Sub cmdSend_Click()

cmdSend.Tag = 1 ‘send command request

‘ take notice that cmdSend.Tag is a property of the Command button that is utilized for this task

‘tmrCommunication_Timer will route the request to MSComm

End Sub

Private Sub tmrCommunication_Timer()

 Dim vRTseconds As Variant

 Dim sRTmin As String

 ‘The Now keyword provides real time information

 vRTseconds = Second(Now)

 sRTmin = Minute(Now)

 ‘Check automatic datalog issued commands before the manual request

If DataLogFlag = True And vRTseconds > 5 Then DataLogFlag = False

If sDataLogStatus = “True” And CommandSentFlag = False Then

 ‘check datalog time Every 5 minute interval

  If DataLogFlag = False And vRTseconds < 5 Then

 If sDataLogTime = “5” And (Right(sRTmin, 1) = “0” Or Right(sRTmin, 1)=”5") Then

   LogDataflag = True: DataLogFlag = True: SendCommand

  End If

   ‘every 10 minute interval

  If sDataLogTime = “10” And Right(sRTmin, 1) = “0” Then

    LogDataFlag = True: DataLogFlag = True: SendCommand

  End If

   ‘every 15 minute interval

  If sDataLogTime = “15” And _

   (sRTmin = “0” Or sRTmin = “15” Or sRTmin = “30” Or sRTmin = “45”) Then

    LogDataFlag = True: DataLogFlag = True: SendCommand

  End If

   ‘every 30 minute interval

  If sDataLogTime = “30” And (sRTmin = “0” Or sRTmin = “30”) Then

    LogDataFlag = True: DataLogFlag = True: SendCommand

  End If

  End If

End If

 ‘Manual send command path by “Send Command” button control

If CommandSentFlag = False And cmdSend.Tag = 1 Then

 SendCommand

 cmdSend.Tag = 0

End If

End Sub

Private Sub SendCommand()

 ‘Send Command through MSComm1.output

 CommandSentFlag = True

 MSComm1.Output = sCommand + vbCr

 tmrTimeOut.Interval = 60  ’60 milliseconds

 tmrTimeOut.Enabled = True  ‘Start Timer

End Sub

Private Sub MSComm1_OnComm()

 ‘Collect and Route Response from the device. Datalog if specified

Static sRxData As String

Dim sRD As String

Select Case MSComm1.CommEvent

 Case comEvReceive  ‘ Received RThreshold # of chars.

 sRD = MSComm1.Input

 sRxData = sRxData & sRD

  If Asc(sRD) = Asc(vbCr) Then

   CommandSentFlag = False

   If LogDataFlag = True Then  ‘DataLog Path

    StripOffLeadingNonNumerics sRxData

     DataLog (sRxData)  ‘Save Data to a file

     LogDataFlag = False

      tmrTimeOut.Enabled = False ‘Stop Timer

   End If

   sRxData = “”  ‘Clear sRxData for next data collection

   ‘Show data collected on Form1

  Else: lblReceivedData.Caption = “Received Data =>” + sRxData

  End If

 End Select

End Sub

Public Sub StripOffLeadingNonNumerics(ByRef sRxData)

‘ByRef option sends back the result to original variable

Dim bIndex As Byte  ‘Used for indexing

Dim NumberFlag As Boolean  ‘Flag used to exit Do—Loop

bIndex = 1  ‘initial starting point

Do

Select Case Mid(sRxData, bIndex, 1)   ‘Mid String Function

 Case “0” To “9”, “+”, “-”, “.”  ‘Elements of a real number

  NumberFlag = True ‘Flag used to exit Do—Loop

  sRxData = Mid(sRxData, bIndex, (Len(sRxData) - bIndex))

 Case Else

  bIndex = bIndex + 1

 End Select

Loop Until bIndex = Len(sRxData) Or NumberFlag = True

End Sub

Public Sub DataLog(data)

 Dim FILENUM As Byte ‘temporary scratch pad variable

 Dim sMOyr As String

 Let sMOyr = Format(Now, “MMMYYYY”) ‘JAN2000

 ‘Set file attributes to Read Only when exiting therefore

 ‘make the attribute normal for appending data. Setting

 ‘the attribute will stop programs like Excel from taking

 ‘complete control of the file when it is opened for inspection

 ‘or graphing.

 On Error Resume Next

 SetAttr “Data” + sMOyr + “.csv”, vbNormal

 FILENUM = FreeFile

 Open “Data” + sMOyr + “.csv” For Append As #FILENUM

 Print #FILENUM, Date$ + “,” + Time$ + “,” + data

 Close #FILENUM

 SetAttr “Data” + sMOyr + “.csv”, vbReadOnly

End Sub

Private Sub tmrTimeOut_Timer()

 ‘Time out timer required otherwise the program could hang up

 ‘Clear all communication flags

 LogDataFlag = False

  CommandSentFlag = False

   DataLogFlag = False

    cmdSend.Tag = 0

  tmrTimeOut.Enabled = False ‘Stop Timer

End Sub

The manual command button generates a request for display purposes only. A request command based on real time is automatically issued by the data-logger control and the data is saved to a disk file. The data-log request sends the request at the zero second of the interval time. In the event that the operating system may be busy with another task at that moment, provisions are made for a five-second data-collection window. Reliable data collection is well worth the additional logic. This may seem a little excessive, but if the operating system is initializing a Win modem or busy with scandisk, a one-second delay is possible on even the fastest machines.

You will notice that the issuance of the request command is controlled by the timer named “tmrCommunication.” This timer is activated every 60 milliseconds, and all communication requests are routed through it. Each request is operated on a first-come, first-serve basis. If a data-log time interval match occurs, the appropriate flags are set and a request command is issued. If a manual request is already in progress, the steering logic ensures that the command will be issued upon completion of the current request.

A communication timer called “tmrTimeOut” is provided to ensure that the program does not sit there forever looking for a carriage return and ignoring all other requests. This timer is enabled when the request command is issued. Subsequently, when a carriage return is received, the timer is disabled.

When constructing combinational logic statements such as in the Data-Log time-interval detection code, you should pay close attention to the grouping of the logic. For example, A and B or C or D will produce a completely different solution than A and (B or C or D). In the first case, the logic grouping is implicitly (A and B) or C or D. The second logic statement can be expanded as (A and B) or (A and C) or (A and D). As you can see, logical grouping is very critical to the desired result. Figure 2.14 illustrates an actual application with a KT32 serial temperature device. The Data-Log file with the CSV extension is directly readable with Microsoft Excel. This is illustrated in Figure 2.15.

Figure 2.14

Figure 2.15

With the data loaded into Excel, a data chart is just several clicks away, as Figure 2.16 illustrates.

Figure 2.16

Conclusion/Exercise

This chapter introduced serial communication, provided some hands-on experience using the personal computer’s serial port, and offered an opportunity to put some of the elements of Chapter 1 to work.

In the last section, General Purpose Serial Link, a general-purpose serial communications program was created. In addition to the serial communication exchange, this example also demonstrates how the data collected along with an associated time/date stamp is saved to a file for future reference. One item that was not discussed is error checking of the data. How do you know the data wasn’t corrupted? Later chapters of this book will look into several types of error-checking schemes. There is a two-step, simple but effective error-checking scheme that can be added to the GPSL program.

As an exercise, you should implement the required code for the scheme thusly: Add another user-selectable field to the data-collection parameters. In this field, the user provides information on the expected response from the serial device. With the KT32 serial device, the response template would look something like “@+0000.00”. The “+”, “.” and the “0s” indicate numerical characters and, therefore, represent the desired data field: a signed, six-digit number with two decimal places. All other characters are considered fixed literals. The received response would then be checked against this template. If an error occurred, another request would be generated. The second step of the error-checking scheme would require the data of two consecutive requests to be an identical numerical match. Similarly, a subsequent request would be issued until a match occurred.