This is only a preview of the December 2020 issue of Silicon Chip. You can view 37 of the 112 pages in the full issue, including the advertisments. For full access, purchase the issue for $10.00 or subscribe for access to the latest issues. Articles in this series:
Items relevant to "Power Supply for Battery-Powered Vintage Radios":
Items relevant to "Dual Battery Lifesaver":
Items relevant to "A Closer Look at the RCWL-0516 3GHz Motion Module":
Items relevant to "Balanced Input Attenuator for the USB SuperCodec, Part 2":
Articles in this series:
Items relevant to "Flexible Digital Lighting Controller, part 3":
Purchase a printed copy of this issue for $10.00. |
Flexible D i g i ta l
Lighting Controller
Part three – Using it with RGB LEDs – by Tim Blythman
Addressable LEDs are a simple and effective way to add coloured lights to all
manner of displays. They make the perfect addition to our Digital Lighting
Controller. In this final instalment, we’ll show you how to use them alone or
in combination with mains-powered lights as part of our new system.
W
e noted early in this series
that addressable LEDs are
now a standard part of lighting displays. They’re easy to control
and being low-voltage, are very safe.
So it makes sense that you should be
able to use them with the new Flexible
Digital Lighting Controller.
In January 2020, we described an
8x8 RGB LED matrix made from addressable LEDs (see siliconchip.com.
au/Article/12228).
These use the WS2812 addressable
LED IC, which can be found in many
other forms; last month, we reviewed
some of Jaycar’s range of “wearables”,
which includes their Cat KM1040
RGB LED Raft Pad, based on a compatible IC.
They (and other retailers) can also
90
Silicon Chip
supply the same (or similar) ICs on
strips and/or reels.
We’re going to use these handy modules and strips for our experiments.
In this article, we’ll describe several
different ways to integrate addressable LEDs into a lighting project based
around our Digital Lighting Controller.
The first option we’ll present is an
alternative ‘slave’ unit which can control sets of these addressable LEDs. The
slave unit already described can control up to four mains-powered lamps.
Our LED slave can instead drive up
to 64 addressable LED modules, using
signals from the same master units we
described last month.
The two different slave units (fourchannel mains and 64-channel LED)
are a great way to combine mains and
Australia’s electronics magazine
LED lamps with the excellent sequencing software that we produced for the
original Digital Lighting Controller
many years ago.
We’ll also describe example software for Micromites and Arduinos
which can directly drive addressable LEDs at the same time as controlling one or more mains-powered
slave units.
If you’re happy programming a Micromite or Arduino, you can modify
our sample code and build a lighting display that does precisely what
you want.
Addressable LED slave unit
Being able to control up to 64 mains
lamps using our Digital Lighting Controller makes it easy to build an insiliconchip.com.au
Here’s the LED Slave Unit driving a
length of Jaycar’s XC4390 addressable
LED strip for testing – and found that
it not only worked well . . . it looked
spectacular! It would look even better
strung up outside, or wrapped around
a Christmas tree!
credible lighting display, but there is
no doubt that the cost of doing so will
add up very quickly.
Our LED slave allows you to strike
a compromise between expense and
grandeur. One of these can control up
to 64 LEDs, while each mains slave
unit adds another four lamps. They
can be mixed and matched in any
combination within the 64 addresses
that exist.
The addresses can be set independently, so lamps can be set to some addresses and LEDs to others. You can
even set some devices to the same address, to allow simple sequences to be
more impressive by controlling both
lamps and LEDs.
Since the addressable LEDs tend to
be smaller and produce much less light
than mains-powered lamps, we’ve also
come up with ways to have multiple
LEDs in the same strip respond to a single address, so that you can conserve
the 64 available addresses.
There are various options when it
comes to addressable RGB LEDs to
control. We tested Jaycar’s XC4390
siliconchip.com.au
addressable LED strip and found it
worked well. These IP65-rated 2m
strips are sealed in silicone and backed
with 3M adhesive tape. Each strip has
120 LEDs (one every 17mm) and is terminated at both ends with a locking
plug and socket.
Each end of the strip also has a pair
of wires for a separate power connection, which is handy when running
longer strips. There is also a prewired plug with bare leads which
we connected directly to the LED
slave’s screw terminals. Although not
marked, the connections are red to 5V,
white to ground and green for data.
We should also mention Altronics
Cat X3223A, which is a 5m-long strip
with 300 LEDs. While we have not
tested this ourselves, we expect them
to be fully compatible; you could even
mix and match the two.
Circuit details
The LED slave circuit is shown in
Fig.16, overleaf. You might recognise
part of the circuit from the mains slave
unit; it works in much the same fashion.
Australia’s electronics magazine
Opto-isolator OPTO1 receives the
serial data via CON3, with CON4
available to daisy-chain the signal to
another slave. CON3 and CON4 are
wired in parallel and are interchangeable. A 220Ω resistor limits the current through OPTO1’s LED to a suitable level, while the diode limits its
reverse bias voltage.
Since there are no mains voltages
involved in this circuit, OPTO1 might
seem unnecessary, but it prevents the
formation of ground loops, which
might occur depending on how the
unit is wired. It also allows circuits
with different grounds to be connected without problems.
OPTO1 has an open-collector output, so a 1kΩ pull-up resistor brings
the output of the optoisolator to 5V
when its internal transistor is off.
The serial data from OPTO1 goes
to the UART pin (pin 5) of IC1, a
PIC16F1455 microcontroller. This decodes the serial data and produces data
to drive LEDs on pin 2. This signal is
fed through a 390Ω resistor and along
with 5V power and ground, is made
December 2020 91
l
l
l
SC
Ó
DIGITAL LIGHTING CONTROLLER WS2812 SLAVE
Fig.16: the circuit for the LED slave unit is quite simple, and much of it is borrowed from the mains slave described
in the October issue. Virtually all of the work is done by PIC micro IC1, which receives the DMX-512-like serial data
at its RC5 digital input, pin 5. It then produces a signal to drive one or more WS2812B RGB LEDs from its RA5 digital
output at pin 2.
available at screw terminal CON5. The
resistor protects the micro and LEDs
from excessive current flow under
fault conditions.
Power for the unit is supplied via
CON1, a mini USB socket. JP1 and JP2
provide option settings. CON2 is an
in-circuit serial programming (ICSP)
header for IC1, in case that is required.
VR1 is a 10kΩ trimpot which is used
to control LED brightness, by varying
the voltage applied to the analog input
at pin 3 (AN3) of IC1.
Indicator LED2 lights up when power is applied, while LED1 lights up
when serial data is supplied.
Operation
The serial protocol used is explained in the previous articles in this
series; it is similar to DMX-512 but
uses a simpler and slower serial interface. Microcontroller IC1 decodes
the serial data received at pin 5 and
produces data suitable for driving ad92
Silicon Chip
dressable LEDs at digital output pin 2.
We used a PIC16F1705 in the mains
slave, as it is slightly cheaper than the
PIC16F1455 and we do not need the
USB peripheral in the 16F1455.
However, the PIC16F1455 also has a
higher maximum clock speed (48MHz
vs 32MHz). We need that for this design, to ensure that the serial data can
be processed and the timing-critical
LED data is produced with accurate
timings.
Jumper header JP2 provides the
same address setting feature that the
DIP switches provided in the mains
slave unit. Unlike that one, the LED
slave unit is not limited to controlling
four lamps. So one LED slave unit set
to address 0 can provide control of
64 LEDs.
If the address is not set to 0, then
the offset is applied and the addresses ‘wrap around’. For example, if the
address is set to 16, the brightness of
the first LED in the chain will be set
Australia’s electronics magazine
by the 16th data byte, the second LED
by the 17th data byte, the 48th LED by
the 64th data byte, the 49th LED by the
first data byte etc.
JP1 controls whether each data byte
controls an entire RGB LED, or the individual colour channels (red, green
and blue) within each LED. When JP1
is inserted, each LED receives identical data on each of the red, green and
blue channels from the data at a single address.
So the LEDs will light up white with
adjustable brightness.
When JP1 is out, each individual red, green or blue LED element is
treated as a separate channel. Thus,
you can control up to 21 individual
RGB LEDs in this mode.
Potentiometer VR1 is used to control
the brightness, but also sets some other
configurations. VR1’s wiper is divided into three roughly equal sections.
Within each section, the position sets
a global brightness value. You might
siliconchip.com.au
like to reduce the overall LED brightness either because these LEDs can be
too bright, or to simply limit the current needed by the supply.
Each of the three sections corresponds to a different LED configuration.
At the ‘lowest’ (most anti-clockwise) section, each colour channel
corresponds to one LED. In the middle section, each channel corresponds
to four LEDs, and in the top section,
one channel corresponds to 16 LEDs.
This allows more LEDs to be controlled from fewer channels. A similar effect could be had by cutting and
wiring LED strips so that they are fed
data in parallel, but we think this is a
much simpler approach.
To keep the timing tight, each LED
slave unit only produces data for 64
LEDs, so in four-LED mode, only 16
channels are used, and in 16 LED
mode, four channels are used.
JP1, JP2 and VR1 are continuously sampled during operation, so you
can tweak the controls in real-time to
get a feel for how the different modes
work and look.
You’ll also note that we’ve wired the
USB D+/D- lines to the USB socket. The
software doesn’t use these pins or the
USB peripheral, so we figured that they
might as well be connected, in case
anyone wants to modify the software
so that it does use the USB function.
Software
Although the brightness is set by an
analog voltage from a potentiometer,
the addressable LEDs use all digital
data, so this conversion must be done
in software.
To avoid the (relatively slow) multiplication that would be needed to do
this ‘live’, an array in flash memory
stores a table of pre-calculated values
for 16 brightness levels. This reduces
the processing load on the micro. The
16 brightness levels are not linear, but
are roughly logarithmic, which corresponds to the human perception of
brightness.
The LED data takes about 2ms to
produce, during which time no serial
data can be received, as the micro is
too busy ensuring that the LED signal
is timed accurately. So we only process every second ‘update’ from the
master. With our Micromite master
unit, this still means an update rate
around 30Hz, which is fast enough to
be unnoticeable.
Eagle-eyed readers may have noted
that there are no pull-up resistors on
JP1 or JP2 and that the PIC16F1455
does not have internal pull-ups on
PORTC (which is connected to JP1
& JP2).
To simulate a weak pull-up, the pin
is pulsed high very briefly (around
83ns). Stray capacitance keeps the pin
high unless the jumper is in place, so
the jumper state can still be sensed,
and the circuit is simplified.
Construction
The LED slave unit is built on a
small PCB which is sized to fit in a UB5
Jiffy box. It measures 79 x 45mm and
is coded 16110205. Refer to the PCB
overlay diagram, Fig.17, to see where
the components go on the board.
The USB socket is the only surfacemounted part and should be fitted first.
Here, some flux paste, a fine-tipped soldering iron and a magnifying glass will
come in handy. Some solder braid will
help if you manage to bridge any pads.
Apply flux to the pads and place
the USB socket on the PCB. There are
small holes in the PCB to locate it accurately. Add flux to the top of the
pins as well.
Now load the iron’s tip with a small
amount of solder. You want to be able
to touch the iron to the PCB pads and
allow just the right amount to run off
to form the joint; the flux will encourage this.
If the USB socket is firmly against
the PCB, you may only need to touch
the PCB pad. If that doesn’t work, carefully bring the iron to meet the socket’s
pin where it sits on the pad. A fine tip
will help to prevent bridges.
Then solder the four connected pins;
the fifth is not needed. If you bridge
any pins, finish soldering the remaining pins before attempting to remove
the excess.
If you are confident that the pins
are lined up accurately, solder the
larger side tabs to secure the part mechanically.
If you have solder bridges to remove,
apply some flux to the area and clean
the iron’s tip. Place the braid against
the solder and press gently with the
iron. When the braid takes up the
solder, carefully draw it away with
the iron.
Once you are happy, you can use a
flux cleaner to remove any that is left
on the PCB.
Follow with the resistors, checking
the values as you install them; there
are six resistors with four different
values. Then mount the three MKT
capacitors, which are identical and
not polarised. The solitary diode has
its cathode facing to the right – solder
it in place.
CON2, JP1 and JP2 are simple pin
headers. In each case, it is a good idea
Fig.17: fit the parts to the LED slave PCB as shown in the component overlay above and the matching same-size photo at
right. CON1 is the trickiest part to fit, so do that first. CON2 is optional if you have a pre-programmed microcontroller,
and CON4 is not needed if you don’t wish to connect any downstream slave units.
siliconchip.com.au
Australia’s electronics magazine
December 2020 93
Fig.18: connecting addressable LEDs to the LED slave is
straightforward. This shows Jaycar LED Raft Pads (Cat
KM1040), but other addressable LEDs will also work,
such as Jaycar XC4390 or Altronics X3223A strips.
to solder one pin and check that the
header is straight and square before
soldering the remainder. For JP1 and
JP2, you can temporarily fit the jumper shunts to ensure that the pins stay
aligned. CON2 is only needed if you
wish to program IC1 in-circuit.
When mounting IC1, ensure that
its pin 1 orientation matches the PCB
silkscreen and overlay diagram. You
can solder it directly to the board (the
more reliable method) or via a socket, which is useful if you want to reprogram it out of circuit. Solder two
diagonally opposite pins, then check
that the IC or socket is square and flat
before soldering the rest.
If you are using a socket, insert the
programmed IC carefully, ensuring
that no pins are bent underneath.
OPTO1 can be socketed too, but it
does not need to be. Use the same procedure as for IC1.
VR1 will only fit one way, but you
may need to bend the leads to fit it.
Once it has clicked into place, solder
all three leads.
CON3 and CON4 are the RJ45 sockets. If you plan only to use one socket,
then only one needs to be fitted. This
will also save you cutting a hole in the
case. In any case, snap the socket into
place and solder one pin to secure it.
Check that it is flat and parallel to the
Parts list – Digital Lighting LED slave
1 double-sided PCB coded 16110205, 79 x 45mm
1 UB5 Jiffy box
4 12mm-long M3 tapped spacers
8 M3 x 6mm panhead machine screws
1 SMD mini USB Type-B socket (CON1)
1 5-way pin header (CON2; optional, for ICSP)
2 PCB-mount RJ45 sockets (CON3,CON4) [Altronics P1448]
1 3-way 5mm pitch screw terminal (CON5)
1 2-pin header (JP1)
1 4x2-pin header (JP2)
5 jumper shunts (JP1,JP2)
1 14-pin DIL IC socket (optional; for IC1)
4 self-adhesive rubber feet
Semiconductors
1 PIC16F1455-I/P microcontroller programmed with 16110205.HEX, DIP-14 (IC1)
1 green 3mm LED (LED1)
1 red 3mm LED (LED2)
1 6N137 optoisolator, DIP-8 (OPTO1)
1 1N4148 signal diode (D1)
Capacitors
3 100nF MKT
Resistors (all 1/4W axial 1% metal film)
1 10kΩ
(brown black black red brown or brown black orange brown)
3 1kΩ
(brown black black brown brown or brown black red brown)
1 390Ω
(orange white black black brown or orange white brown brown)
1 220Ω
(red red black black brown or red red brown brown)
1 10kΩ mini horizontal trimpot (VR1) (code 103)
94
Silicon Chip
Australia’s electronics magazine
silkscreen markings before soldering
the remaining pins. After those are finished, install CON5.
The LEDs are mounted so that their
lenses go through holes in the front
panel. We’ve left them to last so that
you can check the mounting arrangements before soldering them in place.
Fit the LEDs so that the tops of their
flanges sit around 10mm from the PCB.
This ensures that the flanges clear the
lid when fitted, and the LEDs don’t sit
too proud.
LED2 (on the left) is the power LED,
which should be red. The serial data
LED, (LED1) is on the right and should
ideally be green. Both their cathodes
are to the left, which means that their
longer (anode) leads are to the right.
Programming
Use the MPLAB X IPE (a free download) to program IC1 if it is not programmed already. Connect a PICkit 3
or PICkit 4 programmer to CON2, select PIC16F1455 as the Device, then
click Apply and Connect.
You may need to select “Use Low
Voltage Programming mode entry”
and “Power Target Circuit from Tool”
from the Power menu. LED2 will light
up when power is applied through
the tool.
Browse for the HEX file, then press
“Program” and check that it was successful.
Testing
Before completing the assembly,
it’s a good idea to test the LED slave
unit. Connect a USB power supply to
CON1; the power LED should illuminate. Then connect any of the master units described in parts 1 or 2 to
apply a signal to the LED slave unit.
LED1 should light up when a signal
is received.
If all is well, connect some addressable RGB LEDs; Fig.18 shows how to
connect Jaycar’s RGB Island Pads. Any
compatible addressable LEDs should
have similar pin markings. Check that
the current draw of the connected
LEDs will be within the capacity of
the USB supply.
The contacts on most mini-USB type
sockets are rated up to around 1A; this
puts a hard limit on what the LED slave
unit can supply (besides what the supply can actually deliver).
If you have control data coming into
CON3 or CON4, you should see attached LEDs illuminate. If not, check
siliconchip.com.au
Fig.19: the LED slave fits neatly in a UB5 Jiffy box; make the
holes as shown here. The wires for the LEDs are fed through
the holes on the right-hand side, so you can adjust them to
suit your wiring.
Fig.20: this is the lid panel artwork, which can also
double as a drilling template for the LED holes.
that VR1 is not wound fully anticlockwise.
Preparing the enclosure
The PCB mounts in the base of a
UB5 Jiffy box using four threaded
spacers. The box we used had four
small holes marked on the base already, so we based our design around
these dimensions. If your case has
similar markings, that will make construction easier.
Drill four holes in the base according to Fig.19. Thread an M3 machine
screw through the bottom of each hole
and secure with a tapped M3 spacer
from above. You might like to use
Nylon machine screws so that their
heads also form feet for the box. Alternatively, you could fit rubber feet
(screw mounting or stick-on).
siliconchip.com.au
Cut the remaining holes in the sides
of the base of the box as shown in
Fig.19. The larger holes for the RJ45
sockets are at the top edge, so they can
be started by carefully making vertical
cuts with a hacksaw on either side.
You might be able to snap the tabs
out with wide-nosed pliers or by drilling some holes to weaken it. Then
straighten up the holes with a file,
carefully bringing them to the required
dimensions.
The hole for the USB socket is a
bit trickier. Start with a pair of 4mm
drilled holes, then bring the holes out
to size with a small file (such as a needle file). Alternatively, a single 10mm
round hole will do the job, although it
won’t be as elegant.
Also drill the lid as shown, to suit
the LEDs. Alternatively, use the lid
Australia’s electronics magazine
artwork (Fig.20) as a template.
Now slot the PCB into place to test
it fits. Guide the USB socket into place
and then rotate the PCB to bring the
RJ45 sockets into their slots. Rest the
lid on top and ensure that the LEDs go
into their holes.
Remove the PCB and make any necessary adjustments. You should also
drill some holes to suit the LED wires.
We used 3mm holes; this should be
sufficient for most cases.
Re-seat the PCB and screw it down
onto the spacers with the remaining
M3 machine screws. The wires for
the RGB LEDs can be terminated by
feeding them in through the holes and
screwing them into CON5.
Now print the lid artwork, cut out
the holes and glue it to the lid. You
can download this as a PDF from the
December 2020 95
Screen1: our Arduino sample code uses Adafruit’s Neopixel library to control the addressable LEDs. It’s easily
downloadable via the Library Manager, as shown here.
SILICON CHIP website and print it in
colour.
Print it onto overhead projector film
(in reverse so that it appears correctly
when printed on the back) or laminate
a paper copy to protect it. Use neutral
cure silicone to secure it to the lid, being sure to squeeze out any bubbles.
We h a v e m o r e i n f o r m a t i o n
about making front panel labels at
siliconchip.com.au/Help/FrontPanels
Fit the lid onto the base and over
the LEDs, and secure with the screws
supplied with the Jiffy box.
to the mains slave units, depending on
how you want your display to look.
Multiple chains of addressable
LEDs can be connected to one of our
LED slave units, although we haven’t
tested how many you can parallel before the signal degrades. The current
drawn by the LEDs will probably be
the main constraint.
This could be handy for waterfall
type effects, where parallel chains of
LEDs can connect to a common data
source, allowing for stunning effects
from even a single controller.
For larger displays, you might have
to consider connecting an alternate
supply for 5V power.
Remember that you can also drive
LED strips in sets of four or 16 LEDs
by adjusting VR1. You could also com-
Usage
With JP1 fitted, each LED becomes
a single channel and produces white
light (equal amounts of red, green and
blue). If JP1 is not inserted then each
colour becomes its own channel. This
reduces the number of LEDs that can
be addressed, but allows for more colour options. The colour order is red,
green then blue.
JP2 allows the slave address to be
set. It operates identically to S1 on the
mains slave.
Of course, since this unit can address up to 64 LEDs, it should be
considered more of an offset than an
address, and the address may wrap
around in some cases.
You can set the LED slave unit to use
the same address or different addresses
96
Silicon Chip
Fig.21: using an Arduino to control both addressable LEDs and lamps via our
slave units is easy. This shows the Uno, but you can also use a Mega board
with identical wiring. Other boards may have different pin requirements for
the serial data, but just about any Arduino can be made to work.
Australia’s electronics magazine
siliconchip.com.au
bine this feature with multiple strips
in parallel.
example to write your own program.
Arduino and Micromite
You will need to have the Arduino
IDE (integrated development environment) set up to program an Arduino
board to control lights (download it
from siliconchip.com.au/link/aatq).
We’re using version 1.8.5 of the Arduino IDE; any version since 1.8.0 should
work much the same.
Wire up your Arduino board to
the CP2102 Interface board and RGB
LEDs as shown in Fig.21. Not shown
is the RJ45 lead from the socket on
the CP2102 Interface PCB to the Slave
units.
The data connection for the LEDs
passes through a 390Ω resistor to
protect the two halves of the circuit
from voltage differences between independent power supplies. We’re using digital output D6 to produce the
addressable LED data, but the library
is configurable, so this can be changed
as needed.
Adafruit helped make addressable
LEDs popular with their “Neopixel” range of products; they also produced a library to make them easy to
work with.
We’re using this library to drive our
LEDs, as it doesn’t work only with Ne-
You can also drive addressable LEDs
from an Arduino or Micromite which
is also acting as a master unit for our
Flexible Digital Lighting Controller.
This saves you having to build any LED
slaves; the master can do all the work.
This means that the addressable
LEDs do not take up any of the 64 addresses, so you can have even bigger
displays.
In terms of hardware, we’re assuming you are using at least one slave
unit (mains or LED type). You will
also need one of the CP2102 Interface
boards described in the October issue, to allow a Micromite or Arduino
board to drive multiple slaves; otherwise, you’ll be limited to controlling
2-3 slave units.
And you will, of course, need either
an Arduino (we’re using the Uno) or
Micromite LCD BackPack (the V3 is
ideal).
The examples contain some simple
subroutines that produce interesting
patterns on both the LEDs and mains
lamps. You can try changing these by
altering some of the parameters, or
you might like to use our code as an
Arduino
opixels; it can drive any WS2812Bcompatible device.
Install this library by searching for
“Adafruit_NeoPixel” in the Arduino
Library Manager or by downloading it
directly from https://github.com/adafruit/Adafruit_NeoPixel
Screen1 shows the correct library to
install in the Library Manager.
The library comes with example
code that works with addressable
LEDs, but we’ve also written a demo
program that combines this with data
for the slave units (allowing mainspowered lamps to be controlled too).
It is part of the download package for
this article.
Extract the sketch, open it, select
the correct serial port and board type.
Press “Upload” and the LEDs and
lamps should spring to life.
Micromite
We’ve put together a similar demo
for use with a Micromite; we prototyped our version on a V3 BackPack,
but any Micromite variant using the
PIC32MX170F256B should work with
our code.
The wiring diagram is seen in
Fig.22. And like the Arduino master,
the pins are configurable, but in this
case, we have chosen to use pin 9 for
the LED data and pin 10 to drive the
mains slaves. As with the Arduino
example, if you need more current to
drive LEDs than the USB port can provide, you will need to connect another
power supply.
There are no libraries to download,
as these are embedded in our BASIC
program as CFUNCTIONs. Open the
BASIC program, send it to your Micromite (using MMEdit, TeraTerm or
another terminal program) and run it.
Once you have confirmed that it all
works, you can modify our example
to suit your requirements.
Conclusion
Fig.22: you can also drive RGB LEDs and/or mains lamps using any
Micromite with a PIC32MX170F256B chip onboard – we tested our code
using a V3 BackPack, as shown here. The pins used are reconfigurable in
software.
siliconchip.com.au
Australia’s electronics magazine
Our new Flexible Digital Lighting
Controller gives you lots of options,
both in terms of how you arrange the
lights (using LEDs, mains-powered
lighting or a mixture of both) and also
how you control them, using a PC, Arduino or Micromite with your own
control code, or using our sequencing software.
We’re looking forward to seeing
what incredible displays our readers will create, using this design as a
starting point!
SC
December 2020 97
|