This is only a preview of the October 2021 issue of Practical Electronics. You can view 0 of the 72 pages in the full issue. Articles in this series:
|
Max’s Cool Beans
By Max the Magnificent
Flashing LEDs and drooling engineers – Part 20
A
s I pen these words, I’ve just
returned from Silicon Valley
where I was working on a rush
job of a nature I am unable to disclose
for a company whose name must remain
unspoken with individuals whose
identities I am not at liberty to reveal.
But I fear I’ve already said too much.
On the one hand, this was a lot of
hard work, rising at 5:30 in the morning
and working until 11:00 at night before
staggering back across the road to the
conveniently located hotel to start anew
the next day. On the other hand, it was
a lot of fun because I was working with
the crème de la crème of techno-dweebs.
Of course, this meant I had to be in a
position to establish my own technocred, as it were. Fortunately, to bolster
my modest skills, I had recently taken
possession of a new smart business card,
which offered a useful distraction (Fig.1).
This laser-etched wooden beauty – they
also have plastic versions – was kindly
gifted to me by the folks at Mobilo. I
opted for the wood version because I am
enamored by the ‘steampunk’ aesthetic.
Now, you may be thinking, ‘Ho hum,
a wooden business card, what’s so
great about that?’ Well, if you had your
smart phone handy, I’d show you. The
point is that you don’t need to waddle
around staggering under the weight of
a bunch of these cards – one is plenty.
All I need to do is wave my card over a
Fig.1. Meet my new smart business card.
50
smartphone equipped with NFC (nearfield communication) capability, and my
contact details – including my photo,
name, company name, address, telephone
number and website – pop up on the
screen. With just a single tap of the finger,
the phone’s owner can add me to their
contacts list.
Quite apart from anything else, when
one is living in the middle of a worldwide
pandemic, this 21st century business card
technology prevents any embarrassment
or worry associated with accepting a
potentially disease-ridden traditional
business card. An added advantage for
me is that this card acts like fish bait
when I’m swimming with a technoweenie crowd (you can discover more
at: MobiloCard.com).
GROK is a four-letter word
The word ‘grok’ is a neologism coined by
American writer Robert A. Heinlein for
his 1961 science fiction novel Stranger
in a Strange Land. The Oxford English
Dictionary summarises the meaning of
grok as: ‘to understand intuitively or
by empathy, to establish rapport with’
and ‘to empathise or communicate
sympathetically (with)’; also, ‘to
experience enjoyment.’ (Heinlein’s
concept was a little more nuanced than
any of these, but I’m sure you get the drift.)
The reason I mention this here
is that, in my previous column (PE,
September 2021) I mentioned that one
of the things I am planning on doing
with my 10-character Victorian Display
(where each character is formed from
21-segments) is to implement a version
of the word art piece that was created
by Matt Gorbett in 2007 (https://bit.
ly/2THZLQf). As part of this, I’m going
to mount a potentiometer below each of
my characters.
In Matt’s implementation, he started
by displaying the message ‘I #### YOU’
(which will consume all 10 characters
of my display when we count the two
spaces). The idea is that a causal passerby
can use the potentiometers under the
four blank characters to add a word that
expresses a sentiment like ‘I LOVE YOU’
(hopefully they refrain from declaring
‘I HATE YOU,’ otherwise someone will
end up sleeping on the sofa). After a few
seconds to allows the user to contemplate
their statement, the system starts to swap
individual letters to form alternative
messages until eventually returning to
its original ‘I #### YOU’ state.
So, how many four-letter words are
there? Well, if we were to include every
combination, we’d have 26 * 26 * 26 *
26 = 456,976. In reality, of course, we
don’t use many of these permutations
for one reason or another, including
those that graunch on our ears. It’s been
a long time since I felt the urge to xqzn
my oiwk, for example (I’m not as flexible
as I used to be). I just had a quick Google
while no one was looking to discover
that, according to the Official Scrabble
Player’s Dictionary, Volume 6, there are
3,996 legal four-letter words.
As an aside, Word-Buff.com informs us
that, while 93 of these four-letter words
claim three vowels and one consonant,
only one four-letter word is composed
exclusively of vowels: EUOI, which
was, ‘a cry of impassioned rapture in
ancient Bacchic revels,’ although I think
I expressed much the same sentiment
when I once dropped a hammer on my
foot. By comparison, 47 four-letter words
are formed using only consonants, eg,
HYMN: a religious song or poem of praise
to a god, LYCH: the Saxon word for a dead
body (possibly someone whose hymns
were deemed to be unsatisfactory), and
MYTH: a widely held but false belief or
Practical Electronics | October | 2021
idea (such as the notion that I have a
clue what I’m talking about).
But we digress... Let’s assume we have
our list of 3,996 four-letter words stored
in our microcontroller’s memory. This will
require 15,984 bytes of memory (one byte
for each letter), which would be a problem
for an Arduino Uno, but it’s not an issue
when we remind ourselves that I’m using
a Teensy 3.6 to drive my Victorian Display,
and this little beauty boasts 1MB of Flash
and 256KB of RAM.
So, how are we going to generate
derivative words based on the original
selection entered by our passerby?
The simplest technique would be to
simply search for any random word
that differs from our current word by
a single letter and swap that letter out,
then keep on repeating the process
for some number of cycles before
returning to the ‘I #### YOU’ state.
On the one hand, we will end up with
a lot of nonsensical sentences; on the
other hand, we might be surprised and
delighted by an unexpected expression.
Another possibility would be to
associate each of the words in our list
with its logical opposite, such as LOVE
and HATE, and then have the system
create a word ladder, which is based on
a word game invented by Lewis Carroll.
A word ladder puzzle begins with two
words. To solve the puzzle, one must find
a chain of other words to link the two, in
which each pair of adjacent words differ
by only one letter. For example, LOVE,
LAVE, LATE, HATE (or LOVE, LOOE,
LOOK, GOOK, GROK).
But before I start rooting around for an
algorithm to implement this, I thought
I’d throw things open to discussion. Can
you think of any other form(s) of word
play we might decide to employ for this
task? If so, please feel free to drop me an
email and share your ideas.
It’s a SMAD, SMAD, SMAD,
SMAD world!
I have no idea why, but I was just thinking
about the 1963 American comedy film It’s
a Mad, Mad, Mad, Mad World with its allstar cast, including Spencer Tracy, Buddy
Hackett, Mickey Rooney, Ethel Merman,
and Phil Silvers. As a kid, I also used to
love watching Phil Silvers and the gang
in the Sergeant Bilko sitcom (officially
known as The Phil Silvers Show), which
originally ran from 1955 to 1959.
‘Not a lot of people know that’ is a
catchphrase that is commonly associated
with Sir Michael Caine. Well, not a lot of
people know that the American animated
sitcom Top Cat, which originally aired
from 1961 to 1962, had its roots in
Sergeant Bilko. For example, the Top
Cat character was voiced by Arnold
Stang, whose vocal characterisation
was based on an impression of Phil
Practical Electronics | October | 2021
Silvers. Furthermore, Maurice Gosfield,
who played Private Duane Doberman in
Sergeant Bilko, also provided the voice
for Benny the Ball in Top Cat.
I’m sorry. What were we talking about?
Oh yes, Steve and Max’s Awesome
Displays (SMADs), each of which boasts
45 tricolour LEDs. As we previously
discussed (PE, August 2021), these
displays – which were conceived and
created by Steve Manley and yours truly
– can be enhanced by the addition of
‘shells’ that compartmentalise the light
from the LEDs. We currently have two
different types of shells allowing us to
create 29-segment displays (in which 13
of the shells’ compartments have one LED
and 16 compartments have two LEDs),
and 45-segment displays (in which each
compartment has its own LED).
In my previous column (PE, September
2021), I made mention of the fact that I’ve
created two ‘robot heads,’ each of which
boasts two SMADs. One head features
two 29-segment displays, while the
other flaunts two 45-segment displays.
These are fixed structures at the moment,
but a project for the future may be to
create upgraded versions with sensors
(to detect the presence of people and to
locate the source of sounds) and servos
(to pan and tilt the heads), thereby
allowing their SMAD eyes to follow
you around the room (be afraid, be
very afraid). Also in that issue, we
introduced the LED and segment map
for the 29-segment versions of these
displays (Fig.2). The numbers, which
are applicable to both types of SMAD,
refer to the positions of the LEDs in the
string, while the letter combinations
are the names we use to identify the
segments in the 29-segment versions.
Just call me Don Quixote
You may recall that Steve created a
cunningly cool video that compares and
contrasts a bare SMAD, a SMAD with a
29-segment shell, and a SMAD with a
45-segment shell (https://bit.ly/2VNhhUh).
Steve demonstrates all sorts of cunningly
colourful effects in this video, and we
will build up to these sophisticated
presentations over time. However, before
we run, we first have to learn to walk,
so we are going to take things step-bystep, starting with a simple pinwheel or
windmill effect (Don Quixote – tilting at
windmills – I’m sorry, sometimes I just
can’t help myself).
We will start with a simple effect where
just one windmill arm sweeps around in
a circle (Fig.3a). Don’t forget that, should
you wish to join in the fun, frivolity,
giddiness and gaiety, then SMADs are
available for purchase from the PE PCB
Service (https://bit.ly/3wVUgLq) for the
remarkably low price of only £11.95
each, which includes shipping in the
UK (shipping outside the UK will be
quoted separately).
As usual, we won’t present complete
programs here, but you can follow along
by downloading the code from the October
2021 page of the PE website at: https://bit.
ly/3oouhbl). You’ll find our first sketch
(program) in file CB-Oct21-01.txt
L e t ’s s t a r t b y d i s c u s s i n g s o m e
housekeeping tasks. In an earlier column
(PE, October 2020), we created some
useful utility functions called GetRed(),
GetGreen() and GetBlue(), each of
which accepts a 24-bit colour value as
input (actually, it’s a 32-bit word, but
only 24 of the bits are used) and returns
its corresponding 8-bit colour channel
value. We also created a BuildColor()
function that accepts three 8-bit red,
green, and blue colour components and
returns the corresponding 24-bit colour
value. The point is that you will find
these utility functions in our sketch, along
with a ModifyBrightness() function
that accepts a 24-bit colour as input and
returns a diminished version that’s been
dimmed-down to a specified percentage
of the original.
Consider the ModifyBrightness()
function – which I’m mainly using
when I want to dim things down to
take videos – it’s worth noting that we
perform the multiplication followed
by the division and not the other way
round. For example, assuming we wish
to modify the red channel to be only
20% of its original brightness, then the
algorithm we use is (red * 20) / 100. If
we were performing this calculation
using pencil and paper based on real
numbers with fractional components,
then we could achieve the same result
using (red / 100) * 20. The reason we
can’t use this latter approach in our
program is because an integer division
truncates any remainder, which means we
might discard useful information before
performing the multiplication, thereby
diminishing the fidelity of our result.
I’ve decided that I want the arm of my
windmill to perform a full rotation of the
display each second, so I’ve defined a
CYCLE_TIME of 1000 milliseconds. I’ve
also defined NUM_NEOS_PER_SMAD (the
number of LEDs forming each SMAD)
to be 45.
In my case, I have four SMADs (two for
each of my ‘robot heads’), so I’ve defined
NUM_SMADS to be 4. You can change this
value to reflect the number of SMADs at
your disposal. I’ve also daisy-chained all
of my SMADs together to form a single
string of 45 × 4 = 180 LEDs, so I’ve defined
NUM_NEOS to be (NUM_NEOS_PER_SMAD
* NUM_SMADS). The idea is that, if you
have only two SMADs, for example, then
all you have to do is to change the value
associated with NUM_SMADs for these
programs to work with your displays.
51
default value of 25% brightness, and
a foreground colour of white with a
default value of 100% brightness. The
actual values displayed for both of these
colours are further modified by our
ModifyBrightness() function.
Now, let’s jump to the main loop()
function. If you have only recently
joined our party, you may be surprised
to see that we don’t make use of the
Arduino’s delay() function. Instead,
every time we roll around the loop, we
check to see if a certain interval has
elapsed, as defined by a variable called
IntervalTime, which has been set to
Fig.2. SMAD board (left), LED and segment map (right) (Image source: Steve Manley).
CYCLE_TIME (one second) divided by
the number of patterns in our effect. If this interval has
Hold onto your hat!
elapsed, we first set the LEDs in the current pattern to be
I hope you are sitting comfortably because things are about
the background colour and we then set the LEDs in the
to get exciting. For this first effect, I’ve defined NUM_
new pattern to be the foreground colour. This technique
PATTERNS_IN_EFFECT as being 8 (this corresponds to the
was introduced in the Dump the delay topic in an earlier
fact that we have 8 ‘spokes’, as illustrated in Fig.3a), and
column (PE, December 2020).
MAX_LEDS_IN_EFFECT as being 2 (there are two LEDs in
Let’s look at this in a little more detail. In the case
each spoke). Using these, I’ve created a two-dimensional
of this particular program, we have a variable called
array of 8-bit integers called EffectMap[][], that is
EffectMapIndex that we use to point to the current row
comprised of NUM_PATTERNS_IN_EFFECT (ie, 8) rows,
(pattern) of interest in our two-dimensional EffectMap[][]
each containing MAX_LEDS_IN_EFFECT + 1 (ie, 3) items.
array. We start by determining how many LEDs we have in
We initialise this array as follows:
the current pattern:
{
numLeds = EffectMap[EffectMapIndex][0];
{2, 1, 17}, // BA
{2, 2, 18}, // BB
Using this information, we set the LEDs in the current
{2, 3, 19}, // BC
pattern to the background colour:
{2, 4, 20}, // BD
{2, 5, 21}, // BE
for (int iLed = 1; iLed <= numLeds; iLed++)
{2, 6, 22}, // BF
{
{2, 7, 23}, // BG
int iNeo = EffectMap[EffectMapIndex][iLed];
{2, 8, 24} // BH
Neos.setPixelColor(iNeo, BackgroundColor);
};
}
The first element in each row tells us how many LEDs we
Next, we increment our index to point to the next pattern
are using to form this pattern, while the remaining values
(the use of the ‘%’ modulo operator was discussed in detail
are the numbers of the LEDs in question. For example, the
in an earlier Cool Beans column: PE, March 2021):
first row tells us that we are dealing with 2 LEDs numbered
1 and 17. From Fig.2, we know that these LEDs correspond
EffectMapIndex = (EffectMapIndex + 1)
to segment BA, which is the vertical spoke in our windmill.
% NUM_PATTERNS_IN_EFFECT;
Of course, you might feel that – since there are two LEDs in
every pattern – defining this in the first element of each row
Once again, we determine how many LEDs we have in this
is a waste of time, space and effort, but we are establishing
new pattern, then – using this information – we set the LEDs
a foundation for what is to come.
in this new pattern to the foreground colour.
Last but not least, we’ve defined a background colour
and a foreground colour. At some stage in the future, we
will experiment with making one or both of these colours
The more the merrier
dynamic (eg, a rippling rainbow). For the moment, however,
As we see, implementing a simple windmill effect using one
we will stick with static values. In the case of this column’s
arm (segment) on one SMAD is ‘easy peasy lemon squeezy’
code, we are using a background colour of red with a
as they say in the US (we certainly wouldn’t want it to be
the opposite, which would be ‘stressed
depressed lemon zest’).
Suppose we wish to control additional
( a)
SMADs that are daisy-chained together
– for example, the four SMADs in my
two robot heads.
Let’s consider the part where we set
( b)
the LEDs in the current pattern to the
background colour. As a ‘cheap-andcheerful’ (also known as ‘quick-and(c )
dirty’) technique, we could simply use
the following (you can see the full listing
of the program in the download file:
Fig.3. Variations on a simple windmill effect.
CB-Oct21-02.txt):
52
Practical Electronics | October | 2021
for (int iLed = 1; iLed <= numLeds; iLed++)
{
int iNeo = EffectMap[EffectMapIndex][iLed];
Neos.setPixelColor((iNeo +
0), BackgroundColor);
Neos.setPixelColor((iNeo + 45), BackgroundColor);
Neos.setPixelColor((iNeo + 90), BackgroundColor);
Neos.setPixelColor((iNeo + 135), BackgroundColor);
}
Instead of writing to one LED, we now write to four of the
little rascals using a 45-pixel offset each time (the only
reason we add 0 in the first statement is for completeness –
the compiler will remove this from the subsequent machine
code). We would apply a similar treatment when we come to
setting the LEDs in the new pattern to the foreground colour.
The problem with this approach is that it’s hard-coded.
That is, if you have only two SMADs, for example, you
would have to comment-out (or delete) some of the lines.
A more generic approach is as follows (here we are setting
the current pattern to the background colour):
One thing you might find confusing is the ‘0’ values in this
array, which we are using for two different purposes. In the
case of the rows that have 3 LEDs in their patterns, the 0s in
the second column refer to the LED associated with segment
AA. By comparison, in the case of the rows that have only
two LEDs in their patterns, the 0s in the fourth column serve
only as space fillers – we could assign any value to these, and
it wouldn’t have any effect because we never use them. (As
an aside, we used unsigned 8-bit integers to form this array.
If we had opted to use signed 8-bit integers, I would probably
have assigned –1 values to these space filler items, thereby
providing a visual clue that they were ‘special.’)
As one final variation on this theme, suppose we now decided
to augment our current version of the program with the ability
to illuminate the EA, EB, EC and ED segments when the arm
is in its NE, SE, SW and NW positions, respectively (Fig.3c).
Once again, all we need to do is modify our MAX_LEDS_IN_
EFFECT definition to be 4, and then update the contents of
our EffectMap[][] array to be as follows (you can see the
full program in file CB-Oct21-05.txt):
{
{2, 1, 17, 0, 0}, //
BA
{4, 0, 2, 18, 41}, // AA BB EA
{2, 3, 19, 0, 0}, //
BC
{4, 0, 4, 20, 42}, // AA BD EB
{2, 5, 21, 0, 0}, //
BE
{4, 0, 6, 22, 43}, // AA BF EC
{2, 7, 23, 0, 0}, //
BG
{4, 0, 8, 24, 44} // AA BH ED
numLeds = EffectMap[EffectMapIndex][0];
for (int iSmad = 0; iSmad < NUM_SMADS; iSmad++)
{
int smadOffset = iSmad * NUM_NEOS_PER_SMAD;
for (int iLed = 1; iLed <= numLeds; iLed++)
{
int iNeo = EffectMap[EffectMapIndex][iLed];
Neos.setPixelColor((iNeo + smadOffset),
BackgroundColor);
}
}
As we see, we create an outer loop that cycles through
all of the SMADs, and then we calculate the number of
the pixel to be modified based on the current SMAD. We
would perform a similar treatment with regard to setting
the new pattern to the foreground colour (you can see the
full program in file CB-Oct21-03.txt).
Variations on a theme
Even though our current windmill effect with its single arm
is rudimentary, it still gives us the ability to perform some
interesting experiments. For example, suppose we wish to
pulse the center segment such that it is on whenever the
arm is pointing NE, SE, SW and NW, and off whenever the
arm is pointing N, E, S and W (Fig.3b). Take a moment to
think how we might set about doing this.
In fact, all we need to do is modify our MAX_LEDS_IN_
EFFECT definition to be 3, and then update the contents
of our EffectMap[][] array to be as follows; the rest of
the program stays as-is (you can see the full program in
file CB-Oct21-04.txt):
{
{2, 1, 17, 0}, //
BA
{3, 0, 2, 18}, // AA BB
{2, 3, 19, 0}, //
BC
{3, 0, 4, 20}, // AA BD
{2, 5, 21, 0}, //
BE
{3, 0, 6, 22}, // AA BF
{2, 7, 23, 0}, //
BG
{3, 0, 8, 24} // AA BH
};
};
For your delectation and delight, I’ve just created a short video
showing all of these test cases in action in gloroius technicolor:
https://youtu.be/BBFFyQP_yhE
It’s your turn!
I don’t think it’s fair for me to be having all the fun (and doing
all the work). How about you jump into the fray with gusto and
abandon? For example, how would you go about modifying
our latest program so that it has four patterns each with two
arms at 180° to each other?
Next, how would you modify this latest incarnation such
that the windmill patterns on one of the SMAD’s eyes rotate
clockwise while the other SMAD’s eyes rotate anticlockwise?
As another thought experiment, you might want to consider
how to implement a program involving two or more SMADs that
starts with them each displaying a single windmill arm pointing
upwards. We start with the least-significant SMAD (the one on the
right) spinning its arm clockwise completing a full rotation each
second. Every time this arm returns to its vertical position, the
arm on the adjacent SMAD advances by one position (pattern).
Similarly, every time the arm on the second SMAD returns to its
vertical position, the arm on the third SMAD advances by one
position, and so on for all of the SMADs in the chain.
Finally, remembering that I eventually intend for the SMADs
in my robot heads to give the impression that they are acting
as eyes, this would be a good time for us to start cogitating and
contemplating on which colour and segment combinations we
could use to make them appear to be looking left, right, up, down
and straight ahead. Also, can we use different combinations
of colours and segments to reflect emotions, like happy, sad
or angry, for example? As always, I welcome your comments,
Cool bean Max Maxfield (Hawaiian shirt, on the right) is emperor
of all he surveys at CliveMaxfield.com – the go-to site for the
latest and greatest in technological geekdom.
Comments or questions? Email Max at: max<at>CliveMaxfield.com
Practical Electronics | October | 2021
53
|