Lab 5 Parallel Port Software Interfacing

ENGSCI 232 Computer Systems 1
Lab 5: Parallel Port Software Interfacing Laboratory
Your name: _________________
ID: ____________
This laboratory aims to demonstrate simple interfacing with the parallel port on a PC.
Due Wednesday 21 Sept 9am
The questions on this handout should be completed during the lab. Listings of the code you
write, along with answers to the questions on this handout, should be handed in at the start of the
next lab. You should have your code running to be checked off at the start of the next lab. You
should aim to spend no more than 1 hour working on this outside lab time.
Team Work
You will be working in pairs in this lab. You can choose your own pairs. You should hand in
your own answers to the questions on this handout, but may hand in joint code listings
completed together (with both your names at the top). Hand in just one copy of the code.
This lab gives you the power to severely damage
your computer, the I/O board, and the power supply
units. Please be careful!
Parallel Port
The parallel port (also known as LPT, or LPT1)
connects the computer to the physical world
Parallel port pin-outs. The unlabelled pins
through a 25-pin connector (right). This interface
are ground (0 volts). From
has 8 output lines (D0…D7), and 4 input lines (S4,
To PC Parallel Port
S5, S6, S7 ), plus some extra lines we won’t use. Each output line
can be set to 0 volts or to 5 volts by setting the value of a particular
bit in the computer to be either 0 or 1. The voltage (0 or 5V) at each
Parallel port connector
input pin can be determined by reading a bit inside the computer.
To help protect the computer from damage, we don’t wire things
directly into the parallel port, but use an interface board which
makes the input and output lines easy to connect to. We will refer to
this board as the ‘Parallel Port Input/Output Board’, or ‘I/O Board’
for short. The board’s Out0…Out7 connectors are wired to the
D0…D7 pins, while In4..In7 connect to S4, S5, S6, S7 . The board
uses LEDs to show what is happening on the output lines (On=+5V,
off =0V). The input lines are normally at 0 volts, but can be ‘pulled
up’ to 5 volts by the user (by connecting the input line to a 5 volt
supply, or pushing one of the input buttons.)
Page 1
Out 0
Out 1
Out 2
Out 3
Out 4
Out 5
Out 6
Out 7
In 7
In 6
In 5
In 4
In7 In6 In5 In4
input switches
I/O Board
Version 4.0
To PC Parallel Port
First Steps
We begin by connecting the I/O board
(shown in Figure 1) to its power supply
& then the computer.
As a general rule, it is safest to make
sure the computer and the I/O board are
both turned off before they are
connected. The I/O board should then
be turned on before the computer (and
turned off last). However, in this lab we
are unlikely to damage anything by
connecting things while they are on, so
we take this faster option.
Parallel port connector
Out 0
Out 1
Out 2
Out 3
Out 4
Out 5
Out 6
Out 7
In 7
In 6
In 5
In 4
input switches
1/ Turn on your computer, and start it
booting up. Logon in the normal
Figure 1: Breadboard (left) and I/O Board.
2/ There should be a PC parallel cable
We use the breadboard later.
(thick cable with a wide plug) and a
DC power cable (thin cable, small round plug) coming up through your desk. Connect the
plug on the DC power cable in to the “DC In” on the I/O Board.
3/ Next, connect the PC parallel cable plug to the I/O board as shown. (If you are doing this at
home, note that the cable has male connectors (with protruding pins) that connect to female
connectors (with holes) on the back of the computer and on the board. That is, the connector
you use on the computer should look the same as the one on the I/O board. (There is another
similar male connector on the back of the computer; this one is for the serial port, and should
not be used.)
4/ Congratulate yourself on completing your (probably) first computer interfacing exercise!
ParMon: Monitoring the Parallel Port
The next step is to read and set values on the parallel port. To do this,
we read or write values in the computer’s input/output address space.
Because the smallest unit the computer works in is bytes (not bits),
we will be reading and writing 8-bit numbers (between 0 and 255).
All 8 output lines are controlled by putting values into the byte at
input/output address 37816, while the voltages at the 4 input lines are
determined by reading the byte at address 37916.
To make this easy, we use the Parallel Port Monitor program
“ParMon 2000”. This allows us to change bits (individual output
lines) in the 37816 output, and continuously display the 37916 input..
1. Run the Parallel Port Monitor (ParMon) program from the Start :
The ParMon Program
Programs Files : Other menu.
2. Use the small arrows to enlarge the display, and then turn on the
Beep option and set the sampling rate to be ‘As fast as possible’. (The beep option may not
work on all PCs.) You may also find it useful to choose ‘Always on Top’ option; this will
keep this program in front of Excel when we run it.
Page 2
Version 4.0
Report Questions
 What happens when you click on the top 8 red/black buttons on
ParMon (shown right). Try a few to see how they work. Be sure to
look at the I/O board as you do this, or you may miss something
important! Hint: Each time you change a button, a new value is
written to the memory location 37816. Explain how each button
changes this value, and how the 8 output voltages (and hence what
you observe) are related to the value that is written.
The top buttons control
the outputs.
The push buttons on the I/O board change the byte that is read at 37916.
ParMon is reading this all the time and showing the value in the “In 379”
area. Complete the following to describe the value that is available at
37916. in terms of the 4 values (being 0=0V or 1=5V) at the 4 ‘in’ inputs
The inputs as shown
‘In7’, ‘In6’, ‘In5’ and ‘In4’. (Remember, these voltages are normally 0,
in Parmon
but change to 5V when you push the button.) Note: The slightly strange
behaviour can be blamed on IBM engineers making design decisions back
in 1981. Their decisions made sense at the time when LPT1 was used for controlling dot
matrix printers.
Bitwise values: Give a value for each
bit, being either 0, 1, or some value
expressed in terms of one of inputs In7, In6, etc.,
where InX=0 (button up) or InX=1 (button down)
Bit 7
Bit 6
Bit 5
Bit 4
Bit 3
Bit 2
Bit 1
Give a formula for the DataRead value in terms of the 4 inputs In7, In6, In5, & In4.
Dataread value (in decimal) =
Explain, in terms of the bits in the value being output, how the clock, count, and ripple
functions work. (Hint: For the ripple, try watching it when there is just 1 output turned on.)
Page 3
Version 4.0
Bit 0
Interfacing with the Parallel Port through
Now launch Visual Basic 6. We will next write code in VB
to interface with the parallel port. A partially completed
VB Project file is available on the server in folder “LPT
Project” .
1. Find (but do NOT open) the “LPT Project” folder in the
ENGSCI232SC course folder under "Teaching".
2. Copy this folder into your own working directory. Do
NOT open the original.
The LPT1 Project
3. Open your copy of the folder, and double click on the
pretty looking Project1 file (not the ugly one!), as
shown in the figure (right). This will open up the project in VB to give a screen like that
shown below.
4. This project has both a form and a module (named Module1 under Modules in the Project
window, right). A module is used to contain code that is required, but doesn't really belong to
a form. In our case, this module defines functions and
subroutines that we use to access the parallel port.
5. Run this project. You will see its form (shown right) appear.
Note that not all the buttons on this form work, yet!
6. Experiment with the "Read from LPT1" and "Write to LPT1"
buttons to see how they work. Hint: Try pressing the switches on
the I/O Board as you click the "Read from LPT1" button and
changing the text box (the one containing 255) to other values
before clicking "Write to LPT1". Watching ParMon may also
give you clues as to what’s going on.
There are a few lines of code that may be new to you…
Const LPT1out As Long = &H378
Const LPT1in As Long = &H379
This defines LPT1out as a long integer and gives it the value 378
(in hex). This value is “constant”, ie cannot be changed by the
program. This is the ‘address’ where we find the output part of
the parallel port in the computers input/output memory. LPT1in
works in a similar way.
The VB Form
lblReadValue = DlPortReadPortUchar(LPT1in)
This reads the byte from the parallel port’s input, and puts it’s value (as text) in the “lblReadValue”
label on the form. (DlPortReadPortUchar is a function defined in Module1.bas.)
DlPortWritePortUchar LPT1out, Value
This writes the number in “Value” into the parallel port’s output, thus controlling the
voltages on the output connections.
7. Try clicking the "Count Clicks" button, and then pressing the buttons on the IO Board.
Page 4
Version 4.0
8. The code listing for this project is shown in Appendix 1. Have a good look though this code
to understand how the examples work. Note the names like "cmdCount" used for a button,
"lblClickCount" used for a label, and "txtWriteValue" used for an editable text boxes. This
naming convection is common in VB, and is required in any code you hand in from now on.
This convention can also be applied to integers etc, although this is optional and not required
in this course. The details are listed in Appendix 2. Be sure to follow this convention for any
buttons, labels, pictures etc you add to the form.
Report Exercises
 Complete the missing subroutines in the project (see listing in Appendix 2), but NOT the
reaction timer (we do that later). Each of the buttons is already linked to a subroutine; you
just have to fill in the gaps. Be sure to use the logical operators (AND, OR, XOR etc) if they
are appropriate. Use compact code; marks will be deducted for doing things the long way.
Full marks are reserved for easy-to-read code, ie well documented, properly indented,
efficient, descriptive names, using the correct VB naming convention (Appendix 2) for all
items on a form, etc.
Next week the tutors will check that your code performs the following functions:
 Count completed (counts from 0 to 255):
 Echo completed (Each of 4 LEDs on when corresponding switch down):
 Bounce Completed (1 LED bounces down/up/down/up…):
 Toggle Completed (Each switch turns 1 LED on/off when the button goes down):
Page 5
Version 4.0
Appendix 1: VB Code Listing
' Excel LPT 99 (c) 1999, 2000 A. Mason, Dept of Eng Sci, University of Auckland
' Some modification 1999 by S. Blackett and A. Mason in 2000, 2001, 2002
' This program demonstrates interfacing with the parallel port from VBA.
' It requires dlportio from Scientific Software Tools, Inc.
' Visit to download dlportio if the code doesn't run
' Note: We
use the following naming convention:
is a form
is a command button
is a text label
is an editable text box
' Force all variables to be explicitly declared
Option Explicit
' Declare the addresses of LPT1 for input and output.
' Note that &h means 'hex' (base 16). A 'Long' is a 32 bit integer
Const LPT1out As Long = &H378
Const LPT1in As Long = &H379
' The following subroutines read or write data entered by the
' user to or from LPT1
Private Sub cmdReadLPT1_Click()
This macro reads LPT1, and places the byte value in the
lblReadValue label on the form.
Note that VB converts the number into text for displaying
lblReadValue = DlPortReadPortUchar(LPT1in)
End Sub
Private Sub cmdWriteLPT1_Click()
This macro takes the value entered into the txtWriteValue text box
on the form and writes it to the LPT1 port.
A beep is generated if the value is
outside the range 0-255.
Dim Value As Integer
If Not IsNumeric(txtWriteValue) Then
Beep ' user has not entered a number
Value = txtWriteValue ' Get number out of the form's text box
If Value >= 0 And Value <= 255 Then
DlPortWritePortUchar LPT1out, Value
End If
End If
End Sub
Page 6
Version 4.0
' This subroutine demonstrates timing and counting on LPT1
Private Sub cmdCountClicks_Click()
' This subroutine counts the number of button changes (roughly speaking)
' in 5 seconds. The LPT1 input value and count is displayed on the form.
' It measures 5 seconds by using timeGetTime which returns the number of
' milliseconds since the computer was turned on.
' Note that while our code is running, VB doesn't get a chance to draw any
' changes to labels etc on the screen; we do this ourselves using Refresh.
Dim StartTime As Long
Dim ClickCount As Integer
Dim NewInput As Byte, OldInput As Byte
Const CountPeriod As Integer = 5000 ' 5000 milliseconds = 5 seconds
MousePointer = vbHourglass ' Show an hour glass to indicate "thinking"
' Set our count so far to zero
ClickCount = 0
lblClickCount = ClickCount ' set new value in the count label...
' and force the label to redraw itself
' Display and remember the current input
OldInput = DlPortReadPortUchar(LPT1in)
lblReadValue = OldInput
lblReadValue.Refresh ' force the label to redraw itself
' Remember our current time
StartTime = timeGetTime
' Keep looping for 5 seconds
While timeGetTime < StartTime + CountPeriod
' Read the input from LPT1
NewInput = DlPortReadPortUchar(LPT1in)
' Has it changed?
If NewInput <> OldInput Then
' Yes... update count and display new value
ClickCount = ClickCount + 1
lblClickCount = ClickCount
' force the label to redraw itself
' Display new input value
lblReadValue = NewInput
' force the label to redraw itself
' and remember this current input
OldInput = NewInput
End If
MousePointer = vbDefault ' Restore the standard mouse pointer
End Sub
Page 7
Version 4.0
' TASK 1: Count
Private Sub cmdCountUp_Click()
This subroutine outputs the values from 0 to 255 on LPT1
and also shows the LPT1 output value in lblCount using
lblCount = Value
Unlike ParMon, it always starts at 0, and goes up to 255.
It waits pauseTime=200 milliseconds between counts using:
SleepEx pauseTime, 0
Press Ctrl-Break to interrupt execution of the subroutine.
Const pauseTime As Long = 200 ' the pause between counts, in milliseconds.
Dim Value As Integer
' the value we write to the output
MousePointer = vbHourglass ' Show an hour glass to indicate "thinking"
' Here's a bit of code for you to start from... it will need changing.
' This code outputs the value 10; you will need to add a loop that changes
' the value being output from 0 to 255
Value = 10
lblCount = Value
' show value on the form
' force label to redraw on the screen
DlPortWritePortUchar LPT1out, Value
SleepEx pauseTime, 0 ' wait for 200 milliseconds so we can see what's happening
MousePointer = vbDefault ' Restore the standard mouse pointer
End Sub
' TASK 2: Echo
Private Sub
' This code
' is turned
' This code
controls the LEDS so that each of LEDs 4, 5, 6, and 7
on if the corresponding button is down, and off otherwise.
runs for 10 seconds
Dim StartTime As Long
Dim NewInput As Byte, NewOutput As Byte
Const CountPeriod As Integer = 10000 ' 10 seconds
MousePointer = vbHourglass ' Show an hour glass to indicate "thinking"
StartTime = timeGetTime ' Remember our current time
Do While timeGetTime < StartTime + CountPeriod ' Keep looping for 10 seconds
' Get new input value
NewInput = DlPortReadPortUchar(LPT1in)
' Change the following line to calcuate the new output value
' We want the each light to be on when the button's down, and off when it's up
' Remember one of the buttons is different from the others...
NewOutput = 0
' Output new value to parallel port
DlPortWritePortUchar LPT1out, NewOutput
MousePointer = vbDefault ' Restore the standard mouse pointer
End Sub
Page 8
Version 4.0
' TASK 3: Bounce
Private Sub cmdBounce_Click()
' This makes a single LED appear to bounce from top to bottom
' and back again (like the Knight Rider display!) with a
' small pause between steps. It does 20 'down and ups'
' Make sure it doesn't go too fast to see; a wait of
' around 200 milliseconds between changes might be good.
Const pauseTime As Long = 200 ' the pause between steps, in milliseconds.
' Show an hour glass to indicate "thinking"
MousePointer = vbHourglass
' Your code goes here
' This might be useful
SleepEx pauseTime, 0 ' wait for 200 milliseconds so we can see what's happening
MousePointer = vbDefault ' Restore the standard mouse pointer
End Sub
Page 9
Version 4.0
' TASK 4" Toggle
Private Sub cmdToggle_Click()
' This controls the LEDs so that the user can turn on or off
' each of LEDs 4, 5, 6, and 7 using the buttons 4, 5, 6 and 7.
' The user clicks a button (down and then up) once to turn an LED on, and
' then repeats this to turn it off.
' The LED change happens when the button goes down; nothing happens as it come back up
' This code runs for 10 seconds
' The following might be useful
Old Button State
New Button State
Toggle LED
No action required
Dim StartTime As Long, OldInput As Byte, NewInput As Byte
Dim InputChange As Byte, Output As Byte
Const CountPeriod As Integer = 10000 ' 10,000 milliseconds = 10 seconds
MousePointer = vbHourglass ' Show an hour glass to indicate "thinking"
StartTime = timeGetTime ' Remember our current time
' Turn off all the lights
Output = 0
DlPortWritePortUchar LPT1out, Output
' Read the current state of the buttons
OldInput = DlPortReadPortUchar(LPT1in)
Do While timeGetTime < StartTime + CountPeriod ' Keep looping for 10 seconds
' Get new button input
NewInput = DlPortReadPortUchar(LPT1in)
' Change following line to calculate 'InputChange' which determines which
' buttons have changed since last time around the loop.
' Each bit in InputChange is equal to 1 only if the corresponding
' button has changed value since last time.
' The correct answer is one of:
InputChange = OldInput and NewInput
InputChange = OldInput or NewInput
InputChange = OldInput xor NewInput
InputChange = 0
' We want to ignore buttons coming up; things only happen when buttons go down
' Add code in here that resets to zero the bits in any positions
' for which the corresponding button is not currently down.
' As a result of this InputChange will have a 1 in a position only if
' the user has just pushed down the curresponding button.
' We don't care what happens in bits 0, 1, 2, 3.
InputChange = 0
' Calculate the new output value so that the lights change (on to off,
' or off to on) in those positions for which the user has just pushed down
' the button. You only need 1 line of code.
' Use XORs and ANDs to calculate a new Output value from the
' current Output value and the InputChange variable
' We don't care what is output in bits 0, 1, 2, 3.
Output = 0
' Write new output value
DlPortWritePortUchar LPT1out, Output
' Remember old button states to use next time around loop
OldInput = NewInput
MousePointer = vbDefault ' Restore the standard mouse pointer
End Sub
Page 10
Version 4.0
Private Sub cmdReaction_Click()
' This sub will be used for a game in the next Lab.
' For example it might turn off all the LEDs, wait for
' between 5 and 10 seconds, turn on the LEDs, and
' times how long until a button is pushed.
' The time is then output to lblReactionTime in milliseconds
' Hint: Rnd gets a random number between 0 and 1.
MousePointer = vbHourglass ' Show an hour glass to indicate "thinking"
MousePointer = vbDefault ' Restore the standard mouse pointer
End Sub
Page 11
Version 4.0
Appendix 2: The “Hungarian Notation” VB Naming Conventions
(from Hungarian Notation (HN) is a naming
convention invented by Charles Simonyi from Microsoft. The naming conventions found on this
page are relatively simplistic compared to other texts on the subject. On the other hand, it is
short and simple enough to be easy to remember, implement, and follow on a regular basis.
In this course, we won’t use any of the prefixes listed under ‘Variables’.
User Defined Type
Form Objects
Command Button
Picture Box
Common Objects
Class Module
Form Class Module
Form Dialog Box
Form Lookup Table
Sub Form
Sub Report
Database Objects
Append Query
Delete Query
Query Definition
Query for a form
Make Table Query
Pass-Through Query
Query for a report
Query or View
Detail Report
Sub Report
Sub Report
Table Definition
Relationship Table
Note: In addition to the conventions listed below, scope must be considered when naming a
 When declaring module level variables, add an 'm' to the variable prefix, eg mintMarkTotal.
 Add a 'g' prefix for global variables, eg gintMaxMark.
Page 12
Version 4.0