DB25 connector pinouts.

Python Interfacing PC Printer Electrical Switches

by Lewis Loflin

So far we have been turning LEDs on-off through software - now it's time to get input from the PC printer port. In addition we look at other ways to blink an LED on-off and detect switches from the printer port.

N.O. switches

Before we get started note the PC printer port (pport) has no pull up resistors or 5-volt supply - that must be supplied from outside. Let's look at some short code snippets.

Fig. a and Fig. b above illustrate two ways to connect a mechanical switch to a data pin be it the pport, Arduino, etc. Fig. a produces a HIGH when pressed while Fig. b produces a LOW when pressed.

def Sw1(): # check state pin 10 Db25
	return p.getInAcknowledge()  

The above is a function simply called Sw1(). It returns the state of pin 10 on the Db25 pport connector. If we connect the switch in Fig. a it returns a LOW when the switch is pressed, if we connect Fig. b a HIGH is returned when pressed. How do we handle this?

# Blink LED D0 on-off
while 1: 
    time.sleep(.5) # delay .5 sec.
    invertStateD0() # or use toggleD0() 
    if not Sw1():  
        break # break "while" loop if Sw1 pressed

Above we have while loop using either functions invertStateD0() or toggle D0() to blink a LED on-off. The "if" statement will break the while loop if TRUE. If using the switch setup in Fig. b we must use "NOT" because it would return true if the switch wasn't pressed. We wouldn't use it if using switch setup Fig. a.

# Blink LED D0 on-off
while Sw1(): 
    time.sleep(.5) # delay .5 sec.
    invertStateD0() # or use toggleD0() 

The code above does the same thing. If using the switch configuration of Fig. b leave out "not". This saves some code over the earlier "while" snippet.

# use if statement write state to pin
# bit_val must be 1 or 0
def writeD0(bit_val):
    if bit_val == 1: # could also be just "if bit_val"
        p.setData(p.data() | 1) # set bit 0 with bitwise OR
    else: # clear bit 0 with bitwise AND
        p.setData(p.data() & (255 - 1))
    return

The above routine reads the latch on the data port then writes either by 1 or 0 by using an "if" statement and bitwise operations OR to set a bit while AND clears a bit. This works on the other 7 bits by taking the bit position as a power of 2 subtracted from 255. Ex. D1 is pow(2,1) = 2; 255 - 2. Ex. D2 is pow(2,2) = 4; 255 - 4. etc.

# invert pin state with if statement
def toggleD0(): # reverse state of D0
    if p.data() & 1: # check if bit D0 set
        writeD0(0) # if yes reset bit
    else:
        writeD0(1) # if no set bit

In the above snippet we read the data port latch with data() use an "if" then use writeD0() to change the bit by using another "if" statement. "p.data() & 1" return TRUE only if bit D0 is HIGH. Works fine but we can do better than this.

def invertStateD0():
    p.setData(p.data() ^ 1)

Note setData(x) writes a byte to the 8-bit data port.

The above using bitwise XOR will invert any bit XORed with a binary 1 be it a single bit or multiple bits. Much more efficient than toggleD0(). Again look at the data bit as a power of 2 then XOR that number with the byte return by data() to invert (toggle) the bit. Ex. D3 is pow(2,3) = 8; p.setData(p.data() ^ 8).

Understanding basic bit manipulations is the key to connecting hardware to embedded controllers such as Arduino or the PC printer port. Have fun!

The program is written in Python and runs under Linux. To use this one must setup a module pyparallel. How to set this up is on my webpage Programming the PC Printer Port in Python




#!/usr/bin/env python
# File toggle.py
# http://www.bristolwatch.com/pport/index.htm
# By Lewis Loflin - lewis@bvu.net
# Demonstrate the use of python bitwise operations
# on PC printer port to detect external switches.
# Must use my version of pyparallel on website for p.data().
# Invert state individual bit in data port on-off. 
# Connect LED to pin 2 of Db25 if not already there.


# This can be done from Idle, Geany, or command line
# Set Geany to use lxterminal if available.


import parallel
import time

p = parallel.Parallel()


# use if statement write state to pin
# bit_val must be 1 or 0
def writeD0(bit_val):
    if bit_val == 1: # could also be just "if bit_val"
        p.setData(p.data() | 1) # set bit 0 with bitwise OR
    else: # clear bit 0 with bitwise AND
        p.setData(p.data() & (255 - 1))
    return

# invert pin state with if statement
def toggleD0(): # reverse state of D0
    if p.data() & 1: # check if bit D0 set
        writeD0(0) # if yes reset bit
    else:
        writeD0(1) # if no set bit

# alternative:
# use bitwise XOR for bit D0
# byte is read, single bit D0 bit inverted,
# by use of XOR then written to port
# p.data() reads byte on data port latches 
# p.setData() writes byte to data port latches
# there are 8 latches or bits
def invertStateD0():
    p.setData(p.data() ^ 1)


# use bitwise XOR for bit D1
# p.data() reads value on data port
def invertStateD1():
    p.setData(p.data() ^ 2)

# for all 8 bits use powers of 2
# such as 4, 8, 16, 32, 64, 128
# will invert related bit.

p.setData(0x00) # all LEDs off

# Toggle D0 on/off - LED will blink at 1 Hz.
# p.getInAcknowledge() returns state of pin 10.
# Pin 10 tied to VCC via 10k resistor.
# Sw1 is N.O. switch connected to ground.
# When Sw1 pressed pin 10 goes LOW.
# LED will blink until Sw1 closed.
# state on pin 10 goes LOW which when
# used with logical not makes "if" True
# breaking the while loop.


# Sw1 is connected from ground to Db25 pin 10 and pulled high
# by a 10k resistor.
def Sw1(): # check state pin 10 Db25
	return p.getInAcknowledge()  

print "Running. Press Sw1 to exit."	

# Blink LED D0 on-off
while 1: 
    time.sleep(.5) # delay .5 sec.
    invertStateD0() # or use toggleD0() 
    if not Sw1():  
        break # break "while" loop if Sw1 pressed

print "Good by!"

exit 


Projects

Below are listed a series of projects using pyparallel and electronics. Starting with routines I wrote to aid students I'd advise walking through this in sequence. Have fun and send comments and/or corrections to lewis@bvu.net.