Background
I
have a number of older digital integrated circuit components (both TTL and
CMOS), and as part of my on-going experiments I wanted to create a simple
counter and single 7-segment display. I needed to confirm that the counter
could take in a number of pulses and provide a digital display readout. The
pulses to be counted could come from a number of sources such as clocks or
sensors providing a pulsed output. I ended up putting together a simple Python
script on the Raspberry Pi to use as a pulse generator.
Research
Initially I put together the circuit below comprising a counter,
with a binary to decimal coded LED driver feeding a 7-segment display. There are many similar circuits available
on-line, the operation and configuration of which is well documented, so I
don't intend fully describing the operation. Suffice to say for each single
complete pulse on the input to the counter, the output count is coded in order
to drive, or light up, a series of LEDs arranged in the 7-segment display
format to display digits 0 to 9.
For a detailed explanation and examples see
the Digital Counter reference below.
To test the circuit I initially provided clock input to the
counter using the simple push button pulse generator described in a previous
article. This worked very well but was
limited to single pulse operation, generated by hand.
To provide a more realistic input I decided to produce a
simple Python script to run on a Raspberry Pi computer. This script would
enable me to input pulse characteristics such as pulse length, the time between
pulses and the number of pulses. Each pulse or set of pulses would appear on a
General Purpose Input Output port (GPIO) and be connected to the digital
counter input. The benefits of this would allow me to reliably generate noise
free, repeatable pulses.
Operation
The diagram below shows the Raspberry Pi 26-way GPIO
connector, with a connection from GPIO port 17, (pin 11) to an IC4050 hex
buffer, which in turn connects to the input of the divide by 10 counter IC7490.
The 4050 operates at 3.3v whilst interfacing to a 5v circuit, which is well
within its operating parameters. It is
required to provide an interface between the Raspberry Pi GPIO output which
operates at 0/3.3v, and the 7490 operating at 0/5v. Power for the 4050 can be taken
from the Raspberry Pi as there is only one hex buffer in use. There are other configuration connections that need to be put in place associated with the 7490 and
7447; see http://www.electronics-tutorials.ws/counter/bcd-counter-circuit.html
The Python script below runs in a console / terminal display
and takes in user supplied parameters to generate pulses - a series of
High and Low level changes. The script is commented which should make it
reasonably straight forward to understand what's going on. The script isn't
entirely error proof - this was one of my first Python coding attempts using
the Raspberry Pi GPIO ports, but if you are careful in selecting the input parameters
all should be well.
In operation I have found this script to be very useful, not
only with this simple counter application but with experimenting with other
shift register and counter combinations where larger numbers of pulses are
required. The advantage of using such a script on the Raspberry Pi is the
ability to craft an exact pulse stream. Where the circuit under test could
produce unknown results it's most important to have confidence in the input
pulse source.
# Python v3.4.2 console based script
# Set an individual Raspberry Pi GPIO port as an output
# Generate pulses by setting the port High & Low [amount of pulses user supplied]
# Pulse duration/length & inter-pulse duration/length is user supplied
# *** NOTE no check is made whether the port number entered is valid to use as an output ***
# Selected port is set Low prior to 'pulse' generation
# Tested on RPi Model B & 2
import RPi.GPIO as GPIO # import GPIO module, use local name GPIO to reference
import time
GPIO.setwarnings(False) # disable warning messages
GPIO.setmode(GPIO.BCM) # use chip specific GPIO pin numbers
try:
while True:
print ("Set Raspberry Pi GPIO port as output & generate pulses")
print ("Warning! supplied parameters are not validated")
print ("Enter a valid Raspberry Pi GPIO number to set as an output [99 quits]")
portstr = input(">_ ") # get port number as a string
port = int(portstr) # convert string to integer
if port != 99:
GPIO.setup(port,GPIO.OUT) # set port as output
GPIO.output(port,GPIO.LOW) # set port low to start
print ("Enter length of pulse in seconds") # get pulse length
lengthstr = input(">_ ")
length = float(lengthstr)
print ("Enter inter-pulse time in seconds") # get pulse off time
spacestr = input(">_ ")
space = float(spacestr)
print ("Enter number of pulses") # get number of pulses to generate
pulsesstr = input(">_ ")
pulses = int(pulsesstr)
loop = 0
while loop < pulses: # set port High & Low, generate pulses
GPIO.output(port,GPIO.HIGH)
time.sleep(length)
GPIO.output(port,GPIO.LOW)
time.sleep(space)
loop += 1
else: # user exit
print ("Exiting..")
GPIO.cleanup()
break
except KeyboardInterrupt: # catch the Ctrl-C
print ("Exit..")
except: # catch other errors
print ("Error..Exiting")
finally: # clean up on exit
GPIO.cleanup()
Python script in operation
The screen shot below shows the parameters provided to
generate a series of pulses. In this case each pulse comprises an on/High
period of 100mS and an off/Low period of 900mS. Total pulse length being 1
Second.
Pulse outputs - examples
To illustrate a number of pulse outputs I have included some annotated oscilloscope traces with various user input values:
Second trace: 50 pulses, each having pulse on 1mS, pulse off 9mS.
Third trace: an expansion of the 50 pulses train to show
the pulse quality and timing accuracy. There is a slight increase in time
between pulse periods - this seems to be more apparent as the pulse lengths decrease,
with frequency increasing. Never the less, for experimenting purposes where
absolute timing accuracy isn't the primary requirement, I've found this to be
more than adequate to drive counter circuits.
Components
IC 4050 Hex buffer
IC 7490 Divide by 10 counter
IC 7447 7-segment display driver
7-segment display LED, common anode
7 resistors; 220Ω 1/4w
References:
IC 4050 Hex buffer datasheet
Digital Counter
IC 7490 Decade and Binary Counter
IC 7447 BCD to 7-Segment Decode/Driver
7-Segment Display - Common Anode