Python Interfacing PC Printer Electrical Switches
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.
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 - firstname.lastname@example.org # 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
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 email@example.com.
- Introduction to Python Bitwise Operations
- Python Bitwise Operations by Example
- Using the PC Printer Port series:
- Programming the PC Printer Port in Python
- Additional Commands for Py-Parallel
- Controlling Data Bits on the PC Parallel Port
- Connecting Switches to the PC Printer Port with Python
- Reading an Analog Voltage Through the PC Printer Port Part 1
- Reading an Analog Voltage Through the PC Printer Port Part 2
- Controlling a Serial LCD Display on a PC Printer Port with Python
- Serial ADC and LCD Display with PC Printer Port with Python
- Controlling MAX7219 LED Display with PC Printer Port with Python
- MAX7219 8-Digit LED Display and Serial ADC in Python
- Project pages:
- Part 1: Read Arduino with PC Printer Port
- Part 2: Better way to Read Arduino Through the PC Printer Port
- Part 3: Read-Write an Arduino Through a PC Printer Port
- Part 4: Control LCD Display and Arduino from the PC Printer Port
- Arduino sketches needed by programs:
- pportArduino1.ino read only after reset.
- pportArduino2.ino reset once and multiple reads.
- pportArduino3.ino reset once read write Arduino infinite times - multiple commands.
- Related Raspberry Pi projects:
- Connect Serial LCD to Raspberry Pi
- Serial Read from Arduino to Raspberry Pi
- Arduino Raspberry Pi Interface with LCD Display
Printer Port Interfacing Videos:
Connect Electronics to PC printer Port with Python
Setup PC Printer Port with Python-Linux
Use PC Printer Port to Read Analog Voltage
Read-Write Arduino ADC PWN with Printer Port
Printer Port to Serial LCD Display
Connect Arduino to PC Printer Port for advanced control