This is only a preview of the March 2025 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:
Articles in this series:
Items relevant to "Mains Power-Up Sequencer, part two":
|
Max’s Cool Beans
By Max the Magnificent
Weird & Wonderful
Arduino Projects
Part 3: building a 14 × 10 tricolour LED array
H
ello once again. I can’t believe
it’s March already! It seems
like every time I blink, another
day slips by and every time I sneeze,
a month zips past. But enough of my
ramblings.
I’m currently quivering in anticipation of what is about to unfold. We
are poised to take the strip of 144 tricolour light-emitting diodes (LEDs)
that we introduced in our previous
column and use it to build the 14 × 10
array that will form our retro games
console’s main display.
Even if you aren’t planning on building one of these beauties yourself (I
have no idea how you could resist
the temptation), you can still follow
along with the rest of us because we’ll
be learning all sorts of useful tips and
tricks along the way.
When working with semiconductor
devices like integrated circuits (ICs)
and LEDs, it’s important to do everything on an anti-static mat while also
wearing an anti-static wristband. This
was discussed in excruciating exhilarating detail in PE, January 2023.
Rows and columns
Almost immediately, we are faced
with a choice. Should we refer to our
main LED display as being a 10 × 14
array (height × width) or as a 14 × 10
array (width × height)?
In some fields, particularly mathematics and computer science (and
in programming contexts), arrays and
matrices are often described by the
number of rows and columns, which
translates to height × width. However,
when looking at an image or a screen,
our visual intuition is to think of its
horizontal span (width) before its vertical span (height) because we read
left-to-right, top-to-bottom.
When we come to writing our programs, we’re going to be describing
things in terms of their (x, y) coordinates. The main thing is for us to be
clear and consistent; we will employ
the (x, y) or W × H notation henceforth.
Chop chop
To make our discussions easier, we
will refer to each of our tricolour LEDs
as ‘pixels’ (an abbreviation of “picture elements”). Let’s start by taking a
slightly closer look at our strip (Fig.1).
You should see white arrows indicating the direction of data from the input
of each pixel to its output, and from
Pixel 0
Pixel 1
that output to the next pixel’s input.
There are three copper pads between
adjacent pixels. One is for 5V, one for
0V, and one for data. There are also
copper wires inside the strip that aren’t
visible from the outside. I’ve used red
and blue lines to show the 5V and 0V
rails on the strip in Fig.1, because this
will facilitate our discussions later.
However, real strips don’t have these
lines. Instead, they show ‘+’ and ‘–’
characters, respectively.
I think of the strip as having an ‘input
end’ (shown here) and an ‘output end’.
For our initial experiments last
month, we connected a 390Ω resistor
(with orange, white and brown bands)
in series with the data input as close
to the strip as we could. This protects the first pixel in the chain from
the Arduino’s enthusiastic switching
speeds that can cause overshoot and
undershoot on this signal if we’re not
careful.
Originally, we employed red (5V),
white (0V) and green (data) wires for
the signals feeding the strip, matching the colour scheme of the connector already attached to the strip. I’ve
moved to showing red (5V), black
(0V) and yellow (data) wires in Fig.1
because that is what I’m using in my
console implementation, so that is
what we will see in the photos I’ll
be showing.
0V
From
MCU
Our
gracious
host.
390Ω
5V
Copper Pads
Fig.1: a close look at the strip.
32
Practical Electronics | March | 2025
(0,9)
(13,9)
(0,9)
(13,9)
(0,9)
(13,9)
From
MCU
:
From
MCU
(0,0)
(13,0)
(a) Raster
(0,0)
(13,0)
(b) Serpentine
(0,0)
(13,0)
(c) Reverse serpentine
Fig.2: different ways of connecting our segments together.
Remember that our strip contains
144 pixels. We want to cut this into 10
segments, each containing 14 pixels.
Even my poor maths informs me that
this will leave us with four pixels
left over.
Before you start cutting with gusto
and abandon (and aplomb, of course),
check your strip carefully, looking for
a join somewhere in the middle. In
my case, there was no join (hooray!).
I started cutting my 14-segment sections from the output end of my strip.
Why? When I’d finished, this left me
with a four-pixel strip that was still
attached to my wires and resistor from
last month. I can use this for future
experiments.
What if you do have a join in the
middle? This happened to my friend
Joe Farr, who has already built a prototype of our console. Joe was lucky.
His join occurred 44 pixels in from the
output end of his strip, so he could cut
three 14-pixel segments, then a 4-pixel
chunk with two pixels on either side
of the join, then continue to cut the
remaining segments.
Things may be a little trickier if you
have a join that prevents you from obtaining 10 ‘clean’ 14-pixel segments.
Is this really a problem? Possibly not.
It depends on how you intend to construct your console.
It may be you are planning on
mounting everything onto something
like a sheet of hardboard or plastic.
I thought that a cheap-and-cheerful
clipboard could do the job (https://
pemag.au/link/ac3i). In this case, the
fact that a couple of your pixels are a
little closer together—or, more likely,
a little farther apart—won’t matter
all that much in the grand scheme
of things.
On the other hand, if you are going
for a full Monty implementation with
a laser-cut front panel, you will need
all your pixels to be evenly spaced
and precisely aligned. In this case,
you have only two options if your
strip has an awkward join: (1) desolPractical Electronics | March | 2025
der, trim and re-solder the join until
things are as close as you can get or
(2) buy a second strip and use this to
source the missing segment.
I used my trusty side cutters for the
actual cutting. This may be a good time
to note that I recently penned a threecolumn mini-series titled The Beginner’s Guide to Electronics: Tools—What
to Buy First, and I covered cutters in
Part 2 (https://pemag.au/link/ac3j).
The copper pads are very small, so
you need to be careful to cut them as
close to the middle as possible. You’ll
also find that solder attaches better to
these pads if you first deoxidise them
by gently abrading (scuffing) them
with fine-grit sandpaper.
My seemingly cunning plan
Let’s assume that we have our ten
segments sitting in front of us. The
next question is how we are going to
connect these together. Three possibilities (out of many options) are illustrated in Fig.2.
Remember that our 140 pixels are
numbered from 0 to 139. At a low level
in our program, pixel 0 will always
be the one being driven by the Arduino, with the numbers increasing
sequentially based on how the segments are joined.
By comparison, from our perspective, looking at the front of our console, we are going to view our array
in terms of (x, y) coordinates. We
are going to employ a ‘bottom-left’
origin system, in which (x, y) = (0, 0)
is in the bottom-left corner. This is
standard in mathematics and Cartesian plane graphing, where positive
x values extend to the right and positive y values extend upward.
We should probably note that computer graphics, screen displays and digital
imaging applications often use a ‘topleft’ origin system. In this case, (x, y) =
(0, 0) would be in the top-left corner, x
would increase to the right as before,
while y would increase downward.
When Joe wired his array, he opted
to use what we might call a “raster”
scheme, as shown in Fig.2(a). One
advantage of this scheme is that all
the segments are orientated in the
same way, so the power and ground
connections are in the same place for
each segment. One disadvantage is
the longer data signal wires required
to connect the segments.
An alternative would be to use the
“serpentine” scheme shown in Fig.2(b).
The advantage of this scheme is the
shorter data signal wires required to
connect the segments. The disadvantage is that adjacent segments are reversed compared to each other. This
is illustrated by the alternating positions of the red (5V) and blue (0V)
lines on the strips.
I dare to be different. My plan was
so cunning that we could have pinned
a tail on it and called it a weasel, as
Black Adder might say. I decided to
use the “reverse serpentine” scheme
illustrated in Fig.2(c). In this case,
unlike the other two schemes, pixel 0
is at (x, y) = (13, 9) rather than (0, 0).
This turned out to be a not-socunning plan, more like something
Baldrick would come up with. The
only advantage of this scheme (and
I’m clutching at straws here) is that
it will provide an important lesson
in a moment.
In many respects, it really doesn’t
matter how we decide to connect our
segments, so long as we follow a regular repeating pattern. We can use
our software to sort out the mapping
of virtual (x, y) pixels to the physical
pixels in our string later.
Attaching the segments
The strip of tricoloured LEDs I purchased came equipped with doublesided tape on the back. I’m assuming
your strip is similarly endowed. If not,
you’ll need to attach some double-
sided tape yourself, or you might opt
for another attachment method like
hot-melt glue.
As we previously discussed, you
may decide to attach your segments—
along with everything else comprising
the console—to a sheet of hardboard
or plastic. Alternatively, you may opt
to use a laser-cut front panel and a 3Dprinted case, or you might choose to
do something in between.
I’ll explain what I did; it’s up to you
to decide whether to follow my lead
or to go your own way.
I was lucky because, when Joe was
creating his prototype, he fabricated
some extra bits and pieces, which
he kindly donated to the cause (that
would be me).
First, Joe provided me with a white
laser-cut panel as seen in the centre
33
Photo 1: the inner fascia (left), mounting panel (center), NeoPixel segments (right) and joining hardware (bottom).
of Photo 1. This is the base to which
I’m going to attach my segments. Observe the four mounting holes in the
corners. In the fullness of time, we
will use these to attach this board to
the main fascia (front panel).
Next, observe the small black laser-
cut ‘inner fascia’ panel shown on the
left in Photo 1. We’ll discuss the actual
purpose of this panel later. For the
moment, we’re going to use it to align
our segments, which you can see on
the right in Photo 1.
Below the inner fascia in Photo 1, we
see a few sample pieces from a printed
circuit board (PCB) spacer kit. I just
found a nice kit on Amazon (https://
pemag.au/link/ac3k). This is an M3 kit,
which means the nuts, bolts (machine
screws) and pillars are metric with a
nominal diameter of 3mm. M2.5 kits
are also available. I usually opt for M3,
but it’s your call what you use.
The reason I mention these spacers
here is that, if you look closely at the
photo of the inner fascia, you can see
that I’ve inserted four machine screws
in the four mounting holes in the corners. In the not-so-distant future, we’re
going to use these screws to align the
white board with the segments.
Next, we need to lay out our segments
to match the ordering shown in Fig.2(c)
(or whichever scheme you choose to
use for your console), after which we
flip them over and lay them on top of
the inner fascia. Do this such that the
pixels on the strips slot into the holes
in the inner fascia. This leaves everything looking as shown in Photo 2.
Finally, we remove the blue backing from the double-sided tape, after
which we drop the white panel over
the four machine screws in the corners
and press down gently, but firmly, to
ensure the segments attach to the panel.
34
Segment data wiring
When we remove the white board, all
the segments should be attached, but
it won’t hurt to run a finger along each
segment pressing gently down on each
pixel to ensure good, tight contacts.
The next step is to wire everything
up as illustrated in Photo 3. Once
again, your wiring will depend on the
scheme you choose to use from Fig.2
(or some other arrangement of your
own devising). I started with the green
wires connecting the data signals between segments.
I could have used regular multi-core
wire for this, but the green wires in a
single-core wire jumper kit were the
perfect size. I just found a similar kit on
Amazon (https://pemag.au/link/ac3l).
The colours of the wire lengths in that
kit may be different to those in mine.
One point worth noting at this stage
is that the bulk of the wiring takes
place behind the board. Joe had located the holes for the wiring centred on
his segments, which worked well for
his connection scheme, as per Fig.2(a).
In the case of my not-so-cunning connection arrangement per Fig.2(c), my
green solid jumper wires obstructed
these holes. I would have been better
off with holes between the segments. I
could have easily added these myself, but
I didn’t realise there was a problem until
after I’d soldered my green wires (rats!).
Segment power wiring
Next, we need to connect our red
(5V) and black (0V) wires. What gauge
(diameter) wires should we employ
for this? This depends on how much
current we intend to use. The data
sheet states that each of the red,
green and blue LEDs in each pixel
has a maximum forward current of
20 milliamperes (20mA), giving a
maximum possible current draw of
60mA per pixel.
If we were to drive all our pixels fullon, this would equate to 140 × 60mA
= 8400mA = 8.4A. Eeek!
We will delve deeper into this
topic in next month’s column. For
the moment, let’s just say that we are
Photo 2: using the inner fascia to align the segments.
Practical Electronics | March | 2025
going to limit our current draw to a
maximum of 10mA per pixel. Based on
this, we know that each of our segments
will draw only 14 × 10mA = 140mA.
We are going to use multi-core wire
for this task because it’s nice and flexible. A quick Google search reveals that
24 AWG (0.5mm diameter copper) wire
can carry 1A, 22 AWG (0.65mm diameter copper) can carry 1.5A and 20 AWG
(0.8mm diameter copper) can carry 2.5A.
In the AWG (American Wire Gauge)
system, smaller numbers represent larger
diameters due to the historical method
used for wire manufacturing. The gauge
number reflects how many turns of wire
will fit on a rod of a certain length.
I opted to use 22 AWG (0.65mm) wire
to attach to the segments themselves,
but 24 AWG (0.5mm) would also have
been OK. If you aren’t already in possession of suitable wires, you could do
worse than getting a kit containing a
selection of different colours, like the
one I just found on Amazon (https://
pemag.au/link/ac3m).
Since our segments have only 14
pixels, we don’t need to concern ourselves with the voltage drop, so I decided it would make my life easier if
I connected the black (0V) wires on
the left and the red (5V) wires on the
right. Don’t forget that the relative positions of these wires will be flipped
between adjacent strips if you opt for
a connection scheme like those shown
in Fig.2(b) & (c)!
Photo 3: wiring up the NeoPixel LED strip segments.
Keeping everything tidy
Now, let’s look at the back of the
board, as seen in Photo 4. We know
that the maximum current for each
segment will be 140mA. This means
the maximum current if all ten segments are fully on will be 10 × 140mA
= 1400mA = 1.4A. On this basis, we
could use our 22 AWG (0.65mm) wire
with its 1.5A capacity to gather all our
segment wires and connect them to the
main power supply.
On the other hand, it’s better to be
safe than to be sorry, so I opted to use
20 AWG (0.8mm) wires (https://pemag.
au/link/ac3n) with their 2.5A capacity
for this purpose. These are the single
red and black wires exiting Photo 4
on the right.
Observe that the soldered joints where
these wires connect with the bunch of
wires connected to the segments are
covered and protected by heat-shrink
tubing (we mentioned this last month).
The small piece of yellow heat-shrink
tubing that appears in the bottom lefthand corner of Photo 4 is covering the
390Ω resistor that’s connected to the
data input of pixel 0 in my chain. The
other side of this resistor connects to
the 22 AWG (0.65mm) yellow wire we
can see exiting from the bottom righthand corner of Photo 4.
Since the yellow wire is carrying
only a very low-current data signal,
almost any gauge of wire would do,
but 22 AWG is what I had on hand.
Having more current carrying capacity
than we need certainly doesn’t hurt.
Rather than leaving my wires to their
own devices, I created two wiring harnesses. That is, I bundled my wires together. I could have used cable ties but
I decided to revive an old-cable lacing
technique using waxed dental floss.
Besides making everything look nice
and neat, these harnesses help to provide strain relief for the connection
points where the wires are soldered
to the segments.
Speaking of voltage drops
Earlier, I used the term ‘voltage drop’.
This refers to the reduction in electrical potential (voltage) as current flows
through a component or a conductor
(like a wire) with resistance.
The resistance of a wire is a function
Photo 4: this split image shows how I tidied the wiring on the back of the 14 x 10 LED array board by tying the bundles of wires into looms.
Practical Electronics | March | 2025
35
But does it work?
You can bet your booty it does! I
took a copy of the second program that
we used to test our strip last month.
I changed the number of pixels from
144 (the full strip) to 140 (the number
of pixels in our array) and dropped the
RGB values from 255 to 32, which will
give us white light at only 12.5% of full
power (so we can see what it looks like).
(0,9)
(13,9)
You can download a copy of this code
in the file named CB-Mar25-Code-01.
txt. As usual, all the files mentioned
in this column are available from the
March 2025 page of the PE website:
https://pemag.au/link/ac3o
As before, I connected the red and
black wires from the array to the 5V and
GND (0V) pins on the Arduino. Remember that we’re powering our Arduino
via USB, which gives us 500mA. The
Arduino itself requires 50mA, leaving
us with 450mA to play with.
For the purposes of any experiments
we will perform in this column, we
will only ever activate a single row
of 14 pixels at 12.5% of their full
power, which means 14 × (60mA
× 0.125) = 105mA, so there are no
problems there.
Next, I connected the yellow wire
from the array to digital pin 12 on the
Arduino, because this is the pin we’re
using to drive the array in our program. Then I attached the USB cable
to power everything up, downloaded
my program into the Arduino and…
held my breath.
Things occasionally don’t work when
I power something up for the first time.
I’m usually poised to kill the power,
especially if I start to smell something
iffy. Then I moan and groan and set to
tracking down what I’ve done wrong.
Now and then, however, the Fates
smile upon me and it all works the
first time. This was one such occasion.
I still have a great big grin plastered
across my face!
We need a function
GetNeoNum()
x
y
(f)
n
Pixel 139
(0,0)
(a) First demo
(13,0)
(b) We need a
function
Fig.3: we need a function to convert (x, y) into a pixel number, n.
36
Now for an algorithm
Sad to relate, the segment connection scheme I’m using as depicted in
Fig.2(c) doesn’t make things as simple
as one might hope. I’m a visual person,
so the way I usually set about tackling
a problem like this is to start by creating a handy-dandy diagram like the
one shown in Fig.4.
In this case, the values in the boxes
represent the pixel numbers in the
physical string. Now that we are armed
with our trusty diagram, all that remains is to use it to derive a cunning
algorithm (somewhat above Baldrick’s
level of cunning this time).
Let’s start with a few definitions.
We might not use all of them, but I
The way I’ve connected my segments, as in Fig.2(c), means that the
first pixel in my physical string, pixel
0, is in the top right corner of my array
at (x, y) = (13, 9). Meanwhile, the last
pixel in my physical string, pixel 139,
is in the bottom right corner of my
array at (x, y) = (13, 0). This is illustrated in Fig.3(a).
Because of
this, our curColumns
rent test program starts
9 13 12 11 10 9 8 7 6 5 4 3 2 1 0
by lighting
8 14 15 16 17 18 19 20 21 22 23 24 25 26 27
the pixel in
From
MCU
Pixel 0
the top right corner. Then the lit pixel
races left and right as it works its way
down the array, following the path
(arrows) in Fig.3(a), until it conceptually falls off the end in the bottomright corner.
Now, suppose I want you to light
the pixel at (x, y) = (4, 2). All we need
to do is calculate that pixel’s number
in the physical string. Off you go; I’ll
wait here until you’ve finished.
Not that easy, is it? What we need
is a function that accepts the x and
y values of the desired location in
the array as inputs and returns the
number n of the pixel in the string as an
output. I use the term “Neo” to refer to
pixels in my programs because I always
think of these as being Adafruit’s Neo
Pixels. On that basis, we’re going to
call our function GetNeoNum( ) – see
Fig.3(b).
The great thing about this is that it
doesn’t matter if you organise your segments differently to mine. So long as
we both have GetNeoNum() functions
that work with our own arrays, and
whose external interfaces are identical, all you will need to do to run one
of my programs is to exchange my version of this function for yours.
7 41 40 39 38 37 36 35 34 33 32 31 30 29 28
6 42 43 44 45 46 47 48 49 50 51 52 53 54 55
5 69 68 67 66 65 64 63 62 61 60 59 58 57 56
y
4 70 71 72 73 74 75 76 77 78 79 80 81 82 83
3 97 96 95 94 93 92 91 90 89 88 87 86 85 84
2 98 99 100 101 102 103 104 105 106 107 108 109 110 111
1 125 124 123 122 121 120 119 118 117 116 115 114 113 112
0 126 127 128 129 130 131 132 133 134 135 136 137 138 139
0
1
2
3
4
5
6
7
8
9
10 11 12 13
x
Fig.4: this diagram shows the number for each pixel in my display.
Practical Electronics | March | 2025
Rows
of the resistivity of the material forming the wire and its length. The wires
on our strip are formed from copper,
which is an excellent conductor with
low resistivity.
The resistance is directly proportional to the length of the wire (the
longer the wire, the higher the resistance). It is also inversely proportional
to the cross-sectional area of the wire
(the greater the cross-sectional area,
the lower the resistance).
The voltage drop from one end of a
wire to the other is also a function of
the amount of current flowing through
that wire. To cut a long story short,
(which is opposite to the way I usually like to do things), if we took a onemeter LED strip and all the LEDs were
at 50% brightness, the voltage drop
from the input end to the output end
of the strip would be somewhere between 0.2V and 0.5V.
Alternatively, if all the LEDs were
at 100% brightness, the voltage drop
would be somewhere around 0.5–1.0V.
This means the LEDs would get
dimmer as we progressed down the
strip. For this reason, if we were powering a 1m strip, it would be a good
idea to connect 0V and 5V wires to
both ends.
Furthermore, if we were working
with a longer strip—say 10 meters—
we would adopt a ‘power injection’ approach. Specifically, we’d inject (connect) power (5V) and ground (0V) to
the strip every metre or so.
In our case, since our segments are
only 10cm long, and we are planning
on running our pixels at a maximum
of 10mA (which is only 16% of their
maximum brightness), we don’t need
to really be concerned with the voltage drop (phew!)
GetNeoNum( ) function is easy peasy
lemon squeezy: n = (y × NUM_COLS)
+ x (seriously, that’s all there is to it!).
We will discuss all this in more detail
next month, but for now we have other
poisson à frire (“fish to fry”).
Testing times
Listing 2(a): the first iteration of my GetNeoNum() function.
always find this is a useful way to
kick things off:
#define NUM_NEOS
#define MAX_NEO
#define NUM_ROWS
#define NUM_COLS
#define MAX_X
#define MAX_Y
140
139
10
14
13
9
As they say in America, this is not
my first rodeo. Since my segments alternate back and forth, I know I’m going
to need to treat the odd and even rows
differently. Let’s start with the lowest-hanging fruit in the form of row 0,
column 0, which equates to (x, y) = (0,
0). In this case, we want our function
to return a value of 126, which is 139
– 13. Hmm, that’s MAX_NEO – MAX_X.
Now let’s move to the next even row,
which will be row 2. Row 2, column 0
equates to (x, y) = (0, 2). In this case, we
want our function to return a value of
98, which is 139 – (2 × 14) – 13. That’s
MAX_NEO – (y × NUM_COLS) – MAX_X.
Similarly, if we look at row 4, column
0, which equates to (x, y) = (0, 4), we
want our function to return a value of
70, which is 139 – 13 – (4 × 14). Once
again, that’s MAX_NEO – (y × NUM_
COLS) – MAX_X.
Now, let’s return to row 0 but move
to column 1, which equates to (x, y) =
(1, 0). In this case, we want our function to return a value of 127, which is
139 – 13 + 1. That’s MAX_NEO – MAX_X
+ x. In fact, for any of the columns in
this row, all we need to do is subtract
13 from 139 and add our x value.
I think we’re onto something here.
We can generalise this to say that for
even rows, ie, even values of y, our
function should return MAX_NEO – (y
× NUM_COLS) – MAX_X + x.
Practical Electronics | March | 2025
Performing a similar treatment for
the odd rows, ie, odd values of y, our
function should return MAX_NEO – (y
× NUM_COLS) – x.
Before we do anything else, let’s take
our algorithm for a spin. Do you remember earlier when I told you I wanted
you to light the pixel at (x, y) = (4, 2)?
Since this is an even row, we can say
n = MAX_NEO – (y × NUM_COLS) –
MAX_X + x. That equates to 139 – (2
× 14) – 13 + 4 = 102, which is what
we’d expect from Fig.4. I’m performing my happy dance!
We can pick a few (x, y) values at
random with different mixtures of odd
and even values to verify that our algorithm works in all cases.
This is the point in the conversation
where Joe would point out the advantages of his scheme from Fig.2a. The
calculation inside Joe’s version of the
I just created a quick-and-dirty test
program that employs our new algorithm; you can find it in the file named
CB-Mar25-Code-02.txt. This features
the first iteration of my GetNeoNum( )
function as illustrated in Listing 2(a).
The listing number (2 in this case)
corresponds to part of the name of the
matching code file (“02” in this case).
Observe Line 55, where we use the
(y % 2) modulus operation. This operator returns the remainder from an
integral division. Since we are dividing by two in this case, the remainder
can only ever be 0 or 1, and we can use
this value to determine if y (the row) is
even or odd.
For my first test, I decided to light
all the pixels in each row in turn, starting with the bottom row and working
my way up to the top row. It’s very
important to remember that we are
currently powering our array from
our Arduino (this will change next
month), which means we only ever
want to have a single row of pixels illuminated at a time.
As we previously discussed, this will
draw 105mA. If we were to foolishly light
all 10 rows at the same time, then—even
though we’re running each pixel at only
12.5% of its maximum capacity—this
would equate to 1.05A, which would
give our Arduino a ‘bad hair day’.
The main loop() function in my test
program as illustrated in Listing 2(b).
In this case, the outer for() loop on Line
34 cycles through the rows. For each
Listing 2(b): the main loop() function in my test program.
37
row, the inner for( ) loop on Line 36
lights all the pixels on that row, waits
for a delay of ON_TIME, and then turns
the pixels off again before proceeding
to the next row.
Why don’t you try to come up with
a program that extends this first test?
For example, after lighting each row
in turn from bottom to top, we could
reverse things and light each row in
turn from top to bottom. Then we
could light each column in turn from
left to right, finally reversing it and
lighting each column in turn from
right to left.
I just created a suitable program, in
the file named CB-Mar25-Code-03.txt.
It looks great running on my array. I
cannot wait for you to see it running
on your array (send pictures!).
Next time
We have so much to look forward
to that I can barely contain my excitement. In our next column, we will start
by lighting the pixels in diagonal lines
across the display, one line at a time,
starting with the one-pixel ‘line’ in the
bottom left corner at (x, y) = (0, 0) and
ending in the top right corner at (x, y)
= (13, 9).
Next, we will move to powering our
array with something other than our
Arduino; something that will let us
light all the pixels at the same time if
we want to.
I must acknowledge that the current
implementation of my GetNeoNum( )
function is horribly inefficient, so we
will examine ways we can improve
this little scamp.
My head is already buzzing with
ideas and possibilities, but it would
be great if you could also start pondering ways in which we could make
the software better.
Also in our next column, we will
perform some additional breadboardbased experiments with the eight-segment LED we introduced in the January 2025 issue. These experiments will
Useful Bits and Pieces from Our Arduino Bootcamp series
Arduino Uno R3 microcontroller module
Solderless breadboard
8-inch (20cm) jumper wires (male-to-male)
Long-tailed 0.1-inch (2.54mm) pitch header pins
LEDs (assorted colours)
Resistors (assorted values)
Ceramic capacitors (assorted values)
16V 100µF electrolytic capacitors
Momentary pushbutton switches
Kit of popular SN74LS00 chips
74HC595 8-bit shift registers
https://pemag.au/link/ac2g
https://amzn.to/3O2L3e8
https://amzn.to/3O4hnxk
https://pemag.au/link/ac2h
https://amzn.to/3E7VAQE
https://amzn.to/3O4RvBt
https://pemag.au/link/ac2i
https://pemag.au/link/ac2j
https://amzn.to/3Tk7Q87
https://pemag.au/link/ac2k
https://pemag.au/link/ac1n
Other stuff
Soldering guide
Basic multimeter
https://pemag.au/link/ac2d
https://pemag.au/link/ac2f
Components for Weird & Wonderful Projects, part 1
4-inch (10cm) jumper wires (optional)
8-segment DIP red LED bar graph displays
https://pemag.au/link/ac2l
https://pemag.au/link/ac2c
Components for Weird & Wonderful Projects, part 2
144 tricolour LED strip (required)
Pushbuttons (assorted colours) (required)
7-Segment display modules (recommended)
2.1mm panel-mount barrel socket (optional)
2.1mm inline barrel plug (optional)
25-way D-sub panel-mount socket (optional)
25-way D-sub PCB-mount plug* (optional)
15-way D-sub panel-mount socket (optional)
15-way D-sub PCB-mount plug^ (optional)
https://pemag.au/link/ac2s
https://pemag.au/link/ac2t
https://pemag.au/link/ac2u
https://pemag.au/link/ac2v
https://pemag.au/link/ac2w
https://pemag.au/link/ac2x
https://pemag.au/link/ac2y
https://pemag.au/link/ac2z
https://pemag.au/link/ac30
* one required for each game cartridge you build
^ one required for each auxiliary control panel you build
Components for Weird & Wonderful Projects, part 3
22 AWG multicore wire kit
20 AWG multicore wire kit
include driving this device with one
of the SN74HC595 shift registers we
used in our Arduino Bootcamp series
(PE, December 2024).
So, over to you. If you have any
https://pemag.au/link/ac3m
https://pemag.au/link/ac3n
thoughts that you’d care to share on
anything you’ve read here, please
feel free to drop me an email at
max<at>clivemaxfield.com. Until next
PE
time, have a good one!
FIND ALL YOUR ELECTRONIC
COMPONENTS IN ONE PLACE
www.basicmicro.co.uk
High-quality, genuine electronic
parts from leading distributors.
38
Practical Electronics | March | 2025
|