This is only a preview of the August 2022 issue of Practical Electronics. You can view 0 of the 72 pages in the full issue. Articles in this series:
|
NANO PONG ON YOUR TV
BY TIM BLYTHMAN
Atari’s Pong arcade game is nearly 50 years old and is remarkable for its
time, inspiring many of the computer games that followed. Our Nano
Pong game is modern and retro at the same time; it replaces the 70-odd
discrete logic chips in the original with a single chip that costs about £1!
But it still looks and plays much like the original game.
I
f you’ve ever seen any of the
modern single-chip versions of
Pong, you may well have felt they
lacked a certain something and were
inferior to the original ‘discrete’
(multi-chip) incarnation. This project
is an attempt to change that!
While this is a complete redesign
of the circuitry to implement the
Pong game, we have tried to be reasonably faithful to the original in
terms of its graphical style, and how
the game is played.
Another inspiration for this design
is the power of new 8-pin PIC microcontrollers. One such chip that we
like is the PIC12F1572 microcontroller. It’s one of the cheapest 8-pin PICs
available, but despite low cost, it has
superior features to the PIC12F675
that we have used for many years in
out projects.
As one of the smallest, cheapest
microcontrollers around, we decided
that it would be an interesting challenge to use it to recreate Pong.
Nano Pong
Our version of this classic game is
made using not much more than a
small microcontroller and some passive components. It’s so tiny that we
haven’t even specified a case for it; it
can simply be wrapped up in a length
of heatshrink tubing and left hanging
behind the TV.
A pair of controllers (‘paddles’) are
built into small enclosures on flying
leads, but if you’re interested in creating something more akin to the cabinets and consoles that would have
existed at the time, you can do that too.
30
Nano Pong is closely inspired by
the original Pong; two players control
on-screen bats that vie to keep the ball
in play. The winner of the game is the
first to win 11 rallies. We say ‘inspired’
because we haven’t attempted to make
it identical. No doubt those who
played the original game would notice
some differences.
But we have tried to emulate the
style and gameplay of the older game.
In so doing, we hope that those building this project can experience the
joy of playing a 50-year-old computer
game without the hassle of having to
locate and solder a multitude of vintage logic chips.
Like the original, the two player control paddles are potentiometers that
translate the player’s paddle position
to a corresponding on-screen paddle.
We’ve also added a pushbutton
(which isn’t in the original) to allow
a player to ‘serve’ the ‘ball’. The PIC
chip emulates the gameplay mechanics, and generates analogue audio and
video signals that can be fed to a PAL
television’s AV inputs.
Hardware
Fig.1 shows the complete schematic
– there is not much to it! Potentiometers VR1 and VR2 and pushbuttons
S1 and S2 are not located on the PCB,
but connected via flying leads.
CON1 is the first modern flourish. A
mini-USB socket provides 5V power to
the circuit, significantly simpler than
the original mains supply. Since many
TVs now have a USB socket, the unit
can be powered from the TV that it’s
connected to.
5V power goes to pins 8 (GND) and
1 (VDD) of IC1, a PIC12F1572 microcontroller, bypassed with a 100nF capacitor. IC1’s MCLR pin is pulled up to 5V
by a 10kΩ resistor, so the PIC will run
its internal program from Flash memory as soon as power is applied.
Pins 7 and 6 of IC1 are inputs to the
ADC (analogue-to-digital converter)
peripheral and communicate the
Player 1 and Player 2 control inputs
to the PIC.
Each player has a 1kΩ potentiometer padded on both track ends by a
470Ω resistor. The resistors are fitted
to the PCB. The potentiometer flying
leads connect to pins 1-3 of CON5 for
Player 1, and CON4 for Player 2. With
the 470Ω padding resistors in series
Our Nano Pong project fits
on a miniature 43 x 16.5mm PCB.
It relies on a single micro that costs just £1.
Practical Electronics | August | 2022
Nano TV Pong
Fig.1: this Nano version of Pong doesn’t need much in the way of hardware!
A single 8-pin PIC microcontroller and surface-mounted passives are
complemented by a handful of off-board parts for the player controls.
with the 5V supply, the player paddle wipers vary between 1.25V and
3.75V depending on the potentiometer rotation.
We’ve specified standard 24mm
potentiometers, but if you think your
Nano Pong might be subjected to
extended periods of vigorous gameplay, you could upgrade them to more
robust types.
Although it would not be in line
with the original, slide (rather than
rotary) potentiometers could also be
used to make a more intuitive interface, matching the straight-line motion
of the bat on the screen.
Pins 4 and 5 of CON4 and CON5
connect across NO (normally open)
momentary pushbutton switches. By
pressing the button, the player pulls
pin 2 of CON4/CON5 (connected to
the potentiometer wiper) to 0V. As the
lowest voltage the pot can generate is
around 1.25V, the microcontroller can
distinguish this as a button press. The
top padder resistor limits the worstcase current through the switch.
Pin 5 of IC1 is the pulse-width modulated (PWM) sound output. It feeds a
1kΩ/470Ω divider, reducing the PWM
amplitude from 5V peak-to-peak to
around 1.6V peak-to-peak or 0.56V
RMS. This is AC-coupled by a 1μF
capacitor and biased to ground by a
100kΩ resistor before going to the output RCA plugs that connect to the TV.
We’ve chosen these values to keep
the sound signal well below 1V, as the
audio (as per the original Pong) is a
shrill-sounding square wave.
The video signal is a standard CVBS
(composite video baseband signal) in
monochrome PAL format. Many of the
Practical Electronics | August | 2022
differences between PAL and NTSC
involve colour transmission, so many
NTSC TVs should lock onto this signal. The main remaining difference
is in the number of lines that are sent
per frame. Modern TVs will usually
detect and display the correct format.
This signal is formed from digital levels at output pins 2 and 3 of
IC1. Pin 2 is designated as luminance
(LUM) and pin 3 as synchronisation
(SYNC). The TV is assumed to have
a 75Ω terminating impedance, so it
will see different voltages depending
on the pin states.
If both LUM and SYNC are low, then
the output is 0V, which corresponds to
the so-called ‘sync’ level. With SYNC
high and LUM low, the TV sees around
300mV. This is known as black level,
and corresponds to a black raster being
displayed. Finally, with both pins
high, a level near 1V is seen, which
generates a white raster.
Scope 1 shows the voltage generated
over time for a typical horizontal scan
line, along with several lines of video
(including this scan line) above. Note
the horizontal sync pulse troughs on
either side of the displayed video.
Analogue video signal
So how does a TV translate this signal
to a two-dimensional picture? The TV
continually scans its raster in left to
right horizontal scan lines from top to
bottom of the screen, with each scan
line taking around 64μs.
A 4-5μs low pulse indicates the
start of a new horizontal line. The visible area takes up most, but not all,
of the remaining scan line. The actual
visible area takes 52μs to transmit,
so it is bracketed by periods of black
level called the ‘back porch’ and
‘front porch’.
Colour transmissions contain signals in the back porch to help decode
the colour picture information; since
we are not transmitting such signals, the picture is decoded as monochrome. During the visible video area,
the video intensity is determined by
the signal voltage, between the black
and white levels.
A longer sync signal is used to trigger a vertical retrace. Often, the vertical
sync signal is mixed with the horizontal sync signal to create a so-called ‘serrated’ sync signal that allows horizontal sync to be detected during the vertical retrace. This improves the TV’s
ability to maintain horizontal hold.
Thus, a single 1V peak-to-peak
analogue signal can encode raster
intensity and both horizontal and
vertical synchronisation to recreate
a 2-D TV image.
Software
Understanding the following is not
necessary for getting Nano Pong to
work. Still, it is interesting to compare it with how the original version
Once finished, the PCB and cabling can
be covered with heatshrink tubing.
31
Scope 1: a scope grab of the video signal for a typical scan line, along with
a portion of the display around that scan line, so you can see how they
correspond. Each line is delimited by the dips in the trace to the low sync level
(horizontal sync pulses), while the peaks correspond to a white raster on a
black background. The red lines indicate that there is a substantial part of the
signal outside of the visible area.
Fig.2: the way that the screen is laid out
makes it very easy to generate in a leftto-right fashion. Each horizontal scan
line can display the Player 1 bat, Player
1 score, net, Player 2 score and Player
2 bat. The ball is produced separately
by the PWM peripheral so that it can
appear at any horizontal position.
operates, especially since the original
version was purely hardware-based.
Accurately emulating the logic
chips in Pong would be a better job
for an FPGA than a microcontroller, as
the former allows everything to happen independently in parallel, a luxury we do not have.
Our PIC needs to generate a tightly
timed signal to maintain a steady picture. Most older PICs require a crystal
oscillator to provide an accurate enough
clock to display a TV image, which
would take up two of our eight pins.
But here, we get accurate timing by
running the PIC’s internal oscillator at
32MHz (requiring the use of the internal PLL), which gives an instruction
clock of 8MHz. At 64μs per line, we
32
can distinguish up to 512 horizontal
positions per line. By scaling this to
use 256 positions, we can use 8-bit
bytes to hold pixel locations. In practice, the actual horizontal play area is
around 200 positions.
If you look closely at our images,
there is a bit of horizontal jitter, which
would not be present with a more precise crystal oscillator. But we don’t
think it looks out of place in our recreation of 50-year-old technology.
As PAL TV signals have 312 horizontal lines per field, we conveniently
set the play area to be 256 lines, which
neatly lines up with the visible area
on most TVs.
With such tight timing needed, we
have fallen back to using assembly
language so that we know how long
every part of our program will take to
execute, ensuring the image quality
does not suffer.
The initial setup is written in the C
language. It then calls our main assembly language subroutine. The main
program is a loop of 312 subroutine
calls, each corresponding to a horizontal display line variant. These, in
turn, consist of numerous direct pin
manipulation commands to set the
necessary video output levels interspersed with calls to a delay routine
to affect the timing.
This starts with six vertical sync
lines to start the field, followed by 28
blank lines. The blank lines are 5μs at
sync level (SYNC and LUM low), followed by 59μs at black level (SYNC
high and LUM low). The vertical sync
line is serrated by delivering 5μs of
black and 59μs of sync instead.
After this there are 256 active display lines. The counter LINECOUNT
is used to keep track of which line
is being displayed, and this is compared with the bat and ball positions,
then flags are set to indicate whether
the bat or ball should be displayed
on the current line. These flags are
set during the line’s horizontal sync
period, so it does not affect the timing
of the visible part of the display. The
way that these flags are set is somewhat unusual.
To ensure that each line runs for
the same amount of time, as needed
to maintain a steady picture, we avoid
skipping over code we don’t want to
run (as usually happens if a condition
is false), which would change the program timing.
Instead, we use the ‘skip on bit
test’ assembler opcodes (BTFSC and
BTFSS), which essentially treat the
following opcode as a NOP (no operation) if a test is true. These sequences
of commands all take the same time
regardless of their outcome, retaining
the necessary consistent timing.
For lines where the ball is visible,
we use the PWM peripheral to display it. The PWM peripheral on the
PIC12F1572 is quite advanced, with
phase and offset parameters. The ball’s
horizontal position is determined by
the PWM phase and its width by its
duty cycle. This means we don’t have
to keep track of when to turn the LUM
output on and off.
With that taken care of, the remainder of the visible lines can be neatly
broken up into sections that can be
handled sequentially.
From left to right, these are the
Player 1 bat, Player 1 score, the net,
Player 2 score and Player 2 bat. For
the bats and net, we briefly toggle the
polarity of the PWM signal, thus getting the XOR effect as the ball passes
over, so the ball does not ‘merge’
with them.
Fig.2 shows how the horizontal lines
are organised, and Screen 1 shows it
without the lines.
The scores are handled slightly differently. These are effectively bitmaps
hard-coded as brief assembly language sequences, so the PWM output
is turned off while the scores are being
displayed. Thus, the ball disappears
behind the scores, which could provide an advantage for a canny player.
After the 256 active lines, a further
21 blank lines are displayed, followed
by a single customised blank line that
handles all of the logic that updates
the game’s state. The code for this line
Practical Electronics | August | 2022
Parts List – Nano Pong
Screen 1: a typical game of Nano
Pong. The ball is in play after Player 1
has won the first point of the game.
Screen 2: with a reasonable amount
of program Flash memory to spare,
we added this splash screen when the
unit is powered up.
Screen 3: the start of a game, before
Player 1 has served the ball.
is two instructions shorter than the
other blank lines, to account for the
time taken to jump back to the start
of the loop.
Most of the time that this final
blank line is being generated, the
game logic is processed. If it detects
that the ball has struck a wall or
bat, the ball vector is adjusted. This
includes taking into account where it
strikes the player’s bat, as this affects
the ball’s vertical speed, like the original game. Also like the original game,
each strike of the bat can also increase
the ball speed.
These events also trigger a sound
to be played, generated by a different
PWM channel playing a tone from pin
5 until it is reset on the next field. This
gives a variety of differently toned
beeps depending on what the ball
has struck.
The two ADC channels for the
Practical Electronics | August | 2022
1 double-sided PCB coded 08105212, 43 x 16.5mm, from the PE PCB Service
1 PIC12F1572-I/SN (SOIC-8) programmed with 0810521B.HEX (IC1)
1 SMD mini Type-B USB socket (CON1)
1 10cm length of 20mm diameter clear heatshrink tubing
3 RCA plugs AND
1 3m length of shielded cable OR
1 triple RCA plug cable [eg, Jaycar WV7316]
1 5-way male pin header (CON2, optional for programming, see text)
Capacitors (all 50V X7R SMD ceramic, M3216/1206-size)
11 F
1 100nF
Resistors (all 1% metal film SMD, M3216/1206-size)
1 100kΩ (marked ‘104’ or ‘1003’)
1 10kΩ (marked ‘103’ or ‘1002’)
2 1kΩ (marked ‘102’ or ‘1001’)
6 470Ω (marked ‘471’, ‘470R’ or ‘4700’)
Controller parts
2 small plastic enclosures (eg, UB5 Jiffy boxes)
2 1kΩ 24mm rotary potentiometers (VR1, VR2) [eg, Jaycar RP3504]
2 large knobs (up to 50mm) to suit potentiometers VR1 and VR2
2 momentary pushbuttons (S1,S2) [eg, Jaycar SP0716]
1 1m length (or longer) of 4-5 core wire for controllers [eg, Jaycar WB1590]
2 100mm cable ties
paddles are alternately sampled and
allocated to their respective players. The relationship between the
ADC value and on-screen position
is adjusted to take into account the
range set by the resistors.
If the ADC value is outside this
range, then the bat position is not
updated, which also takes care of the
case when the ADC pin is pulled low
by the button press. Thus, trick serves
are not possible.
A point is registered whenever the
ball reaches the screen edges (ie, missing the player’s bat), which increments
the score counter. Flags are set to indicate that the player winning the point
is to serve, and if the score has reached
11, that a win has occurred.
In this case, a melody is played on
the pin 5 PWM channel and the winning score is flashed. Timing for these
events comes from different bits in the
FIELDCOUNT parameter.
Since the main program only uses
about 2/3 of the available Flash memory, we also added a splash screen,
shown in Screen 2. This uses data
from the score bitmap sequences in a
hard-coded loop. An 8-bit timer counts
down over 256 fields at 50Hz, so this
screen shows for around five seconds.
Component notes
With such a small PCB, there isn’t
a lot that can be modified. If you
find that the volume of the sounds
doesn’t match your other TV sources,
you can adjust the 1kΩ/470Ω divider
connected to pin 5 of IC1. Reduce the
470Ω part value (or increase the 1kΩ
part value) to reduce the volume.
Alternatively, increase the 470Ω part
value to increase the volume.
If you want to make the game harder,
you can change the 470Ω resistors connected to the potentiometers at pins
1 and 3 of CON4 and CON5. Increasing their value will create a gap near
the top and bottom of the screen that
the bats can’t reach, as in the original
Pong game.
For example, replacing these four
470Ω resistors with 560Ω resistors
will leave around a 3% gap at the top
and bottom of the bat travel.
If you have a 5V power source that
doesn’t have a USB connector, it can
be fed to pins 2 (positive) and 3 (negative) of CON2. We haven’t tested it,
but the circuit should run from a 4.5V
supply, such as three AA or AAA batteries in series.
Construction
In keeping with the theme of this
being a modernised and miniaturised
version of Pong, the PCB uses mainly
SMD components. Since these are
resistors and capacitors, with one IC
in a relatively large 8-pin SOIC package, plus the USB socket, assembly is
not difficult.
The double-sided PCB is coded
08105212, measures 43 x 16.5mm and
is available from th PE PCB Service.
Refer to the PCB overlay and wiring
diagram (Fig.3) during construction.
Start by mounting the SMDs. We
recommend that you have a temperature adjustable soldering iron,
flux paste, tweezers, a magnifier
and solder wicking braid, as well
as some solder wire. The small PCB
33
Fig.3: with fewer than 20
onboard parts, the PCB is easy to
assemble. Mount SMD parts IC1
and CON1 first, then the passives,
then the connectors (if you are
using connectors).
can be temporarily secured to your
desk with some Blu-Tak or similar
material, so it doesn’t move around
during assembly.
Fume removal or ventilation is also
recommended, as flux generates more
smoke than typical solder wire.
Start by fitting IC1 and CON1. Apply
flux to the pads and rest CON1 in place,
then add a small amount of flux to the
top of the pads. Its small plastic pegs
should align it to holes in the PCB.
Clean the tip of the iron and add
some fresh solder. Apply the iron’s
tip to the two longer pads on the PCB;
the flux should help the solder run up
the leads. You only need to solder the
two outer leads as this socket only supplies power.
If you create a solder bridge, add
some more flux and press the solder
braid against the bridge until it draws
up any excess solder. There should
still be enough solder left to make a
successful connection.
Turn up the iron temperature
slightly to solder the four larger pads
to the PCB that mechanically secure
the connector, then return the iron to
its original setting.
IC1 needs to be fitted in the
correct orientation, with its pin
1 towards the USB socket. There
should be corresponding marks on
the PCB and the part itself.
Apply flux paste to the PCB pads
and rest the IC in place. Add a little
solder to the iron top and touch it to
one pin to tack the part in place. If the
IC isn’t flat against the PCB or the pins
are not aligned with their pads, carefully apply the iron again and adjust
the position.
Once it is correctly aligned, solder
the remaining pins. Then, if you have
bridged pins, use the braid to remove
them as described above.
The 100nF capacitor sits between
IC1 and CON1. Using a similar technique to IC1, tack one lead, adjust and
solder the other. Go back to the first
lead and add a little flux paste or solder to freshen it up.
Don’t be alarmed if your solder
joints don’t have compact, concave
fillets. The important thing is that the
parts are connected firmly; a large
glossy solder joint that isn’t bridging
to other parts is fine.
Now fit the remaining SMD passives
where shown in Fig.3. The resistors are
usually marked (see the typical codes
in the parts list), while the capacitors
will only have their values printed on
the packaging.
Once all the surface-mounted parts
are fitted, you can clean the excess flux
from the PCB using your preferred flux
cleaning solution. Allow the board to
dry out thoroughly before continuing.
All of the through-hole headers
are optional, except CON2, which is
required for programming the microcontroller. CON3-CON5 can be regular
headers or sockets, or you can just solder wires (eg, sections of ribbon cable)
directly to the PCB pads.
Programming IC1
You can program the chip after soldering it to the board, but it’s a bit tricky.
The problem is that the programming
pins, pins 7 (ICSPDAT) and 6 (ICSPCLK) are also connected to the player
paddle wipers. So we recomend you
program the chip before connecting
up those paddles.
To do this, plug your programmer
into the ICSP header, CON2. You can
solder a header strip to the pads, but
we’ve had success by simply resting
the header in place and applying gentle force to ensure contact.
A PICkit 3 or PICkit 4 can be used,
or even a Snap programmer, if you can
supply power to the board (which the
Snap cannot do by default). The easiest way to do this is using the miniUSB socket, CON1.
Use software like Microchip’s
MPLAB X IPE to upload the 0810521B.
HEX file to the chip – this file is available for download from the August
2022 page of the PE website. There’s
nothing obvious to indicate that the
chip is working, apart from using the
software option to verify that the file
has been transferred correctly.
Wiring it up
We built the two player controls into
plastic UB5 Jiffy boxes, but you could
also mount all the parts in a single
enclosure to imitate the hardware
of the arcade version of Pong. Fig.4
shows the two possible ways that
these can be wired.
The only difference is that if the
controls are wired remotely, one end
of the switch can be wired directly to
This is what our player controls look like, with a separate UB5 box for each controller.
Internally it’s very simple, comprising a 1kΩ potentiometer and momentary pushbutton.
34
Practical Electronics | August | 2022
Fig.4: wiring up the two player paddles/
controllers externally only requires a fourcore cable. Each paddle is wired the same,
with Player 1 connecting to CON5 and Player
2 connecting to CON4. If everything is being
mounted in the same enclosure, you can run
the pot and switch wires back to CON4 and
CON5 separately.
the pot wiper to save having to run
an extra wire back to CON4 or CON5.
Fig.5 shows the cutting diagram that
suits the parts we have used (listed
in the parts list). You might need to
modify the hole sizes if you are using
different parts.
Our photos show how we have connected everything, but the design is
quite flexible and can be adapted to
different parts and enclosures. We’ll
describe how we finished our version.
Drill holes in a pair of UB5 Jiffy
boxes according to Fig.5, noting that
this should include a hole in the end
of the box for the wire. The bottom of
the box becomes the top when held in
the hand. Doing it this way means that
we aren’t trying to juggle wires leading
from the lid to the cable entry while
mounting the lid.
Cut down the potentiometer shafts
to suits the knobs you are using, and
use a file to tidy up any rough corners
or edges. This is most easily done with
a hacksaw while holding the end of the
potentiometer shaft (rather than the
body) in a vice. This avoids straining
the potentiometer mechanism.
Fit the pushbutton switches and
potentiometers to the Jiffy boxes. You
can also fit your knobs at this stage. We
whipped up some 3D printed knobs to
give a bit more grip. As with the firmware, the knob design files are available for download from the August
2022 page of the PE website.
Solder and heatshrink the wires as
shown in Fig.3 and our photos. Run
the connecting cable out through the
hole and secure a cable tie around each
cable to prevent it from being pulled
off the terminals inside the box.
Next, solder the other ends of the
wires to their respective pads on CON4
and CON5. If you want to test the paddle operation, apply power and check
for 3.75V on the middle lead of each
potentiometer in the fully clockwise
position, and 1.25V anti-clockwise.
Practical Electronics | August | 2022
Fig.5: we built our paddles into UB5 Jiffy boxes, with holes drilled
in their bases as shown. There also needs to be a hole in the side
of the box for the cable to pass through. Check that the size of your
potentiometers, switches and wires match the hole sizes before drilling.
This voltage should drop to 0V when
the button is pressed.
There are NC (normally closed) variants of this switch, so if you find that
the action is reversed, you might have
this other variant.
To make the RCA connections for
the TV, we simply cut a three-way
RCA cable in half. Strip back a good
amount of insulation and collect all
the braids together. Attach these to
pin 1 of CON3 (marked on the back
with ‘G’). We put a short length of
heatshrink tubing over the braids for
extra protection.
Then bare the internal wires by a
small amount. The video plug (which
will usually be yellow) should be connected to pin 2 of CON3, marked ‘V’.
Pins 3 should go to the left audio lead
(white, ‘L’) lead, and pin 4 should go
to the right audio lead (red, ‘R’).
Plug the RCA leads into the AV
connections of a television and apply
power to CON1. You should see the
splash screen followed by the main
game screen. Check that everything
operates correctly.
If so, the main PCB can be sealed
up by enclosing it in a length of 20mm
diameter heatshrink tubing. Ensure
that the CON1 end does not overhang
the connector. A 10cm length should
ensure that the cables are secure and
have some strain relief.
Let’s play!
At a game’s start, the ball will be in front
of one player’s bat. Pressing the button
on that controller will cause the ball to
be served. Rotate the pot to move the bats
on the screen to keep the ball in play.
If a player misses the ball, the other
player wins a point. Once one player
reaches eleven points, the game is over.
The winning score will flash and a melody will play. Serving the ball starts a
new game.
Reproduced by arrangement with
SILICON CHIP magazine 2022.
www.siliconchip.com.au
This is how we built our
Nano Pong setup. It uses a
separate controller for each
player, and has a composite
video connector.
35
|