This is only a preview of the October 2024 issue of Practical Electronics. You can view 0 of the 80 pages in the full issue. Articles in this series:
Articles in this series:
Articles in this series:
Articles in this series:
Articles in this series:
Articles in this series:
Articles in this series:
|
Max’s Cool Beans
By Max the Magnificent
Arduino Bootcamp – Part 22 (more on BCD & other stuff)
A
s usual, my head is bursting
with all sorts of “stuff” I want to
talk about. For example, a young
engineer recently contacted me to say
he was in the process of writing a
technology-related book about something or other (I don’t want to give the
game away). He was asking for advice
regarding potential publishers.
I know how hard it can be to get one’s
foot through the publishing door, especially in the case of older, staid companies whose revolving doors have a habit
of leaving you on the outside with your
nose pressed against the glass looking in.
Happily, I was able to recommend the
guys and gals at No Starch Press, who
bill themselves as “The finest in geek
entertainment” (https://nostarch.com/).
To be honest, I cannot remember seeing
a No Starch publication I didn’t want to
add to my library. Their Learn to Program
with Minecraft by Craig Richardson is
awesome. Some of the other No Starch
tomes that grace my bookshelves are
Dead Simple Python: Idiomatic Python
for the Impatient Programmer by Jason
C. McDonald, Computer Architecture:
From the Stone Age to the Quantum Age
by Charles Fox, and The Game Console
2.0: A Photographic History from Atari
to Xbox by Evan Amos. Also, I just took
delivery of Writing a C Compiler: Build
a Real Programming Language from
Scratch by Nora Sandler.
Now, before we expand on our previous discussions and take a deeper dive
into the binary-coded decimal (BCD)
waters, a couple of other topics are
bouncing around my old noggin. So, if
you will be kind enough to indulge me…
Feeling grey or gray?
The fact that some words have different spellings in British English (I hail
from the UK) and American English (I
currently hang my hat in the USA) can
be a tad tiresome. For example, ‘grey’ is
more common in British banter, while
‘gray’ is more frequent in American argot.
By some strange quirk of fate, this
leads us to the topic of Frank Gray
(1887–1969), who was a physicist and
researcher at Bell Labs. Frank was responsible for numerous innovations,
especially in the field of television.
However, he is primarily remembered
for coming up with the concept of Gray
codes (when I started out, I wondered
why they weren’t called “Grey codes”).
Connection
Binary
0 0 0
0 0 0
1
0 0 1
0 0 1
2
0 1 0
0 1 1
3
0 1 1
0 1 0
4
1 0 0
1 1 0
5
1 0 1
1 1 1
6
1 1 0
1 0 1
7
1 1 1
1 0 0
Fig.1: Binary vs. Gray codes.
46
As that philosopher for our time,
Mickey Mouse (1928–) famously said:
Display segments
and pin numbers
Ground (0V)
D9
D0
D1
5 10 9 1 2 4 6 7
DP G F E D C B A
Gray
0
Count on me
No connection
3
Decimal
Compare and contrast the two 3-bit
sequences shown in Fig.1, for example.
In the case of transitions between 1
and 2 or 5 and 6 in decimal, two bits
change when using a standard binary
counting sequence. Similarly, in the
case of transitions between 3 and 4 or
7 and 0 in decimal, all three bits change
in standard binary. By comparison, the
ordering of the values in the Gray code
are such that adjacent values always
differ by only a single bit.
In addition to their use when arranging the rows and columns in Karnaugh
maps, Gray codes are widely employed
to prevent spurious outputs from electromechanical switches and to facilitate
error detection and correction in digital
communications.
3
C
3
C
B
B
E
C
B
E
10-Bit Ring
Counter
y9
E
y0
INIT CLK
From
Arduino
May or may
not be used
From Arduino
or BCD decoder
Fig.2: Using a 10-bit ring counter to control ten 7-segment displays.
Practical Electronics | October | 2024
“Arithmetic is being able to count up to
twenty without taking off your shoes”.
You can’t argue with logic like that.
In my last column, we discussed how
we could use ten D-type flip-flips to
implement a 10-bit ring counter. The
idea is that only one bit from this counter
is active (logic 1) at any time, so clocking the counter results in a sequence of
1000000000, 0100000000, 0010000000…
0000000100, 0000000010, 0000000001,
and back to 1000000000 again.
As illustrated in Fig.2, we could use
the outputs from our ring counter to
control ten transistors. In turn, these
transistors could control ten 7-segment
displays.
Personally, I think this is rather clever.
When used in conjunction with a BCD
decoder, it means we can control all
ten 7-segment displays using just six
of the Arduino’s pins. Is there any way
we could increase our cleverness quotient? Well, by golly, I’m glad you asked
because there certainly is.
sidering thus far is
Straight
JohnsonCounter
Counter
StraightRing
RingCounter
Counter
Johnson
a ‘straight ring counState Q0
Q0Q1
Q1Q2
Q2Q3
Q3Q4
Q4
State Q0
Q0Q1
Q1Q2
Q2Q3
Q3Q4
Q4
State
ter’. It may also be State
referred to as a ‘one00
11 00 00 00 00
00
00 00 00 00 00
hot counter’ because
11
00 11 00 00 00
11
11 00 00 00 00
only one output is
active, or ‘hot’, at any
22
11 11 00 00 00
22
00 00 11 00 00
time. A comparison
33
11 11 11 00 00
33
00 00 00 11 00
of 5-bit (aka 5-stage)
straight ring and
44
11 11 11 11 00
44
00 00 00 00 11
Johnson counters is
55
11 11 11 11 11
00
11 00 00 00 00
shown in Fig.3. Can
you spot the two big
66
00 11 11 11 11
11
00 11 00 00 00
differences between
77
00 00 11 11 11
22
00 00 11 00 00
these implementa88
00 00 00 11 11
33
00 00 00 11 00
tions?
The first differ99
00 00 00 00 11
44
00 00 00 00 11
ence derives from the
00
00 00 00 00 00
00
11 00 00 00 00
wiring of the INIT
signal. In the case Fig.4: 5-bit straight ring vs Johnson counter sequences.
of the straight ring
counter, this signal is connected to the the case of the Johnson counter, the D0
S (set) input of the first stage and the R input is fed from QB4, which is the false
(reset) inputs of the remaining stages. output from the final stage.
This means that when the INIT signal
Imagine taking a strip of paper and
is placed in its active state, our 5-bit joining its ends to form a circular band.
Jolly Japes with Johnsons
straight ring counter will be loaded In this case, the band will have two faces
I love digital logic. I stand in awe of with a value of 10000. By comparison, or sides (inside and outside) and two
people like Frank Gray who can come in the case of the Johnson counter, this edges. This would be the equivalent
up with logical concepts like Gray signal is connected to the R inputs of all to our straight ring counter. If we take
codes – things I wouldn’t be capable of the stages. As a result, when the INIT another strip of paper and give one of
conceiving myself in a thousand years. signal is placed in its active state, our its ends a one-half twist before joining
Another of my heroes is the American 5-bit Johnson counter will be loaded the two ends, we end up with a Möbius
inventor, engineer, computer pioneer
with a value of 00000.
strip, which boasts only one side and
and professor, Robert Royce “Bob”
The second difference occurs in the one edge. This would be the counterpart
Johnson (1928–2016). Amongst many way in which we feed the inputs to our to our Johnson counter.
other inventions and innovations, Bob
counters. In the case of the straight ring
The way in which we implement the
came up with something we now call counter, the D0 input to the first stage feedback path in our Johnson counter
is fed from Q4, which is the true output explains why this form of counter may
the Johnson counter.
The ring counter we’ve been con- from the final stage. By comparison, in also be referred to as a ‘twisted ring
Connection
No connection
counter’, a ‘switch-tail ring counter’,
a ‘walking ring counter’, or a ‘Möbius
counter’ (good luck finding tidbits of
trivia like this in other, lesser electronic
S
S
S
S
S
D0 Q0
D1 Q1
D2 Q2
D3 Q3
D4 Q4
hobbyist magazines!).
So, how do these seemingly trivial
QB0
QB1
QB2
QB3
QB4
differences affect the outputs of these
R
R
R
R
R
counters in the real world? The easiest
way to wrap our brains around this is
INIT
to compare the number of count states
CLK
along with their corresponding values
as proffered by these dueling implementations (Fig.4).
y0
y1
y2
y3
y4
As we see, there are multiple dif(a) 5-stage straight ring counter
ferences in the sequences. A glance at
the highlighted 1s in Fig.4 reveals that
the straight ring counter circulates a
S
S
S
S
S
single 1 bit around the ring (it could be
D0 Q0
D1 Q1
D2 Q2
D3 Q3
D4 Q4
a 0 if we wished). By comparison, the
Johnson counter circulates a stream of
QB0
QB1
QB2
QB3
QB4
R
R
R
R
R
1s followed by a stream of 0s.
A by-product of the previous point
INIT
is that, in the case of the straight ring
CLK
counter, two bits always change when
transitioning from one state to the next.
By comparison, in the case of the Johny0
y1
y2
y3
y4
son counter, only a single bit changes
(b) 5-stage Johnson counter
when transitioning from one state to the
Fig.3: 5-bit straight ring vs. Johnson counter implementations.
next. This means the Johnson counter
Practical Electronics | October | 2024
47
Each of his register states was imDecoded Outputs
plemented using
y0 = Q0B & Q1B & Q2B & Q3B & Q4B
0
0 0 0 0 0
two back-to-back
tubes. So, instead
y1
=
Q0
&
Q1B
&
Q2B
&
Q3B
&
Q4B
1
1 0 0 0 0
of using 20 expeny2 = Q0 & Q1 & Q2B & Q3B & Q4B
2
1 1 0 0 0
sive tubes to build
a 10-bit straight
y3 = Q0 & Q1 & Q2 & Q3B & Q4B
3
1 1 1 0 0
ring counter, Johny4 = Q0 & Q1 & Q2 & Q3 & Q4B
4
1 1 1 1 0
son required only
y5 = Q0 & Q1 & Q2 & Q3 & Q4
5
1 1 1 1 1
10 tubes to build
his 5-bit counter.
y6 = Q0B & Q1 & Q2 & Q3 & Q4
6
0 1 1 1 1
Furthermore, each
y7 = Q0B & Q1B & Q2 & Q3 & Q4
7
0 0 1 1 1
of his ten 5-input
AND gates was imy8 = Q0B & Q1B & Q2B & Q3 & Q4
8
0 0 0 1 1
plemented cheaply
y9 = Q0B & Q1B & Q2B & Q3B & Q4
9
0 0 0 0 1
and cheerfully
Fig.5: Decoding 10 one-hot signals from a 5-bit Johnson counter.
using only one
resistor and five
is implementing a form of Gray code.
diodes. Pretty clever, eh?
And, speaking of states, the 5-bit
While this discussion isn’t particularly
straight ring counter passes through relevant to what we aim to achieve, in
only five states (numbered 0 to 4) before my experience, being aware of concepts
returning to its starting state. We could like this can be unexpectedly useful
generalize this to say that an n-bit straight when one least expects it.
ring counter passes through n states
How common!
before returning to its starting state.
Before returning to the BCD fray, we
By comparison, the 5-bit Johnson
counter passes through ten states (0 to must take one more little diversion (so
9) before returning to its starting state. unlike me, I know); some of the things
We could generalize this to say that an we are going to talk about shortly can
n-bit Johnson counter passes through 2n be hard to wrap one’s brain around, it
states before returning to its starting state. behooves us to take things step-by-step.
Throughout this epic Arduino BootWe’ve already seen how to control
ten 7-segment displays using a 10-bit camp series, we’ve been working with
straight ring counter. The cool thing is common-cathode (CC) 7-segment disthat, since we get both the Q (true) and plays, as shown in Fig.6(a). This means
QB (false) outputs from each register the cathodes associated with the eight
stage ‘for free’, we can achieve the same light-emitting diode (LED) segments
thing using a 5-bit Johnson counter in are joined inside the device. We use
conjunction with ten 5-input AND gates, the anodes to control the LEDs on an
as illustrated in Fig.5.
individual basis.
When the states of 5-bit Johnson counIt’s also possible to get common-anode
ter are decoded to generate ten one-hot (CA) 7-segment displays, shown in
outputs, the resulting implementation Fig.6(b). In
is known as a Johnson Decade Counter. this case, the
From Arduino
These are available as off-the-shelf chips, anodes are insuch as the 74HC4017 (https://pemag. ternally joined
au/link/abzh).
and we use
Why go to all this trouble? When the cathodes
Johnson originally patented this concept to control the
in 1954, he was working with diodes, LEDs individ0V
resistors, and vacuum tubes (valves). ually.
Johnson Counter
State
Johnson Decade Counter
Q0 Q1 Q2 Q3 Q4
Multiple anodes
If you cast your mind back to our
early experiments with our CC displays,
you will recall that we connected our
common cathode to ground and used
our Arduino to control the anodes (via
current-limiting resistors), as in Fig.7(a).
As we discussed way back in the
mists of time (PE, March 2023), LOW
and HIGH in our programs are seen
by the compiler as being the same as 0
and 1, respectively. When we write a
LOW (or 0) to a digital pin, this will be
presented as 0V to the outside world.
When we write a HIGH (or 1) to a digital
pin, this will be presented as 5V to the
outside world (at least, in the case of
the Arduino Uno we’re using).
In the case of our CC displays, presenting 0V (LOW) or 5V (HIGH) to an
anode will switch that segment off or on,
respectively. This explains why we’ve
been using the following definitions in
our programs:
// Definitions for CC display
#define SEG_ON
HIGH
#define SEG_OFF
LOW
Later, in the body of our programs,
when we called the digitalWrite()
function to instruct one of the Arduino’s
pins to switch a segment on or off, we
used our SEG_ON and SEG_OFF definitions as arguments to the function.
Have you ever wondered why we bothered to create and use these definitions
in the first place? Since we intend to
use only CC displays in this series, you
might feel this is redundant. There are
two reasons we typically do it this way.
First, even if we only ever use CC
displays, the SEG_ON and SEG_OFF
names are easy for others to understand
if they read our programs (and for us to
(b) CA tied to power
5V
(a) CC tied to ground
From Arduino
From Arduino
(d) CA with PNP transistor
5V
E
B
PNP
C
(a) Common cathode (CC)
(b) Common anode (CA)
C
B
NPN
E
0V
Multiple cathodes
Fig.6: Common cathode vs common cathode displays.
48
(c) CC with NPN transistor
From Arduino
Fig.7: CC and CA displays with and without transistors.
Practical Electronics | October | 2024
understand when we return long after
we’ve forgotten how everything works).
Second, if we ever decided to exchange our displays for their pincompatible CA counterparts, as in
Fig.7(b), all we have to do on the hardware side would be to disconnect the
common pin from 0V (ground) and
reconnect it to 5V (power). Meanwhile,
on the software side, we just need to
modify our definitions as follows:
// Definitions for CA display
#define SEG_ON
LOW
#define SEG_OFF HIGH
The rest of the program will continue
to work ‘as is’. Brilliant!
Switcheroo
Before we proceed, let’s take a moment
to remind ourselves that pure silicon is
an insulator. We can modify the silicon
using a process called ‘doping’ to add
small quantities of different elements
into its crystalline matrix. We can create
P-type (positive) and N-type (negative)
silicon, both of which do conduct.
The interesting stuff happens at a
PN junction, where P-type and N-type
materials meet. A single PN junction
forms a diode, a component that only
conducts in one direction. If we use the
right materials, we end up with a diode
that emits light when it’s conducting,
ie, a light-emitting diode (LED).
If we create a silicon sandwich from
two back-to-back PN junctions, we have
a bipolar junction transistor (BJT). These
components can be used in two ways: as
analog amplifiers or as digital switches.
Furthermore, there are two ways
in which we can create our silicon
sandwiches: NPN or PNP (all of this is
explained in excruciating exhilarating
detail in my book, Bebop to the Boolean
Boogie (https://pemag.au/link/abzi).
Returning to our common-cathode
implementation, in our more recent
experiments, we’ve inserted an NPN
transistor between the common cathode
pin on our 7-segment display and the 0V
(ground) rail, as in Fig.7(c). This transistor acts as a switch to simultaneously
enable or disable all the segments the
Arduino is trying to switch on.
The transistor we opted to use was a
BC337 because this can handle up to
800mA, much more than maximum
current (8 × 20mA = 160mA) if all eight
segments are active at the same time.
First, we used one of these transistors
to control the brightness of a single 7segment display by switching its segments on and off very quickly while
controlling the ratio of the on-to-off
times (PE, January 2024). Next, we used
two of these transistors to multiplex
between two 7-segment displays (PE,
Practical Electronics | October | 2024
April and May 2024). More recently
(starting in PE, June 2024), we moved
to using four transistors to multiplex
between four 7-segment displays.
In our circuits, the signals driving our
transistors’ base (B) control terminals
come (via current-limiting resistors)
from the Arduino. In the case of an NPN
transistor used, as in Fig.7(c), 0V on
its base will switch it off (like opening
a switch), thereby disconnecting the
display’s common cathode pin from
the 0V rail and ensuring all the display
segments are off.
By comparison, a 5V signal on the base
resistor will switch the transistor on (like
closing a switch), thereby connecting
the display’s common cathode pin to
the 0V rail and activating any segments
with 5V on their anode terminals.
If we wished to perform similar experiments with a common-anode display, we would use a PNP transistor
as illustrated in Fig.7(d). In this case,
we might opt for a BC327 (there are, of
course, many other candidates for the
job). This works in a complementary
fashion to its NPN counterpart.
In this case, a 0V signal applied to
the transistor’s base resistor will switch
it on, thereby connecting the display’s
common anode pin to the 5V rail and
activating any segments with 0V on
their cathode terminals. By comparison,
a 5V signal applied to the transistor’s
base will switch it off, thereby disconnecting the display’s common anode
pin from the 5V rail and ensuring all
the display segments are off.
Want an easy way to remember which
symbol is which? Refer to the direction
of the arrow at the transistor’s emitter
terminal:
NPN = Not Pointing iN
PNP = Point iN Please
DIY or off the shelf?
Finally, we are ready to add a BCD to
7-segment decoder to our circuit (Fig.8).
In this case, we are going to employ
the simplest form of BCD code, known
as Natural BCD (NBCD), Simple BCD
(SBCD) or 8421 BCD (see last month’s
column for more on this).
We’ve changed from using uppercase
letters A, B, C, D, E, F, G to lowercase a,
b, c, d, e, f, g to refer to the segments on
our 7-segment display. This is because
we are now using the uppercase A, B,
C, D characters to refer to the inputs to
our BCD decoder. It’s not my fault; I’ll
explain more in a moment.
When it comes to implementing our
BCD decoder, we have a choice: DIY
(do it yourself) or off the shelf. By DIY,
I mean that, similar to how we realized
our 2:4 decoder, we could use a bunch
of primitive logic gates (NOT, AND,
OR, etc) to implement it. We’d start
by thinking of the decoder as a black
box, then create a truth table showing
the gazins and gazouts. Next, we’d use
techniques like Boolean algebra, De
Morgan transformations and Karnaugh
maps to determine which logic gates
to use.
Once again, all of this is discussed
in Bebop to the Boolean Boogie. The
No connection
Connection
D3
Ground (0V)
D2
D0
D1
Display segments
and pin numbers
5 10 9 1 2 4 6 7
dp g f e d c b a
3
3
3
3
C
C
C
C
B
B
E
B
E
Fig.8: Adding a BCD-to7-segment decoder.
B
E
y3 y2 y1 y0
Unused
g
f
e d c b a
8421 BCD Decoder
2:4 Decoder
s1 s0
Free
13 12
E
D C B A
Free
11 10
9 8 7 6
5 4 3 2
Arduino pin numbers
49
B
1
16
VCC
C
2
15
f
?
3
14
g
?
4
13
a
?
5
12
b
D
6
11
A
7
GND
8
From
Arduino
Inputs
Decimal
D
C
B
0
L
L
1
L
L
2
L
L
3
L
L
c
4
L
H
10
d
5
L
9
e
6
L
7
To
Displays
Fig.9: A top view of the 74LS48N package.
problem is that this would take time
and effort and I’m feeling lazy today.
The alternative is to use an off-the-shelf
part like the SN74LS48N. I just found
a pack of 10 for £5 on Amazon’s UK
website (https://pemag.au/link/abzj),
but you can get these little scamps from
any major component supplier.
As we discussed in an earlier column
(PE, August 2024), the “SN” indicates
that Texas Instruments (TI) is the manufacturer, the “74” tells us we are working with a commercial component (as
opposed to industrial or military), the
“LS” informs us that this is a member
of the Low-Power Schottky family, the
“48” is the type of logic function (a BCD
decoder), and the “N” indicates it is in
a plastic dual in-line package (PDIP).
Data sheet deliriums
It’s when we come to cast our orbs
over the data sheet for the 74LS48 that
things have the potential to get a little
confusing (https://pemag.au/link/abzk).
Whoever was charged with creating the
original version of this little rascal back
in the 1970s was overly enthusiastic
because they made it their mission to
cover a wide variety of parts, packages
and functions in this one document.
We are focusing on the 74LS48 because this device is intended to drive
a common-cathode 7-segment display,
which means its outputs are active-high.
Its 74LS47 counterpart, also embraced
by the same data sheet, has activelow outputs and is designed to drive
a common-anode 7-segment display.
Based on this data sheet, a representation of the 16-pin package we’re using
is presented in Fig.9. This explains
why we transitioned to using A, B, C, D
characters for the inputs to the decoder
and a, b, c, d, e, f, g characters for the
signals driving our 7-segment displays.
Outputs
A
a
b
c
d
e
f
g
L
L
H
H
H
H
H
H
L
L
H
L
H
H
L
L
L
L
H
L
H
H
L
H
H
L
H
H
H
H
H
H
H
L
L
H
L
L
L
H
H
L
L
H
H
H
L
H
H
L
H
H
L
H
H
H
H
L
L
L
H
H
H
H
H
L
H
H
H
H
H
H
L
L
L
L
8
H
L
L
L
H
H
H
H
H
H
H
9
H
L
L
H
H
H
H
L
L
H
H
10
H
L
H
L
L
L
L
H
H
L
H
11
H
L
H
H
L
L
H
H
L
L
H
12
H
H
L
L
L
H
L
L
L
H
H
13
H
H
L
H
H
L
L
H
L
H
H
14
H
H
H
L
L
L
L
H
H
H
H
15
H
H
H
H
L
L
L
L
L
L
L
Fig.10: The 74LS48 truth table.
The GND pin (pin 8) connects to the
0V ground rail on our breadboard, while
the VCC power pin (pin 16) will connect
to the +5V power rail. The “?” for pins 3,
4, and 5 is because we will consider the
functioning of these pins next month.
For the moment, we simply use a 10kΩ
resistor to disable these pins by pulling
them up to logic 1 (the 5V rail).
A cut-down version of the truth table
from Table T2 in the data sheet is shown
in Fig.10 (we’ve omitted pins 3, 4, and 5).
In our previous columns, we’ve predominantly used 0s and 1s in our truth
tables (along with occasional “X” characters to indicate ‘Don’t Care’ values on
the inputs and “?” characters to indicate
‘Don’t Know’ values on the outputs).
In the past, it was not uncommon
to use “L” and “H” instead of 0 and 1,
respectively. I’m continuing to use “L”
and “H” here to match the data sheet
and because you might run across this
sort of thing in the future.
Although this isn’t a concern here,
it’s worth noting that some truth tables
might have “OFF” and “ON” values for
their outputs. Oftentimes, this is because
the creators of the data sheet were trying
to cover multiple device variants, some
with active-high outputs and others with
active-low outputs. Using “OFF” and
“ON” values allows one truth table to
cover both implementations.
One final point of interest from our
truth table arises when we consider the
numerical designations and resultant
displays illustrated in Fig.11.
The numbers 0 through 9 are displayed as we would expect, but what
about 10 through 15? We introduced
hexadecimal (base 16) in PE, May 2023.
Did the designers of this device miss
their opportunity to come up with a
hexadecimal display? Well, yes and no.
On the one hand, many people in the
computer industry used only octal (base
8) and decimal (base 10) notations into
the late 1970s and early 1980s, and the
octal characters (0 to 7) form a subset
of the decimal characters (0 to 9). On
the other hand, starting in the early
1960s, it became increasingly common
to use hexadecimal (base 16) notation.
So displaying the hex A, B, C, D, E, F
characters would almost certainly have
been considered by its designers.
The telling point here is the fact that
number 15 corresponds to all the segments being off. That is useful if we wish
to blank leading zeros on a multi-digit
display. We introduced this concept
in PE, August 2024, and we will be
discussing it in more detail next month.
That leaves us with the displays corresponding to numbers 10 through 14.
Were these cryptic segment patterns
carefully selected by the device’s designers? Do they have some long-forgotten
meanings? Personally, I doubt it. I guess
that the designers focused on getting
the displays they desired for numbers
0 through 9, along with the blank (all
segments off) corresponding to number
15, leaving the displays corresponding
to numbers 10 through 14 to fall out as
they might (I’d love to hear if you have
another theory or know something to
the contrary).
Preparing to add the BCD decoder
Before we add the 74LS48 BCD decoder to our breadboard, let’s remind
ourselves as to the current state of play.
As usual, you can download a PDF of
our latest and greatest breadboard, component, and wiring ensemble (file “CBOct24-01.pdf”).All the files mentioned
in this column are available from the
October 2024 page of the PE website:
https://pemag.au/link/abzl
To make sure everything is still working before making any changes, let’s load
and run our most recent program, which
displays the time while suppressing any
leading 0 in the most-significant (left-
a
f
g
e
b
c
d
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Fig.11: Segment identification, numerical designations and resultant displays from the 74LS48 data sheet.
50
Practical Electronics | October | 2024
Bringing-up the BCD decoder
Based on our previous experiences of
things not always working as planned
the first time around, we will take things
step by step.
Practical Electronics | October | 2024
dp
g f e d c b a
To Displays
dp
g f e d c b a
Upper Breadboard
74LS48
16
15
14
13
12
11
10
9
390Ω
Lower Breadboard
Breakout board
1
2
3
4
5
6
7
8
Resistor pack
f g a b c d e
74LS48
BC? ? ?DA
9 8 7 6 5 4 3 2
(a) Without BCD decoder
5 4 3 2
From Arduino
(b) With BCD decoder
Fig.12: Adding the BCD decoder chip to our breadboard.
followed by a red wire from pin 16 (VCC)
First, unplug the USB cable from
your Arduino to power it down. While to the upper +5V power rail. Also, add
working on an antistatic mat and wear- the 0.1µF (100nF) ceramic capacitor
ing an antistatic wrist strap, discon- and the 10kΩ pull-up resistor, along
nect the breadboard ends of the wires with the three purple wires connected
connected to pins 2, 3, 4, and 5 on the to pins 3, 4, and 5.
Now reconnect the USB cable from
Arduino. Also, completely remove the
wires connected to
(a) Add 74LS38
(b) Connect Arduino
pins 6, 7, 8, and
9 on the Arduino.
Now replace the
original 150Ω BOB
with your new
390Ω BOB or resistor pack on the
upper breadboard
(remember to con74LS48
74LS48
nect pin 1 on the
resistor pack/BOB
to ground).
Next, add the
SN74LS48 IC to
the lower breadboard, as in
Fig.13(a). Also add
Logic probe connection point
a black wire from
From Arduino
5 4 3 2
pin 8 (GND) to the
Fig.13:
Upgrading
our
breadboard
one
step
at a time.
lower ground rail,
Lower Breadboard
most) digit (file “CB-Oct24-02.txt”). If
everything is working as expected, we
can proceed.
The area of interest to us with respect
to our existing implementation sans BCD
decoder is illustrated in Fig.12(a). As you
will recall, since we are multiplexing
our displays, this allows us to connect
the LED segments from all four displays
in parallel (side-by-side). We’re using
digital output pins 2 through 9 from
the Arduino to drive display segments
‘a’ through ‘f’ and the decimal point
(‘dp’), respectively. We are currently
using eight 150Ω discrete (individual)
current-limiting resistors mounted on
a small breakout board (BOB). We discussed its creation in PE, July 2024.
Now we will swap out the currentlimiting resistors with new values and
add the BCD decoder as illustrated in
Fig.12(b). From previous columns we
know the red LEDs in our 7-segment
displays have a forward voltage drop
(VF) of 2V and a maximum forward
current (IF) of 20mA (we discussed the
concept of a diode’s forward voltage
drop in PE, March 2024).
The data sheet for the 74LS48 states
that the maximum current each output
can provide is only 6mA, so that is what
we have to work with.
Remember that we have NPN transistors in series with each of our displays.
These have a ‘saturation voltage’ that
appears across them when they are
switched on, usually a fraction of a volt.
This means that we end up with only
about 5V – 2V – 0.5V = 2.5V driving
each LED. Using Ohm’s law of V = I × R
and rearranging the terms to give R = V
÷ I, we end up with R = 2.5V ÷ 0.006A
= 416Ω. The closest standard value to
this is 390Ω, which is close enough.
You can either build a new BOB or
do what I did, which is to use a 16-pin
package containing eight isolated 390Ω
resistors. These components are created
by a variety of manufacturers, like the
Bourns 4100R Series (https://pemag.au/
link/abzm), and they are available from
most major component vendors, like
DigiKey (https://pemag.au/link/abzn).
Since we can’t control the decimal
point (‘dp’) segments on our 7-segment
displays using our BCD decoder, we
will connect pin 1 of the resistor pack
to ground, thereby disabling these segments. Also, we’ve used a 10kΩ pull-up
resistor to ensure that pins 3, 4, and 5 on
the 74LS48 are in their inactive states
(we will consider the functioning of
these pins next month).
51
Main breadboard
Logic analyzer breadboard
Listing 3a: Our pin declarations for testing.
74LS48
B
C
A
D
D
C
B
A
5 4 3 2
Fig.14: Connecting our LED-based logic analyser to the 74LS48 IC.
your host computer to your Arduino.
Don’t worry if your 7-segment displays
are glowing dimly or showing spurious values. This is because we have
not yet connected the outputs from
the SN74LS48 to the ‘inputs’ of the
current-limiting resistors.
As we previously discussed (PE,
August 2024), use your digital multimeter to ensure we have 5V (or thereabouts) between pin 8 and pin 16 on
the IC (apply the multimeter’s probes
directly to the IC’s pins). Next, leave
the black probe on pin 8 and use the
red probe to ensure we see the same 5V
(give-or-take) value on pins 3, 4, and 5.
So far, so good. Remove the USB cable
to power everything down again, then reconnect the breadboard ends of the wires
from pins 2, 3, 4, and 5 on the Arduino
as illustrated in Fig.13(b). Observe that,
the way we’ve wired things, inputs A,
B, C, D on the 74LS48 (pins 7, 1, 2 and
6, respectively) are connected to pins
2, 5, 4, 3 on the Arduino, respectively.
Don’t panic. I know we haven’t connected the outputs from the BCD decoder
yet. For the moment, we are going to
focus on its inputs. Wrapping one’s
brain around all of this (which pins
correspond to which signals and wires)
can require some mental gymnastics. So,
before we do anything else, we need to
make sure we know what we’re doing
and that we are controlling things the
way we want to control them.
To help with this, we’re going to use
four of the probes on the logic analyser
board we constructed earlier (PE, August
2024), as illustrated in Fig.14. Don’t
forget to connect the logic analyser’s
upper power and ground rails to their
counterparts on the main breadboard.
Before we power everything up, let’s
52
first create a small test program to make
sure we are talking to the BCD decoder
in a language it understands (file “CBOct24-03.txt”). As usual, we won’t go
through everything here – we’ll just hit
the highlights.
As you’ll see when you look at the
code, we are using variables of type int
(integer) to represent our BCD values.
Integers are stored as 16-bit values in
the Arduino Uno, but we will be using
only the four least-significant bits to
represent values 0 through 9 in decimal
(0000 through 1001 in binary). As part
of this, we define
pins driving our BCD decoder are outputs and set them LOW also. Last, but
not least, we assign a value of 0 to our
ValBcd variable.
The main part of our test program is
shown in Listing 3b. Let’s start with the
new function called DisplayBcd(),
into which we pass the BCD value we
wish to display. This works similarly
to the DisplaySegs() function we’ve
been using to drive our displays directly.
We described this in detail in PE, April
2023. All we need to note here is that
our new function will present bits 0, 1,
2, and 3 of our BCD value to Arduino
pins 2, 5, 4, and 3, respectively.
Finally, we have the loop() function,
which is as simple as simple can be. It
starts on Line 40 by calling our new
DisplayBcd() function to display
the current value stored in ValBcd.
On Line 41, we pause for ON_TIME,
which we’ve set to one second. On
Line 42, we increment the value stored
in ValBcd. The use of the modulus/
integer remainder (%) operator means
our count will follow the sequence 0, 1,
2, 3, 4, 5, 6, 7, 8, 9 and back to 0 again.
OK, let’s power up our Arduino
and then load and run our test program. Changing each second, our logic
analyser LEDs should reflect the binary
NUM_BCD_BITS
to be 4.
We declare a
global integer
variable called
V a l B c d (think
“BCD value”). We
also declare an
array of integers
called PinsBcd[]
to store the numbers of the Arduino
pins we wish to
use to drive our
BCD decoder. This
declaration is illustrated in Listing 3a.
In the setup()
function, we specify that the pins
driving our 2:4
decoder are outputs and we set
them both to LOW,
thereby selecting
display D0 (which
we will be using a
little later). Next,
we specify that the Listing 3b: The body of our test program.
Practical Electronics | October | 2024
Inputs to BCD
Components from Part 1
0
LEDs (assorted colours)
Resistors (assorted values)
Solderless breadboard
Multicore jumper wires (male-to-male)
1
Components from Part 2
2
7-segment display(s)
ValBcd
D
C
B
A
3
Momentary pushbutton switches
Components from Part 6
5
Passive piezoelectric buzzer
6
Components for Part 9
Components for Part 10
8
Breadboard mounting trimpots
9
Components for Part 12
https://amzn.to/3KmxjcX
https://bit.ly/46SfDA4
https://bit.ly/3QAuz04
Light-Dependent Resistor
Fig.15: The expected logic analyser display.
Components for Part 13
counting sequence depicted in Fig.15.
If not, return to the instructions above
and recheck the wiring.
Once you have this working, power
everything down, then add the wires
connecting the outputs from the BCD
decoder to the inputs of the currentlimiting resistors, as illustrated in
Fig.12(b).
As usual, you can download a PDF
showing our new BCD-based breadboard
setup in its entirety (file “CB-Oct24-04.
pdf”). When you return power to the
Arduino, you should see the values 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0… appear on
display D0.
Components for Part 14
Practical Electronics | October | 2024
https://amzn.to/3Tk7Q87
SW-18010P vibration switch
7
Finally, it’s time to bring everything
together. We’re going to take our old nonBCD clock program (file “CB-Oct24-02.
txt”) and the BCD test program we just
created (file “CB-Oct24-03.txt”), and
“munge” them together to create a new
BCD-based clock program.
Why don’t you do this yourself to
make sure you are totally on top of
things? If you run into any problems,
you can compare your solution to mine
(file “CB-Oct24-05.txt”).
OMG, it works! (I mean, I never doubted us for a minute...)
You may notice that the 7-segment
displays do not appear as bright as they
used to be. There’s a reason for this,
which is that they’re not as bright as
they used to be. Previously, we were
using 150Ω current-limiting resistors
to drive the displays with 20mA. Since
we were multiplexing four displays,
each display was on for only 25% of the
time. That meant each display used to
receive 20mA for 25% of the time and
0mA for 75% of the time, averaging out
at 5mA per display.
https://amzn.to/3Afm8yu
Components from Part 5
4
All together now!
https://amzn.to/3E7VAQE
https://amzn.to/3O4RvBt
https://amzn.to/3O2L3e8
https://amzn.to/3O4hnxk
https://bit.ly/3S2430m
BC337 NPN Transistor
https://bit.ly/40xAgyS
HC-SR04 Ultrasonic Sensor
https://bit.ly/49AMBq4
Components for Part 15
Real-Time Clock (RTC)
https://bit.ly/3S9OjHl
Components for Part 18
Long tailed (0.1-inch/2.54mm pitch) header pins
https://bit.ly/3U1Vp2z
Components for Part 19
Prototyping boards
Kit of popular SN74LS00 chips
https://bit.ly/3UMkcZ1
https://bit.ly/3wqgzyv
Components for Part 20
16V 100µF electrolytic capacitors
Ceramic capacitors (assorted values)
https://bit.ly/44LzpNa
https://bit.ly/4bEAUiv
Components for Part 22
SN74LS48N BCD Decoders
16-pin resistor pack (8 × 390Ω)
Now, due to our 74LS48 BCD decoder’s outputs being limited to only 6mA,
we’ve changed our current-limiting
resistors to 390Ω, so each display is
seeing an average of only 1.5mA, which
explains why they appear dimmer now.
Blowing one’s own flügelhorn
Modesty forbids me from being boastful. Happily, members of the PE community are usually pleased to oblige.
For example, I just received an email
from a reader we will call Ian (because
that’s his name). He wrote:
Dear Max, I have to get this boast in
while acknowledging that I’ve obviously
learned lots from you over the last year
and a half. Some time ago, I bought a
set of 4-digit, 7-segment displays from
AliExpress.
The problem was the unit is common
anode. I am quite proud of myself as I
was able to work out which transistors
to use. Also, which resistors for both
the LEDs and the transistor base. I’m
https://bit.ly/3zT18jx
https://bit.ly/4d0ISDz
happy to report that it worked first time
(that’s a first)!
It was the “I’ve obviously learned
lots from you over the last year and
a half” portion of this message that
caught my eye. My mother will be
so proud. We always suspected that
someone other than her was reading
these columns. Now we know his
name!
Next time
In our next column, we will dive
deeper into the functioning of the
74LS48 decoder.
After that, we will introduce a different BCD decoder integrated circuit
that will better serve our needs, including addressing our lack-of-brightness
issue.
Until that frabjous day, if you have any
thoughts you’d care to share, as always,
I welcome your insightful comments,
penetrating questions, and sagacious
PE
suggestions.
53
|