DB25 connector pinouts.

Read-Write Arduino Microcontroller Through PC Printer Port Part 3

by Lewis Loflin

To use this one must setup their PC to use my modified pyparallel. See Programming the PC Printer Port in Python.

Arduino is programmed in a type of C and can operate a vast number of sensors and motors, but is worthless for high-level programming better done in Python.

So far we have wired two differing PC port configurations to read from Arduino. One Arduino sketch required a reset to update temperature reading with a DS18B20, read an ADC, etc. while the second example did a continuous read of Arduino.

Now we can do a read-write to Arduino so Arduino can execute commands and send back selected data or control electronics by command.

The problem with the serial write routine was to synchronize low-level compiled C in Arduino with a high-level interpreted language such as Python. I did this by using an interrupt routine to shift the serial data into Arduino. This was done by using D3 (pin 5) connected to Arduino DP2 - INT0.

The wiring diagram is shown above and was connected to an Arduino Nano - should work with any of them. Only pins 2-5 are used.

We have two test programs at the bottom to consider:

The first program calls function readAnalog0() which writes a code (0x5500) to Arduino to do an analog read of ADC 0 and send back the 10-bit result. (0-1023) The result is divided by 4 because it will be sent back to operate an 8-bit PWM control for Arduino DP9.

It then adds that 8-bit value to 0x5800 then writes it back again to Arduino that ANDs that 16-bit value with 0xFF to control the duty cycle of the pulse-width modulator (PWM) on Arduino DP9 to control the intensity of an LED.

In other word adjusting a pot on analog 0 on the Arduino controls the brightness of the LED.

while 1:
    j = readAnalog0()
    j = j / 4
    writeArduino(0x5800 + j)
    j =  readArduino(.1) & 0xff
    print "j = ", hex(j), " in HEX."
    # print "j = ", convBinary(j), "in binary."
    # print "j = ", j, "in decimal."
    

The second programs loops 20 times calling readDS18B20() and print the result in HEX, binary, and decimal. The function readDS18B20() in addition prints out the temperature in Celsius and Fahrenheit.

   
# Read DS18B20 temp sensor 20 times.
for k in range(0,20):
    j = readDS18B20()
    print "Reading number ", k
    print "j = ", hex(j), " in HEX."
    print "j = ", convBinary(j), "in binary."
    print "j = ", j, "in decimal."
    time.sleep(5)

This version can read any of the Arduino sketches but can only write to pportArduino3.ino.

#!/usr/bin/env python 
# File pportArduinoWrite.py
# http://www.bristolwatch.com/pport/index.htm
# By Lewis Loflin - lewis@bvu.net
# Read serial data from Arduino
# Same as TLC548 except 16 bit.

# This version use Data port bits D0-D3
# Can write control code to Arduino 
# Data from Arduino displayed on terminal.

# SW1 is connected from ground to DB25 pin 10 and pulled high
# by a 10k resistor.


# Reset used with Arduino sketch
#  pportArduino1.ino for each read. 

# Reset used once for pportArduino2.ino
# then multiple reads.  

# pportArduino3.ino is setup for read/write.
# Write a code then read back result
# in some case original code.
# 0x5600 blink LED on DP13 returns 0x5600
# 0x5500 analogRead(0) returns 0-1023
# 0x5700 DS18B20 temp sensor return integer
# 0x58XX PWM DP9 - X being 0 to 255 in HEX.
# Arduino returns 0x58XX



import parallel
import time

p = parallel.Parallel()


###############################################

# Reset Arduino to perform
# whatever reading if needed
# Delay 2 seconds after reset
def resetArduino():
    writeD2(1)
    time.sleep(.001)
    writeD2(0)
    time.sleep(3)


###############Connecting Arduino#############

# init i/o pins
p.setDataStrobe(0) # Pin 1 NC
p.setAutoFeed(0)   # Pin 14 NC
p.setInitOut(1)    # Pin 16 NC
p.setSelect(0)     # Pin 17 NC
p.getInError()	   # Pin 15 input to DATA OUT Arduino DP4

# data LSB first
# enable CS1 HIGH
# set CLK HIGH
# read data bit shift left
# set CLK LOW
# repeat 15 times
# then once more after loop.
# last bit should not be shifted.

# Arduino
# define CLK 6
# define CS1 5
# define dataBit 4
# Pin 15 input to DATA OUT Arduino DP4


# Connect pport pin 2 to Arduino CLK DP6
def writeD0(bit_val):
    if bit_val == 1:
        p.setData(p.data() | 1) # set bit 0
    else: # clear bit 0
        p.setData(p.data() & (255 - 1))
    return



# Connect pport pin 3 to Arduino CS1 DP5
def writeD1(bit_val):
    if bit_val == 1:
        p.setData(p.data() | 2) #set bit 1
    else: # clear bit 1
        p.setData(p.data() & (255 - 2))
    return


# Connect pport pin 4 to Arduino Reset
def writeD2(bit_val):
    if bit_val == 1:
        p.setData(p.data() | 4) #set bit 1
    else: # clear bit 1
        p.setData(p.data() & (255 - 4))
    return


# Connect pport pin 5 to Arduino DP2
def writeD3(bit_val):
    if bit_val == 1:
        p.setData(p.data() | 8) #set bit 1
    else: # clear bit 1
        p.setData(p.data() & (255 - 8))
    return

# init Arduino:
writeD0(0) # Arduino DP6 CLK for read data for write 
writeD1(0) # Arduino CS1 DP5
writeD2(0) # Arduino Reset
writeD3(0) # Arduino DP2 IRQ CLK for write



#################Write Arduino#######################

# MSB out first!
def writeArduino(value):
    writeD3(1) # tell Arduino write is coming
    writeD1(1) # CS1 HIGH
    for  x in range(0,15):       
        temp = value & 0x8000
        if temp == 0x8000:
           writeD0(1) # set data bit HIGH
        else:
            writeD0(0)
        value = value << 0x01 # shift left
        time.sleep(.001)
        writeD3(0)
        # time.sleep(.001)
        writeD3(1)
    temp = value & 0x8000
    if temp == 0x8000:
        writeD0(1)
    else:
        writeD0(0)
    writeD1(0)
    writeD3(0)
    return

    
###################Read Arduino######################

# DelayT is used to pause after enable CS
# for sensor to upsate. Delay should be 
# 0.5 Sec. for DS18B20 to cycle through.
# 0.1 for everything else.

def readArduino(delayT):
        temp = 0
        writeD1(1) # enable CS
        time.sleep(delayT)
        for i in range(0,15): # loop here 7 times
                writeD0(1) # CLK HIGH
                time.sleep(.001)
                temp = temp + p.getInError() # get bit
                temp = temp << 1 # shift 1 bit left
                writeD0(0) # CLK LOW
        writeD0(1) # CLK HIGH
        time.sleep(.001)
        temp = temp + p.getInError() # get bit 8 
        writeD0(0) # CLK LOW
        writeD1(0) # CS LOW
        return temp

#####################################################

# Print a 16-bit number (integer) in binary. 
# Returns string.
# unlike python bin() this doesn't drop leading zeros
def convBinary(value):
    binaryValue = '0b'
    for  x in range(0, 16):
        temp = value & 0x8000
        if temp == 0x8000:
           binaryValue += '1'
        else:
            binaryValue += '0'
        value = value << 1
    return binaryValue

####################################################    
	
# SW1 is connected from ground to DB25
# pin 10 and pulled high by a 10k resistor.
def SW1():
	return p.getInAcknowledge()  
   # check pin 10 DB25 when pressed returns 0



def degC(val): # convert value DS18B20 read
	return val * 0.0625
	

def degF(val): # convert value DS18B20 read
	return (val * 0.0625) * 9 / 5 + 32



def readDS18B20():
    print "Please wait for T reading..."
    writeArduino(0x5700)
    Treading = readArduino(.5) # delay .5 sec. DS18B20
    print degC(Treading), "deg. C"
    print degF(Treading), "deg. F"
    return Treading


def readAnalog0():
    writeArduino(0x5500)
    return readArduino(.1)

	

# play with these commands:	
# pportArduino3.ino is setup for read/write.
# Write a code then read back result.

# 0x5600 blink LED on DP13 returns 0x5600

# 0x5500 analogRead(0) returns 0-1023

# 0x5700 DS18B20 temp sensor return integer

# 0x58XX PWM DP9 - X being 0 to 255 in HEX.
# Arduino returns 0x58XX

resetArduino()

# Comment out one of the following two
# test programs.


# program below reads Arduino Analog0
# then writes it back to PWM and LED on
# DP9.
while 1:
    j = readAnalog0()
    j = j / 4
    writeArduino(0x5800 + j)
    j =  readArduino(.1) & 0xff
    print "j = ", hex(j), " in HEX."
    # print "j = ", convBinary(j), "in binary."
    # print "j = ", j, "in decimal."

# Read DS18B20 temp sensor 20 times.
for k in range(0,20):
    j = readDS18B20()
    print "Reading number ", k
    print "j = ", hex(j), " in HEX."
    # print "j = ", convBinary(j), "in binary."
    print "j = ", j, "in decimal."
    time.sleep(5)


print "Exit now."      
        
exit


Download pport-1.0.iso from Sourceforge.com then burn to DVD (file size 920 meg.), insert into DVD drive and reboot. Make sure PC is set to boot from DVD ROM.

This is pre-configured by myself to use Python to control the printer port. Python can be run from IDLE or Geany.

All of my PPORT electronics projects will work without installation to a PC.

Programs can be saved to thumb drive in LIVE mode.

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.

Linux Videos

Printer Port in C


Web site Copyright Lewis Loflin, All rights reserved.
If using this material on another site, please provide a link back to my site.