and Projects (Demos)
is no longer being updated.
You will be
redirected to the new Demos
Thank you for your patience.
a teenager and young adult I spent many hours assembling electronic
kits. My first ham radio transmitter was a Heathkit (as was the next).
In addition to ham equipment I also assembled test instruments,
home stereo components, computers and modems, and much more.
I enjoyed kit building as much as using the devices after they
were built (and in a few cases after they were repaired).
Over the last few decades electronic kit
building has fallen victim to advances in
electronics, especially the advent of large scale integration. Indeed in many US locations it is no longer possible to
find a nearby store that sells electronic parts. However, radio
and electronic project kits and ideas can still be found on the
Internet. Some of these are of
limited practical interest—perhaps only
good for the fun of building them, while others continue to bring
pleasure after assembly is complete. This page describes kits that I
have enjoyed putting together, as
well as other small construction projects, and one or two explorations
that have nothing to do with soldering. The accompanying video demos
illustrate highlights and lowlights of these activities.
bare-bones CW only QRP
transceiver from China, that operates within a narrow
crystal-controlled frequency range of the 40 meter band.
Its primary attraction is cost, which ranges from $5 to $15. Building a
transceiver for next
nothing has a charm similar to that of making a high frequency contact
less power. In
the demo videos linked below, Pixie is the small green circuit board.
components of the test setup, such as the battery, speaker, Morse code
and even the corner bolts, are not part of the deal. The
transparent enclosure shown in the photo (left) is an old phono
Pixie transmitting: Pixie-xmt.mp4
is a 40-meter CW or SSB receiver kit. It can be operated in crystal
can be tuned (with a fine touch) over a wider range of frequencies, by
jumpers to use an internal VFO. The internal tuning control is a
The kit, which includes the bright red enclosure shown in the photo was enjoyable and instructive to build.
State QRP Group)
(internal VFO): ssb.mp4
from Kits and Parts dot Com is a significantly more advanced QRP
transceiver than the Pixie, and more challenging to build.
Unlike the Pixie it does not generate low-level RF output in receive
mode! (That’s a good thing.) The
one-watter was my first experience with soldering surface mount
also my first time winding small toroids—interesting! As with the Pixie, the switches, knobs
and enclosure, etc. are not included.
and Parts dot Com): One-watter_demo.mp4
and Parts promises a 5 watt Class-C amplifier kit soon (http://www.kitsandparts.com/5W-A1-Amp.php).
With a bit of luck this page will include one more demo after Christmas.
assembling the ZZRX-40 I wanted to try another kit from the Four State
QRP Group. I did not need a keyer—my main rig has a
built-in keyer, as does the one-watter. On the other hand a
self-contained battery-operated keyer is not a bad idea. It
be taken anywhere and used for CW training or practice.
State QRP Group): testMsg.mp4
Tech Capacitance meter kit was featured in a recent issue
magazine (year 2016). Again, part of the appeal
is price, less than $20
including shipping. This kit is probably the most
useful of those featured on this page.
It was also easy to assemble and would make a good first kit for anyone
having little or no
previous experience with printed circuit boards. The photo shows a 36
pF capacitor under test—the
LCD reads ‘36.2P’. The display sometimes flickers through a narrow
values, with the midpoint taken as the capacitance measure.
JYE Tech Capacitance Meter
Kit (Amazon): JYE-demo.mp4
vacuum-tube era (also known as my
youth) dip meters were called ‘grid
and were considered a useful if not essential part of the radio
toolkit. Now it is hard to think of a persuasive argument
for owning one, which may explain the paucity of choices available to
purchase. Other instruments, such as an antenna analyzer, LCR
meter, oscilloscope and function generator, frequency counter or meter,
etc. serve as well or are superior in many situations.
out the MFJ-201
dip meter: dip_meter_test.mp4
DDS Code Practice Oscillator: This kit is
a tone generator—not
The tone produced is a pleasing one, a sine wave or pure
not a square wave. Audio frequency is adjustable over a broad
range and the direct output to speaker is loud and clear.
On first assembling the kit, the
work so I added a ‘temporary’
to use an external amplifier. Later when the internal amplifier was
working I left the amplifier jack in place and added a speaker jack.
I also added a small relay to key the CPO from the one-watter’s
transmit signal. This would be better done electronically. The
power supply is a 9 volt battery and 7805
At the Charleston Hamfest I picked up a
grab bag of PCB’s
and since then have
used one of them to consolidate the oscillator and mods onto one
board, making a somewhat neater package. At the same time I
replaced the relay with a DPDT version in order to use the second pole
for muting a receiver. The photo and video demo are of the original
messy assembly, however.
N4YG DDS Code Practice Oscillator Demo: CPO/CPO-Demo.mp4
WB9YBM Analog Audio Oscillator:
February 2017, pages 46-47 —
circuit is not a kit (yet)... I constructed it first on a
breadboard and then transferred it to a generic PCB (the leftover half
of a board that I’d
cut in two
for the N4YG oscillator modifications). It was fortunate to
the circuit on a breadboard first, as the diagram in the QST
article misidentifies the output of the 741 op. amp. chip as pin 5.
6. Upon correcting this error, the breadboard circuit
as described in the article. However, I prefer a lower
tone, so tried a few combinations of R1, R2, and C2 + C3.
Then I had the idea to connect R1, R2, and the capacitor to an 8-pin
header that could be unplugged and swapped if desired, a poor man’s
Another sort of crazy reason for doing this is that I did not have any
8-pin dip sockets and thought it would be a good way to fill up the
empty half of the 16-pin socket for the 741. The RC values in
photo are 0.1 µF for C2 + C3 and R1 = R2 = 10K.
Analog Oscillator: WB9YBM_oscillator.mp4
Coax Continuity Tester: This
was a homebrew project, not a kit. The object was to play around with
logic circuits (TTL) and computer software for logic circuit design and
analysis. It is trivial to test the continuity of an ordinary length of
coax using an ohmmeter. Touching the probes to the center conductor at
both ends should show near zero resistance, and the same for the
shield. Probing between the center conductor and shield
indicate an open circuit (infinite resistance).
The tester pictured above has three light emitting diodes (some
additional wiring is not visible under the PCB). When a cable
connected between the two SO-239 jacks (or the RCA phono jacks),
pressing the left pushbutton (left end of circuit board) tests the
conductor. Pressing the other button tests the shield. The
green LED indicates that the tested conductor is good. The red ‘Open’
LED indicates a break in continuity, while the other red ‘Short’ LED
indicates a short circuit. Since the unit is battery powered I thought
it would be prudent to include a power indicator as well (lower left
I first drew the circuit using the
program Logisim. After making a couple of
simplifying revisions I constructed the project on a breadboard and it
appeared to work as intended. At this point I became curious
whether I could write out a logical expression for the ‘Good’
indicator, based on the four inputs (center left, center right, shield
left, and shield right). Using pencil and paper to construct an
equation I made mistakes, inevitably ending up with mismatched
parentheses or a missing or superfluous ‘not’ symbol. So
instead I wrote a simple computer procedure that accepts a list of
equations as input (each equation corresponding to a single logic gate)
and additionally a target expression (something to solve for).
By iteratively substituting symbols the procedure converts
the target to a form that references only input variables (i.e.,
when no further simplification is possible).
Using this ‘helper’ utility I was able
to obtain the desired expression
for the ‘Good’ indicator.
Next, a Google search for ‘logic simplifier software’ yielded several
relevant resources. The one that I ended up using is called Logic
Friday (another wonderful free program). My goal
was to create three expressions, one for each indicator LED, then to
simplify each of them, and in the end produce a simplified combined
circuit. However, when I entered the ‘Good’
expression into Logic Friday the program’s
truth table included two unexpected rows. After wasting a lot of time
proofreading the circuit and double-checking its breadboard
implementation a question popped to mind: Had I really tested the exact
combination of inputs that unexpectedly evaluate as good? The
truth table was saying that if one of the coax conductors was open and
the other not, AND if both buttons were pressed simultaneously the ‘Good’
indicator would illuminate. Upon testing these exact conditions that
what happened. This observation led quickly to a
minor change in the logic, after which the truth table exhibited by
Logic Friday consisted of only two rows, corresponding to a good center
conductor and good shield.
I am omitting details from this
account, which is already too long. However,
supplementary details may
be found here. The
logic diagram shown below is the circuit as implemented in the photo
above. It is revision 4 of a seat-of-the-pants
design. (Note that the two fault LEDs are themselves inverted).
Logic Friday includes a ‘Minimize’
option that accepts as input a messy equation and produces a minimized
version of the same logic. It is possible, in fact easy to
translate the minimized equation back into a circuit, where logic gates
correspond to operators. Combining separate minimized circuits without
further simplification leads to the following diagram.
Since the diagram above represents a
combination of three independently derived circuits, some redundant
elements are obvious
However, in general, minimizing logic in a small-scale circuit
such as this one is not necessarily the same as minimizing the circuit,
due in part to the way that gates are packaged in ICs. Other
considerations include the ready availablity of ICs or their cost if
they must be purchased.
Coax continuity tester: TTL/coax_tester_demo.mp4
This demo is about a small part of another project in which a
pushbutton switch (momentary on) will be used to cycle through a few
options, similar to the way a wafer switch would be used. In
project the options are different AF filters, each enabled through an
analog switch, specifically one-fourth of a 4016. That part
not relevant to the demo.
When I constructed
the switching circuit on a breadboard, pressing the button advanced the
switch through a random number of options, not just to the next one as
was intended. The
pushbutton’s contact was making
and breaking multiple times within the switching rate of the TTL
circuit (details of which are not particularly relevant)
—I intend to describe the whole thing later. The present demo deals
only with debouncing the pushbutton. The method used is the same as
described in a beautifully instructive YouTube video by Derek Malloy.
At a recent ham radio club meeting the presenter talked about Arduino.
A week or so later Radio Shack had a sale on Arduinos and my wife
bought two, one for herself and one for me.
My first Arduino project was a Morse
code sender—or second, if the
world’ sketch called ‘Blink’
on this page
I describe the WB9YBM analog audio oscillator. The idea of the present
project was to make Arduino key the oscillator, converting source text
to Morse code. The standard Blink demo included everything needed to
work this out (how to control a digital pin and how to introduce a
Both the project sketch (program
code) and accessory hardware evolved through a couple of
iterations. First I made an on-board LED blink the
Next, I added the rest of the alphabet and numbers, etc. and used one
of the Arduino’s
digital pins to key a relay. The Arduino output fed a TTL
that operated the small relay. Preliminary testing was done on a
with clip leads from the relay to a real Morse key’s
I began to tire of listening to “The
quick brown fox jumped over the lazy dog’s
figure how to load a huge volume of text, other than to insert it in
the sketch as data. So I switched instead to generating random 5-letter
groups. At this stage of development, code speed was a
and I thought of reading a speed value as binary (using multiple
Arduino input pins). In fact I coded this method of reading
speed, but before
implementing it in hardware, thought instead to use a potentiometer and
one of the analog input pins. This was much simpler. The
minimum speed was arbitrarily put at 5 words per minute. The expression
= analogRead(a0) / 32 + minSpeed;
The final change (so far) was to replace the buffer-relay
combination with an analog switch (4016). After verifying that the
simplified circuit worked, I transferred it from the breadboard to a
PCB and neatified the hookups, for example, replacing clip leads with a
phone-plug terminated wire that plugs directly into the oscillator.
The sketch (subject to change)
The adapter circuit is simple and doesn’t
warrant a diagram.
A 100K potentiometer is wired across the 5 volt source, with the wiper
connecting to pin A0. (A 10K pot would also work.) The 4016
control pin (#13 in my implementation) is connected to digital pin 13
of the Arduino, and the corresponding pair of analog switch pins of the
4016 (#1 and #2) key the
At some point I realized it would have been better to use an Arduino
prototyping shield (Proto Shield) than a generic perf. board. The audio
oscillator could be constructed
on the same board and powered from the Arduino’s
All of the discrete components fit on top of the
some wires had to be routed underneath to escape uncomfortably
tight spots. The
topmost trimmer potentiometer in the photo is the speed control.
The other two belong to the oscillator. The original WB9YBM
audio oscillator included a third potentiometer for setting
the bias to a precise value in order to prevent
clipping one half of the waveform.
I substituted fixed resistors, but maybe should
have kept the trimmer. In any case, the generated signal looks and
VFO: My next
Arduino project is more interesting than the Morse code generator, I
think. It is a DDS variable
frequency oscillator (VFO), designed
by AD7C and based
on the Analog Devices AD9850 chip.
I did not use exactly the same parts as
in the original design, and therefore modified AD7C’s
sketch a little. The rotary encoder that I used emits a great many
per revolution (600). For this particular encoder I modified the Sketch
to decrease its sensitivity to a comfortable level.
Highlighted lines are inserts in the original code. By responding to
every 20th pulse the ISR’s
sensitivity is decreased by a factor of 20. In other words it reacts
to only 30 of the 600 pulses per revolution (one per 12 degrees of
The second change also relates to the
rotary encoder. The one I bought did not have a built-in pushbutton so
I added an ordinary momentary SPST switch (shown in the photo above).
Even when de-bounced with an RC and Schmitt trigger, longer duration
button presses caused multiple step changes. My first thought was to
insert a hardware one-shot, but then I realized that this problem could
also be addressed in software.
Again, the highlighted code was inserted into the original
sketch, as shown. The only other changes to code were to
accommodate the different LCD that I used. These are minor and
At 7 MHz the VFO’s output
volts P-P and at 28 MHz about 0.2 volts P-P. However for the
demo below, instead of showing the oscilloscope display, I hooked the
VFO into the previously described ZZRX-40
kit receiver, and tuned across the 40 meter band.
I have not yet enclosed the VFO in a box. The
encoder (model LPD3806 600BM) came with no mounting hardware or
template, or for that matter even an English-language wire color code!
If I should manage to overcome the mounting
challenge I will post another photo.
misidentified the challenging part of enclosing the VFO. Mounting
the rotary encoder was easy, using
an analog of the Red
Green method but substituting a hose clamp for duct tape,
which would also have worked.
A bigger challenge was to cut a rectangular hole for the 16 x 2 LCD.
I was not able to make a straight cutout, using the Dremel.
Luckily it is possible to conceal the jagged cut with a
manufactured bezel. I suppose with a 3D printer or a laser cutter one
could construct a smooth bezel, but with my selection of
(and skill level) a homemade bezel would have been as rough as the
I have read discussions of how to make
professional looking letters on a panel, but that also doesn’t
look easy. With only an
on-off switch and frequency step button, lettering would be hardly more
than a decorative addition. On the other hand lettering would be a
useful skill to acquire.
After a few weeks exploring Arduino I wanted to learn about
Raspberry Pi, which I had imagined to be similar to Arduino. Both have
convenient physical interfaces—well-documented input/output
pins. What is called a “shield” in the Arduino world is alternatively a
“plate” for Pi. On first encountering these terms I thought they were
clever wordplay-like terms for the same essential thing. That
was an oversimplification, and not my only erroneous preconception.
Pi and Arduino are different
concepts. First, Raspberry Pi is a computer with an operating system (Debian
Linux), while Arduino has
only a program loader and basic I/O functions
operating system, as such. This difference has broad
implications. Arduino is a real-time device, while Raspberry
sophisticated OS manages resource sharing. —Raspberry
applications are small fish in a big pond.
The fact that Raspberry Pi runs Linux
has fantastic advantages, of course. I will return to this point, but
my initial approach to exploring Pi was influenced by the earlier
Arduino experiences. Both Arduino and Pi have SDA/SCL pins supporting
serial I/O, so my first Pi exercise was an attempt to write text to a
small LCD screen,
similar to how the same would be done in Arduino. At this point I was
working with a Pi 1 (26 GPIO pins). Source code for this exercise is here.
This small test project includes one possibly interesting feature,
namely a shutdown switch. With Arduino there is no harm in pulling the
plug at any time, however, switching Pi off without proper OS shutdown
could cause file system corruption. The program detects a
button press from one of the GPIO pins, then shuts down via an
exercise 2 - failure to
my next exercise, which dealt with signal-level conversion
(hardware) and interrupt
processing (software), I
used a new Pi 3 Model B. While Arduino digital I/O pins are 5V (TTL
Raspberry Pi pins are 3.3V. In order to function as a TTL
input a GPIO 3.3V signal needs to be raised to 5V. For this I
used a TTL level shifter from MCM
Electronics. However, it should also be possible to accomplish the
required voltage level change with ordinary components.
The application itself was a
keyer. It was supposed to make either dots or dashes on touching one of
two capacitive sensors (see photo). In other words the program
would be an “event driven” application. Sometimes when I touched one of
the sensors a stream of dots or dashes would be produced, but other
times nothing happened. Once in a while, either a dot or a dash would
stick in the on
state. My first thought was that input pins were not
reliably firing or that corresponding interrupts were not being caught
reliably. Both these guesses were wrong.
In the back of my mind the program’s
structure was suspect, as
code to produce dots and dashes directly. As a final try I reorganized
the program so that event
handlers only set or reset global flags indicating to start or stop a
dash stream and nothing else. The part of the revised program
produces dots, dashes, and characters (the main part) executes a
Moreover, the revised
program runs ‘nice’-ly,
relinquishing time when idle.
Adafruit has a half-size prototyping PCB kit
that comes with a socket. I figured it would be just barely possible to
fit the Python keyer’s GPIO interface components on the small proto
board and although I will never use this keyer I wanted to do this—well,
I already had a
26 pin cable that mates with the proto board socket, and thought I
could plug the other end into the Pi’s
40-pin socket by sanding a little bit off the plug end. This much
worked, but I hadn’t
noticed that the ends of the ribbon cable plug are what hold it
When the sanded end came apart I pushed the top of the plug back on and
the continuity of each pin with an ohmmeter. Then I Epoxed the housing
and made a mental note not to pull on the cable while disconnecting the
plug—of course, one
should not do this even with an unmodified plug, but ...
There was no room for the touch sensors on the half-size board and, in
any case, they were not relevant to the main ideas being tested. In
place of on-board sensors the small PCB has headers for attaching
either a paddle or other accessory.
The test rig
for the Pi software keyer involves so many interconnected pieces as to
into question the sanity of whoever thought it up:
As mentioned in the preceding paragraphs
I originally used touch sensors for testing the Python keyer. For
curiosity and comparison’s
sake I decided to mount these sensors in the shape of a paddle. The
is different than when using a real key or paddle. Instead of pressing
side-to-side, the finger and thumb are positioned close to the sensors
moved in to touch one or the other lightly. Not much can be said for
this concept, except that it more-or-less works. One
is needed, as the sensors require power.
As previously remarked, Raspberry Pi is a full-fledged computer. Many
Linux applications run without modification, while others have been
ported to Raspbian. A software defined radio application Gqrx as well as the popular GNURadio signal
processing tools both
function at least in a basic way under Raspbian Jessie (see photos). A
NooElec R820T dongle was used to exercise the software defined radio.
Gqrx demo: TARC_net.mp4
A special variant of Raspbian runs on a
small LCD touch screen. I tried this, but cannot recommend it.
Taskbar icons were all scrunched up. It was difficult to
touch exactly the intended screen element,
even using a stylus. This small touch screen plate from Adafruit
may have some
use in the context of a dedicated Pi application, or with a different
OS configuration than the one I tried.
Finally, although of no relevance to
radio or electronics experimentation, I have written about porting a
heavy-duty database application to the Raspberry Pi here.
This project did not involve Raspberry Pi, except that the idea
came from a published list of interesting things to do with a Raspberry
Pi. One suggestion was to receive and decode navigational
information transmitted by aircraft using a system called ADS-B. The ADS-B system operates
at 1090 MHz (or 1.090 GHz). By way of comparison, the AIS system used by ships operates
at 161.975 MHz, not very far above marine VHF frequencies and the
2 meter ham band.
Out of curiosity I tuned SDR#
to 1090 MHz using a 2-meter antenna. With this arrangement I could see
occasional activity above the noise in the SDR’s spectrum display,
especially when an
aircraft was near enough to hear its engines.
A quick Google search yielded several excellent ‘how to’ articles for
making a 1090 MHz antenna, for example, https://www.balarad.net/
From these and similar articles it seemed the design of choice for this
frequency and service is a collinear, made from 75-ohm
In less time than a typical search
consumes I found a piece of RG6X that
was still in a sealed plastic wrapper—it must have belonged to some
appliance from years ago, maybe a TV or video player. Being unsure what
sort of precision was needed I looked up the velocity factor for
RG6X and found that published values vary by manufacturer and type, but
hover around 80%. Thus, at 1090 MHz a half wavelength is about 11
centimeters, which is not coincidentally the value cited in
After just a moment’s hesitation I
F connectors off the ends of the 4-foot length of RG6X, and cut the
into 15 cm pieces. Following published guidance, I trimmed 2
centimeters of braid and foam from each end of the cut pieces.
Unfortunately I did not take
photos of construction in progress. The piece shown above
was left over, as I used only 8 segments in making the antenna.
Construction was simple, though. The center conductor of one piece gets
connected to the outer shield of the next, by pushing the solid center
conductor between the shield and outer plastic jacket. A couple of
details may be
worth noting. First after cutting, I cleaned the cut ends
carefully to ensure that no stray ‘hairs’ from the shield could short
to the center conductor. Then on joining each segment I tested the
entire length up to that point with an ohmmeter, both for
continuity and the
absence of a
short. Articles I’d read suggested wrapping the joints with
electrical tape. I did this and also covered the tape with
shrink wrap. When finished the total length of the 8 connected
half-wave segments came to approximately 35 inches.
The next problem was to figure out how
to make the antenna stand straight up, while avoiding the use of metal
parts. To this end I spent $2.00 for a 10 foot length of CPVC, and from
that cut a 35 inch piece. The blue plastic cap at the top
from the ‘strings too short to use’ jar. Two questions still confused
me. Should the end of the antenna be terminated with a 75 ohm resistor
or not? I had a 75 ohm resistor but couldn’t think why it would be
needed, so I did not use it. The second question was whether or not to
make a 75 ohm to 50 ohm transformer. At least one article suggested
connecting two 1/12 wavelength pieces of coax (75 ohm and 50 ohm) for
impedance matching. One twelfth wavelength would be less than 1-inch at
but how would that differ from connecting the 50 ohm coax directly to
the 75 ohm antenna? It is surely different in some way that escapes my
understanding. However, I did not do this.
On placing the 1090 MHz collinear
antenna on the balcony outside
and connecting it to the
NooElec RTL-SDR, I found that 1090 MHz was
alive with some sort of signal, but what? Through earphones it sounded
like a mix of tones and static. I didn’t know what modulation mode or
set in the SDR, but surely these signals must be ADS-B because they
were the right
frequency, and much stronger and more continuous than those previously
observed with the 2-meter antenna.
Yet another Google search led to several
ADS-B decoding accessories, including RTL 1090, DUMP 1090, ADS-B#, FlightAware
ProStick, MATLAB(!), and the one I ended up using for this
Figuring out how to run ModeSDeco2 was a little tricky. The supplied
example .bat file referenced a couple of databases that were not
included. However, I found through experimentation that the program
would start and run without these databases. In retrospect, it would
have been beneficial to have read the ‘Help’ file before starting! I
had expected at first to
use an SDR program, such as SDR# to receive the signal, and then pipe
audio to the decoding program. However, ModeSDeco2 does not work this
way. Rather it receives the signal itself directly from the RTL. Thus
this program can be used without an SDR program. In fact, it is not
possible to monitor the signal concurrently (using the same physical
device) with another SDR
application, as the
decoder ‘owns’ the RTL-SDR.
At first I did not believe the displayed data, thinking both quantity
and quality were too good to be true. However, upon
the antenna decoding stopped completely. Moreover, the
information being displayed described flights that were currently
within about 50 nautical miles of my location. There could be no
question that the program was decoding real-time radio transmissions as
received by the antenna that was sitting out on the balcony table.
serves decoded data as HTML pages, over whatever TCP/IP port was
specified when starting the program. In addition to the tabular form
illustrated above, the program also produces a Google maps projection,
showing the current position and direction of flight for tracked
aircraft (video demo below). Other pages show charts and statistics,
such as the number of messages decoded per second or per hour, and a
graph of contacts by distance. Based on data from the latter chart, the
most distant messages decoded in the first day of testing were 80
nautical miles away.
Collinear demo (with assist of RTL-SDR and ModeSDeco2): ADS-B.mp4
While rummaging for bargains in the Radio Shack store closing sale I
came across a couple of small boxes labeled ‘X-Bee Shield’—I think the
price was $6.00, XBee
not included. At
the time I did not
know what an XBee was,
but for $6.00 and some unknown but presumed-small additional cost I
might find out. A few weeks later I purchased a pair of 2.4 GHz XBees
for $12 each.
The USB adapter that was needed for setting them up was an
additional $10. All considered, to learn a little about XBees
was not an expensive proposition.
On-line tutorials and examples typically
feature one XBee connected to the computer via USB and another
connected to an Arduino. The program XCTU (free download from DIGI) can be used to configure
XBees, and to setup a pair of them to communicate with one another. In
addition to its configuration options, XCTU
includes a console that supports bi-directional wireless communication
between a computer-connected XBee and another one at a distance away.
All this is documented in multiple places. However, I wanted to make a
different kind of demo, one in which both XBees would be Arduino-based,
neither connected to the computer or the XCTU utility software.
The idea that sprang to mind and the one
I will describe here was a simple number guessing game in which one
Arduino would pick a number and the other would guess it, transmitting
each guess wirelessly. On hitting upon the right guess, the turns would
change. As imagined, the demo program or ‘sketch’
would have no intelligence, but would simulate an autonomous
conversation between XBees—actually
are only the radio part.
Before writing the demo sketch I first
created a simple test program that would transmit a single
byte, or receive a byte and return a one byte reply. In theory, for
this test Arduino’s
on-board LED (pin 13) would fire whenever a byte was received. However,
the test did not work—how
could such a simple program fail? Or, more basically, given that it had
failed, how could the program be debugged? In order to see what was
happening during execution I wrote a simple subroutine that would flash
an attached LED
n-times. By observing the number of flashes, it would be possible to
deduce where failure occurred. Alas, there was no obvious failure.
Every part of the sketch—there
being reached, and executing,
yet nothing happened. This caused me to wonder if I had inadvertently
fried one or both of the XBees. But that was not the explanation. On
testing each XBee again, using XCTU, they both checked good.
Something was different between the XCTU
test and the Arduino-connected XBees test. As I thought about this I
realized that I had not configured the XBee shield jumpers, having
assumed that they
were connected to the appropriate pins for Serial communication,
This was not the case. The default Arduino Uno UART pins are D0 and D1,
while the XBee shield (out
of the box) had jumpers
on D2 and D3. Of course, I should have checked this at the beginning,
or at least have read the Serial documentation, but what can
say... Obviously serial communication does not work unless something is
connected. After transferring the XBee transmit and receive jumpers to
Arduino’s default serial
com pins, the test sketch behaved in the expected way.
The rest was anti-climax. The
number-guessing game sketch also worked more or less as had been
imagined. With the program loaded the XBees began an animated
conversation in their rather limited blinking LED
language. The demo sketch provides an
easy-to-understand starting point for Arduino XBee serial
communication. The same program runs in both XBees, except that near
the top the constant GOFIRST should be changed to false for one of the
Arduinos. A small amount of additional code might eliminate this
variants, different numbers of LEDs or different
Arduino pins, etc. should require only minor
XBee demo: XBee/friends.mp4
far apart can XBees be?
The particular ones I tested cannot be very far from one another. When
placed across the room or in nearby rooms they
continue conversing. However, at greater distances they lose
contact, and stop talking. On looking into this I found that the units
I bought are the lowest power type at 1 mW. More powerful versions
are readily available, as
are other similar Arduino-compatible transceiver chips that operate in
the 915 MHz band, where distances of up to a few miles are possible.
Although the number guessing game was
just a demo, I wanted to address the case where the XBees go quiet
after losing contact. The sketch should be able to detect when they are
stuck so that they can unstick themselves. To this end I made a small
auto-recovery patch. It works like this: First there’s an ‘idle
timeout’ number. It is either zero (meaning the auto-recovery feature
is not implemented) or it is a small random amount more than twice the
time between games. Second, there is an active timer that
resets whenever a byte is received from the other XBee, in other words
whenever the normal thing happens. Finally, if the
timer reaches a value at least as great as the timeout, meaning no data
have been received for too long, then it goes into auto-recovery.
The first thing auto-recovery does is
switch turns, in case the two Arduinos are on the same turn, as seems
to happen on signal loss more often that I would have
guessed. If this particular try doesn’t work it will switch
turns again in a short time, sooner or later getting on the right
(complementary) turn even if both are concurrently trying to
recover. Next auto-recovery transmits a byte that can be
interpreted either as a bad guess, in case the other one is waiting for
a guess, or as ‘your guess was correct—OK
to start another game’, in
case the other one is waiting for feedback.
Finally, it flashes the blue LED (three flashes) so that a person can
tell that a recovery attempt is executing. Recovery also
resets the timer, in order to allow time for the other XBee to respond
before starting another recovery attempt.
expectation was that when the XBees were stuck it would be necessary to
move them closer together, so that they would resume play after recovering.
What actually happens is they resume play right there and then, without
being moved again. When a signal is good enough for play most of the
time, but not sufficient to prevent occasional drops, they are able to
resume or continue play, generally for a few games, before getting
stuck again and repeating the cycle. To observe long-term
stoppage it would be necessary to position them far enough apart that
they have no signal most of the time. Note: For running
the demo sketch (either of them), the Arduino that has the ‘GOFIRST
= false’ edit should be started first.
Decoding ACARS: Shortwave
listening (SWL-ing) is not what it used to be.
satellites and the Internet, the high frequency broadcast bands 49
meters, 31 meters, 25 meters, and beyond were alive with news and
commentary from every conceivable point of view, as well as music,
drama and other forms of entertainment. The most recent major
broadcaster to abandon shortwave was Radio Australia in
early 2017. The majority of the world paid little heed to this event,
but to dedicated shortwave listeners the demise of Radio Australia was
a cruel blow.
While shortwave broadcasting has
declined the challenge of shortwave listening remains strong.
The number and variety of listening targets still suffices to fill
books such as the World Radio TV Handbook. Furthermore,
many services and modalities exist today that were not imagined during
the heyday of shortwave broadcasting. Instead of voice and music one
can receive weather satellite images, as I described here,
or images from the International Space Station, or position reports
from ships at sea, or countless other services. Ham radio has also
changed. In addition to Morse code and voice, multiple digital signal
modes can be found across the amateur radio bands.
on this page
I described receiving data from aircraft on 1.090 GHz (ADS-B). The
FAA has mandated that all US aircraft be equipped with ADS-B by the
year 2020 (AOPA). However, aircraft also
transmit data via a long-established system called the Aircraft Communications Addressing and
Reporting System (ACARS). This system operates on various
frequencies in the aircraft
mode is AM. ACARS frequencies range from a few
megahertz below the marine VHF band, so a marine band
antenna should work well enough to explore the modality. As a first
step I connected a small masthead-type marine VHF antenna to the
NooElec dongle, and tuned SDR# to the primary worldwide ACARS frequency
131.550 MHz. Right away I heard intermittent beeps or buzzing sounds.
The next problem was to locate and install ACARS decoding software.
Previously for ADS-B decoding
I had installed ModeSDeco2.
Turns out there is a companion piece called ACARSDeco2.
The ACARS decoder works similarly to the ADS-B decoder, in that the
software does not rely on an external receiver or SDR, and like
ModeSDeco2 it formats decoded data for display in a browser. ACARSDeco2
is able to decode signals from up to three nearby frequencies
concurrently. At first I was surprised to see only textual data in the
program’s output. I had imagined there might be graphs or a map in the
browser view. This misconception led to an abortive attempt to
integrate the decoder with a virtual radar application, a sidetrack
that was not particularly instructive.
A subsequent Internet search revealed another decoding application
that seemed to be more widely used than ACARSDeco2. I was curious as to
differences might exist between the programs. The acarsd decoder does
not have a built in SDR, rather uses a sound channel for input.
Therefore I configured SDR# as its signal source (same antenna and
as before). However, nothing decoded. Various discussion threads
suggested that if there are no decodes, it is likely that the wrong
sound source has been selected. But this could not have been so, as I
was able to change the indicated
(on the acarsd status bar), by increasing or decreasing the volume in
SDR#. Sources also gave different recommendations for the
level; some said that background static should be less than 10 while
others said more than 20 (as indicated in acarsd). I tried very soft to
very loud and everything in between.
Over the course of two half days I varied every conceivable setting,
although I had read that the program should simply work without
changing anything, unless necessary to specify a non-default
sound source. There was not a single decode! All I ever saw was the
pretty startup screen, unless of course I cleared it or selected a
different screen. Tables of messages received and processed, etc. were
filled with zeros.
My wife N4EFS
who is good
with coercing recalcitrant software to do what it is supposed to do
offered to have a go at acarsd. However, I
did not want to be embarrassed by her solving the problem in a matter
of minutes after I had spent hours on it, so I
explained that the configuration utility was a separate executable, not
an option within the acarsd program. Back and forth configuration and
testing would be a time consuming effort. Then, somehow the threat of
having help triggered a thought. With a different signal source, acarsd
testing could be freed from dependence on the
SDR. Another obvious advantage would be that the two
programs could be run at the same time on the same computer, one with
the dongle and the
other with a separate receiver.
To test this idea I connected a 2-meter
JPole antenna to our Icom
and ran a patch cable from the radio’s external speaker jack to the
computer’s primary sound card line-in jack. Success! On tuning the R100
to an active ACARS frequency, the program immediately began decoding
signals. Its volume indicator was in a range previously tried. In fact,
volume doesn’t seem to matter much. In the illustration above, the
volume indicator reports 15 (card 1, left channel). To the ear, signals
from the R100 sound about the same as those from the RTL-dongle with
SDR#, maybe a little more bass. —I
have not tried a different SDR.
As previously mentioned ACARSDeco2 can monitor up to 3 frequencies.
However, it decodes more messages than acarsd does at
the same frequency.
The comparison is not fair, of course, different antennas, likely
different receiver sensitivities, different sound bandwidth and level,
etc. On the other hand the acarsd program retrieves supplementary
information from the
Internet to produce an enhanced display, such as for example, to
include origin and destination airports for a flight. This results in a
more satisfying user experience.
- In the part of the demo where both applications are shown
side-by-side, sound is from the external receiver (131.725 MHz).
Nano - Soil Moisture Study:
A three-pack of Arduino Nano microcontrollers sells for $8.79, or did
when the packet above was purchased. That is less than
$3.00 each. Unbelievable! For previous Arduino studies I had used the
popular Uno board, being only vaguely aware of other options.
The Nano is smaller than the Uno and boasts nearly
the same functionality. It supports eight analog channels, as compared
six. However, it has only a single power
jack (a USB micro socket), while the Uno has an additional round
connector and on-board regulator, so that it can be powered from a 9
volt battery or etc.
It is also possible to purchase a Wi-Fi enabled Nano—that
is, a Nano with Wi-Fi on the same PCB. The form is slightly
larger, but not by much, and the cost a little more than for the
plain version. The project I am going to describe is based on one of
these Wi-Fi enabled controllers.
For ham radio high frequency operation we use a vertical antenna. Our house sits
on a small lot and,
due to HOA restrictions
it was necessary to locate the antenna in the back, away from street
view. With limited space available we were able to deploy only 14
radials, half along a six-foot strip at the back and half along the
east side of the house. Nevertheless the antenna performs surprisingly
Based on casual observation we felt that radio reception using the
vertical antenna improves after a good rain,
other things being equal. Rain of course soaks the ground
radials are buried, and water makes the ground more conductive. We
think this change affects antenna performance in a favorable way. On
other hand, a great many factors influence high frequency radio
reception. (Other things
are never equal.) It
possible that our observations are nothing more than coincidence in
light of imaginative interpretation. Nevertheless, while casting about
for something interesting to do with Arduino it occurred to me that the
ground conductivity hypothesis might be put to the test by acquiring
on ground moisture or wetness, together with some sort of systematic
performance. While it was far from evident what the latter might be, I
thought it could be fun and instructive to tackle automatic ground
moisture monitoring using an Arduino.
Although my interest in the subject relates primarily to
radio reception, on searching the Internet I discovered that the main
reason for sensing or measuring the water content of
soil has nothing to do with radio. It is instead about growing crops
efficiently! The first article I read came from a physics conference,
and then there were several articles from university engineering and
agriculture departments. Technical methods described in these articles
seem complex, impedance of soil at radio
frequencies, time domain
reflectometry, even an
atomic method based on the fact that hydrogen in soil absorbs gamma
rays. To be fair, a few articles touched on simpler methods and
probes, but it wasn’t until the context shifted to home
gardening that readily accessible search
results began to appear.
The sensor pictured on the left sells for $12.90 from Amazon and is suitable for use
with potted plants or similar applications where it can be protected
weather. On seeing a reference to this sensor I guessed that it could
used to test the Arduino-based data acquisition concepts, if
exercise all components of the project, except whatever probe would
eventually be deployed in the
Using a Nano (not Wi-Fi enabled) I tested the sensor dry and then
dipped it into a glass of water. To my great pleasure numbers displayed
via the Serial channel reflected the difference unambiguously.
I am omitting details at this point, but the difference
between wet and dry from the 10-bit A/D conversion was on the order of
a few hundred (table excerpt on right).
It was obvious that if the planned application should not have to
to a computer all the time, some means of displaying or storing
data would be needed that did not rely on the computer’s serial
wife had previously experimented with a temperature and humidity demo
application that interacted with an on-line ‘Internet of
and also in another separate part displayed
values on a small Oled module.
I decided to combine these ideas, essentially to construct a hybrid of
demonstration examples, for sensing, displaying, and uploading ground
To connect to the Internet without being
tethered to a computer meant switching to a Wi-Fi enabled Nano.
This change incurred a potential disadvantage. The single board Wi-Fi
Nano has only one designated analog pin A0,
compared to the eight A/D channels available in the regular version.
that only one sensor probe could be connected to the controller.
Testing with the capacitive sensor was
efficient, because the sensor recovers from wet to dry instantly.
Evidently electrodes embedded in the PCB material do not get wet and
the outside surface is easily wiped dry. Once the program (Arduino
sketch) was working satisfactorily
with this test sensor I began
to wonder how much trouble it would be to substitute a weather
resistant sensor. I had set aside the whole issue
of a practical or deployable sensor. That is when I hit upon an article
that describes a resistive probe made from junk parts and
This simple probe seemed almost too good to be true.
Over several days I made a few probes of different sizes but similar to
the one described in the ‘Cheap Vegetable Gardener’
article. After probes had dried for a day or two I
them under various conditions. The results were befuddling at first.
When wet or just damp, the probes were batteries, reading somewhere
in the range of 10 to 80 millivolts. They also retained an applied test
voltage after disconnection. For one of them I measured the
time constant using a 100K resistor in parallel. The value was 20
seconds, meaning the capacitance was a whopping 200 μF. Subsequently on
low-level (sine wave) test signals from 1 KHz to 1 MHz and measuring
effect on these signals I became increasingly confused. Finally I
abandoned this approach and instead applied 5 volts DC to a voltage
divider, of which one component was the probe. Regarding the probe as a
resistor led at last to reproducible test values.
Although calibration values (minimum and
maximum numbers) differ between the capacitive probe and these
homemade probes, which also differ to a lesser degree among themselves,
thought it should be possible to connect either type probe to the
Arduino without rewiring. To this end I made an adapter for the gypsum
probes so they could be plugged into the same 3-pin header as the
probe. The header is wired to a 3.3 volt Nano pin for V+. As far as I
it doesn't matter (except for calibration) whether V-in or a 3.3 volt
source is used.
This open-source ‘Internet of Things’
resource provides truly amazing capabilities to the amateur
experimenter, including integration with the powerful MATLAB
computing platform (See https://thingspeak.com/,
I decided to give my first ThingSpeak chart
a high-sounding title,
truth the physical meaning of its source data is a bit shaky.
further experimentation and calibration it would be possible to
transform sensed values to millisiemens or some such standard for
but that goal seems fanciful at this point. It is also unclear how probe
conductivity relates to
is not soil. On the other hand it might be fair to assume that over a
long time period
the probe’s moisture
content will come to match that of surrounding soil. I am
Uploading data to ThingSpeak requires an
Internet connection, of course, and that is where it is helpful to have
a Wi-Fi enabled Nano. The
procedure for connecting the device to a wireless router is explained here.
Given the tiny foil antenna it was a little surprising that the
connection works reliably from one end of our house to the other. But
then why not?—cell
phones also have a good Wi-Fi connection throughout the house and yard.
The client setup for
also well explained on-line, and with demonstration examples.
sketch for this project
illustrates all these pieces—the
sketch is basically an assemblage of examples, tweaked specifically for
the soil moisture study.
To make further progress on the question that suggested
this project in the first place, it will be necessary to identify one
or more suitable
comparison measures of antenna performance. Ideally, analogous
procedures could be devised for acquiring such data automatically.
Although none of this is in hand, and may never come to fruition, I
have been reading ahead a little about how to assess relationships
between time series. It is important when comparing time series to sift
out potentially confounding effects, such as a mutual dependence on
time. Not surprisingly, this requirement leads to other challenges of a
Wi-Fi Enabled Nano
I have previously described a project based on the Analog Devices
AD9850 chip (see AD7C VFO
write-up above). The following paragraphs are about how to figure out
and test another DDS
chip, the AD9834.
board shown on the right in the illustration above was purchased on
eBay. It is similar to this one, with three SMA jacks
labeled Sine1, Sine2, and Square. The AD9834 chip is well-documented in
Devices datasheet and related application note. For example,
AN-1070 by Liam Riordan explains how to compute and load a
frequency into one of the chip’s frequency select registers. However,
seem to be few completely documented applications for this chip, and
none that I could find referencing the specific board I purchased. The
small mail packet from China included only the board—no schematic or
The PCB connector labels (left) were a mixture of familiar and
terms. Power connections and SDA / SCK were familiar, and RST for ‘reset’
was meaningful, although I didn’t
know what to do with it. I still do not know what
the abbreviations PS and PSY stand for, although I was able to deduce
what to do with one of them. By tracing AD9834 pin 15 on the circuit
board, I found that the chip’s
FSYNC (datasheet page 9) goes to the header pin labeled PSY.
Many hours went down the tubes in a variety of failed attempts to
communicate with the AD9834 before I came across a tremendously useful
test sketch authored by Alexander C. Frank, and originally written for
the AD9833. The sketch may be found near the bottom of this page.
The PCB master clock frequency is
stamped on the crystal (photo left). To adjust
Mr. Frank’s program for
this clock frequency is a
trivial one-line edit. That is in fact the only
thing I changed in the sketch. The wiring is also simple, once it was
clear which pin
was FSYNC (table above right). One other very minor clarification...
Arduino sketch uses serial COM for user input. When entering a
test frequency and waveform type use ASCII
10 (newline) as the
command terminating character.
Generated sine and triangular waves are
output via the Sine1 jack, while square waves are output via the
top-mounted jack. The oscilloscope probe was capacitively coupled for
the test sine wave shown above (7.036 MHz), but directly coupled for
the other two examples (100 KHz square wave and 5 KHz
triangular). In other words, while the Square wave output is centered
on 0 volts, the triangle (via Sine1) is centered on half its P-P
voltage, and the sine output would be also if the probe were not
The drop-off in output with increasing
frequency is greater than I recall seeing from the AD9850. Above 30 MHz
the signal is messy, and hardly measurable. Of course, these readings
reflect breadboard wiring, with a 2200 ohm load resistor. A better
result might be expected from an improved test setup.
DDS Demo: RTTY.mp4
AD9834 DDS and FSK (Part 2):
The above demo
video introduces something that was not discussed in the accompanying
an Arduino application called TinyFSK written
by Andrew Flowers K0SM. Two Arduino Nanos were used for the demo, one
running TinyFSK and the other to control the AD9834. Outputs of the FSK
Arduino connect to inputs of the AD9834 controller, as shown in the
It occurred to me
that the two programs (sketches)
could be combined and that one Nano would suffice for both FSK and
controlling the DDS. Blending the two programs turned out to be easier
than expected. Starting with TinyFSK, I imported just enough AD9834
control code to generate a sine wave for a specified frequency, and
then inserted calls to update the frequency at
each place where TinyFSK writes to a DIO pin.
It was unclear at first how to turn transmit OFF, but specifying 0 Hz
for the frequency worked! There
was no memory crunch, so no need to remove TinyFSK’s
DIO writes (FSK_DDS.ino).
the audio FSK
demonstration in the first part of the preceding video, output from the
DDS was fed to the computer sound card line-in jack. In the second part
of the video, the AD9834 was configured to generate RF at 7.1 MHz (+
FSK offsets). According to my calculation, output power was less than 1
milliwatt. However for this demo, transmit and receive antennas were
only about 50 feet apart.
The video does not
include an intermediate test in which an RTL dongle and SDR were used
to receive RF from the DDS. For this exercise, the receive antenna was
a length of wire hanging over the stairwell, no more than 10 feet from
the transmit antenna!
In the screen capture image, Termite
keys the FSK Arduino. On the right SDR# receives the 7.1 MHz signal.
Finally, MMTTY (upper left) decodes the
SDR’s audio output.
Observe that decoding lags a couple of characters behind the sender.
All this started as a small-scale
exploration of the
AD9834. I never intended to get into FSK, and certainly not to go
further than encoding and decoding a signal, but sometimes it
is hard to stop, even when one’s
better judgement screams ‘enough already’. Thus,
in a roundabout way I became curious about how to amplify DDS-generated
RF output. Although
the Arduino connection diagrams (above) include the legend ‘to
amplifier’, none of the demos involved an amplifier. At some point I
wondered whether DDS output could be boosted sufficiently to drive the Pacific
Antenna 10-watt linear amplifier.
That would mean increasing the output to a few hundred milliwatts at
least. Unfortunately I
know almost nothing about RF amplifiers.
An obvious next step was to examine a few example low-power RF
circuits, such as the Pixie or the One-Watter (both described near the
top of this page). I also found a couple of circuits on the Internet
covering the power range of crystal oscillator to fractional-watt
differing in detail, these reference circuits exhibit common features,
which I attempted to understand and duplicate.
A little bit of experimentation
with different components or values and two
stages of amplification eventually
led to a potentially exploitable result. RF output measured
3 volts P-P across a 50 ohm resistor. So far so good, although the
second stage transistor got very hot. To
the heat problem, I fabricated a heat sink from aluminum bar stock and
a ring terminal. (The idea of using a ring terminal for bonding the
heatsink to the TO-92 came from the Pacific Antenna QRP amplifier
project, where a ring terminal is used to draw heat from a diode.)
Loose wires are the bane of breadboard construction—the greater the
component count the more likely it is that something will work loose.
So it was with the amplifier. Sometimes it worked and sometimes not, so
I reconstructed the circuit on a generic PCB, more or less the same as
it was, adding a PTT relay and some test points.
Sometime later a transistor lead broke due to the heatsink bending
whenever the board was turned over, or from accidentally setting my
coffee cup on it. When this happened, I unsoldered the transistors and
installed 3-hole headers so that the transistors could be easily
replaced or exchanged for different values, etc. But that was later.
First I hooked the PCB preamplifier to the 10-watt linear.
Preamplifier output was not up to the linear’s minimum spec., but
“nothing ventured nothing gained.”
The entire test setup consisted of the DDS and control Arduino (still
on breadboard), the amplifier PCB, the linear, an MFJ-971 QRP tuner
(for the meter), and a 10 watt resistive dummy load (not the wire wound
resistor shown in the breadboard photo). The linear has a
transmit relay keyed by RF and there was barely enough RF to
it. In fact, transmit keying was not consistent. Sometimes it keyed and
sometimes it didn’t.
When fortune smiled, the tuner meter
moved. Yes I know it is ugly, but however
that may be, in my world when the meter moves the experiment must count
as a success! Of course,
something is not right. How
could a resistive load reflect a third of the power? A possible clue is
that RF signal quality degrades significantly when the PCB
amplifier is connected to the linear (with the latter powered on). To
investigate further I have ordered a few bigger transistors, with a
view to adding a third stage to the preamplifier.
(To be continued, maybe...)
of the routine ‘smoke tests’ carried out during construction produced
actual smoke. This does not happen often and was therefore especially
gratifying, although an acrid smell lingered for several hours
u-blox GPS modules: Much
of the information
to be presented in the following paragraphs (perhaps the useful part)
may also be found in a “Build this....” article,
Amateur Radio Club president
Radio amateurs deploy GPS modules in a
variety of applications, including APRS (https://github.com/4x1md/vx8_gps),
high-altitude ballooning (http://www.arhab.org/), or
possibly in the construction of a precision station clock. [Although
for station time, an Internet solution
might also be considered,
such as was described above,
or alternatively, long wave radio time, e.g., station WWVB
in the United States.]
The first u-blox GPS module I purchased
Neo-6M, similar to this one. I didn’t realize at the
time that a more advanced model the Neo-M8N was available for roughly
the same price (e.g. https://www.ebay.com/itm/142360007536).
These modules consist of a postage-stamp size evaluation board
the GPS receiver, a small battery, annotated serial interface connect
points (no header), plus an active antenna that attaches via a tiny and
rather flimsy connector. The idea must be that once the unit has been
mounted in an enclosure, the board and antenna will not be jostled or
fall apart, as they are inclined to do on the bench. The M8N also
has attachment points for an accessory antenna connector (not included).
The u-blox module can be interfaced
directly with a computer using a USB-to-serial adapter, or if the
computer is old enough, a hardware serial port (with appropriate
voltage conversion). Another option is to
use Arduino’s hardware
and software serial capabilities
for message forwarding. The present exercise employs the
I have long had difficulty with directions that appear to omit a
frame of reference. For example, if the weatherman says that
storm system is circulating anti-clockwise, I want to ask, “Do you mean
looking up into it or looking down on it?”
(S/he means the latter.) It is the same when directions say, “pin
2 is transmit.”
is talking? Is it device A or device B, and so forth? Possibly I am the
only person in the world with this problem. However, my point is that
whereas input-output connectors may have standard specifications, if a
communications channel will be defined on arbitrary pins (such as in
the Arduino software-serial setup), it is important to identify clearly
which pin serves which direction of communication.
Multiple Arduino serial
com pass-through sketches may be found on the Internet, for
example the one at https://blog.startingelectronics.com/how-to-use-arduino-serial-ports/.
They are all basically the same, up to naming of
variables and choice of transmit-receive pins. I have copied a
making only minor changes,
from the aforementioned link
Before abandoning my rant about specifying the transmit-receive frame
of reference, one final note: Care is also required to observe the
directionality of the hardware serial connection. The photo above left
that Neo-M8N connection points are directionally opposite to
those of the Neo-6M, other things being equal (chip side up, battery or
antenna location, etc). Of course, these evaluation boards came
from different suppliers and there may be no standard for such things.
In the example listing
above, selected data
columns have been blanked out. Well, from the remaining viewable data,
fixes were obtained somewhere on a circle that is 6,561 kilometers
from London, so the location isn’t 100% anonymous. The software that
produced this listing is called “FullExample”
and is part of the TinyGPS++ Arduino library (https://github.com/SensorsIot/TinyGPSplus-for-Neo-M8N).
I modified the sketch slightly to omit displaying asterisks when no
valid data are available. This and similar examples included with the
TinyGPS Arduino library should make custom applications
development an easy exercise. Another
excellent software resource is
the u-center suite (from u-blox), which may be downloaded here.
The green-on-black “Deviation Map”
reproduced at the beginning of this narrative is one of several views
furnished by the u-center software.
breadboard photo above shows a Neo-M8N
connected to an Arduino Nano by way of a bi-directional level
converter. The 3.3 volt
the Nano supplies power
to the GPS module, while GPS receive and transmit wires connect to Nano
D5 and D6, respectively. These pins are the same ones defined in
corresponding test sketches for software serial use.
Of course, other pins could be used instead, provided
wiring are consistent. Connections (in the photo) between Arduino pins
0 and 1 and the
converter at B1 and B2 are not relevant to the configuration being
A flashing green LED on the Neo board
indicates that the module is receiving sufficient
data for a
valid fix. This indicator is handy for checking things out at the
having to connect the module to a computer. Based on limited testing
the Neo-M8N appears to
be more sensitive than the 6M. A possible explanation
the M8N processes data from Russian as well as United States
testing inside the house, that is without a clear sky view,
the M8N quickly acquires a fix, while the Neo-6M may take
several minutes (or may fail completely on an overcast day).
It should not be surprising that
estimates derived from these modules are generally poor, because the
same is true of consumer GPS
devices. A quick Internet search yields several putative explanations
for the altitude anomaly, for example
the following, which seems plausible: http://gpsinformation.net/main/altitude.htm.
I have no particular goal or application
in mind for these units. One possibility is to interface
the M8N with a specific amateur radio transceiver.
Another idea that seems
logical, but I’m not sure is valid, would be to average many thousands
of fixes in order to derive an exceptionally precise estimate of a
specific (marked) location. According to scientists and the National Geographic Society, North
America is moving away from Eurasia at a rate of 2.5 cm per year. Hmm!
For fun I used Excel to compute the
average of 62,725 GPS fixes acquired overnight. I thought that the
result should provide a decent estimate of the latitude and longitude
of the bannister next to my computer desk. However, given this average
as input, Google Earth puts its stickpin over the next door neighbor’s
breezeway, about 10 meters from the true location. How
accurate is Google Earth? One supposes that cartographers have
referenced the photos to precisely known (surveyed) locations. But that
is only a guess.
GPS Demo: u-blox_modules.mp4
the GPS explorations described in preceding paragraphs, I was fairly
confident of my place in space, and began to think about different ways
of telling time. GPS time is straightforward. The satellites carry
clocks on board, and from the information they transmit it is possible
to extract the time with more than sufficient
accuracy to know when to take a lunch break.
I knew almost nothing about different
when I first started looking into the subject. However, I have learned
Atomic Time (TAI) is the gold standard for time, and has been since
1972. It is described here. Coordinated
universal time (UTC)
is based on TAI, but
with leap seconds added. The reason for adding leap seconds is to keep
UTC within one second of Astronomical Time, which (skipping many
details...) is based on
the actual rate of earth’s
rotation. The current method of measuring
and recording Astronomical Time is UT1.
radio station WWVB (60 KHz) transmits the time from Fort Collins
Colorado in a
slow digital format (1 bit per second). This is the same time (UTC)
transmits (and WWVH in Hawaii). However, in addition to
atomic clock time, WWVB
also transmits the difference to the nearest 0.1 second between UTC and
People for whom imprecision causes
distress may wish to know current astronomical time to the nearest one
second, rather than UTC from GPS or WWV or from
the computer (Network Time Protocol).
to radio station WWVB that is possible, although not quite
straightforward. Clocks (physical devices) that use WWVB generally
ignore the UT1 delta and display only atomic time, either to
seconds or minutes. To access the UT1 correction in WWVB
data, one is
obliged to receive and decode the signal at a lower level than
typically provided by off-the-shelf clocks. [In
truth, factors such as
propagation path may influence the accuracy of time received
Few radio receivers tune as far down in
the longwave spectrum as WWVB transmits. Fortunately, WWVB receiver
are inexpensive, for example: https://www.amazon.com/60kHz-atomic-clock-radio-module/dp/B01KH3VEGS.
[The similar one in the accompanying illustrations was purchased from
England a couple of years ago.]
Prior to undertaking the present study, one of my misconceptions was
that WWVB could only be received on the US East Coast during hours of
darkness. [My MFJ radio wristwatch synchronizes
with WWVB time, if
left on a window ledge overnight.] It would have been easy to test and
disprove this erroneous nighttime-only assumption by tuning a longwave
(or general coverage) receiver to 60 KHz, as demonstrated in the video
at the end of these paragraphs.
The photo (left) identifies components of a test setup. At first I did
expect to receive anything. That is why the receiver/decoder is not
connected to the Arduino in this photo. The larger
the beginning of this write-up and the dashed line (left)
shows where the receiver connects when actively
(real) green wire at the bottom comes from another Arduino that is
running a WWVB simulator from: https://www.popsci.com/diy/article/2010-03/build-clock-uses-atomic-timekeeping.
The decoding program (Arduino sketch)
that I used may be found in the comments section of a YouTube video
I modified this program to use Serial output in place of an LCD
display. My adaptation also ignores the NTP part of the program.
Finally, to have a clearer picture of
the raw data, I stored decoded bits redundantly for display via
the serial channel.
However, I did not modify the main decoding logic in this
very useful sketch.
The above clip shows decoding of the simulator
output. At this point I had attempted unsuccessfully to receive and
real WWVB signals. I sort of knew that it wouldn’t work, because at
this stage the receiver’s LED was blinking erratically, as if receiving
or attempting to decode background noise or static (video demo below).
always the antenna! I moved the small ferrite loop to a nearby window
ledge. The window faces west (toward Fort Collins) although I doubt
that matters. My plan was to start the decoder after dark and hope that
it would decode something during the wee hours. The first
decode to pass the program’s validity checker came at 11:07 PM EST.
As shown, the current UT1
(astronomical time) correction (called DUT1 ) is +0.2 seconds. Between
this first decode and daybreak just
30 valid decodes were obtained,
the majority coming in the last few hours of
darkness. The number of decodes was disappointing, however. I had
expected more, given that the MFJ radio wristwatch with its miniscule
internal loop antenna is able to receive WWVB at night. I
to try one more change to the test setup, namely a different slightly
larger ferrite loop, taped to a block of wood in order to clear the
window frame. At the same time I strengthened the program’s validity
check, although the original one (based on 13 bits) had not falsely
passed any invalid decodes.
To my astonishment this slightly revised
immediately produced valid decodes while it was still
PM Eastern time (2 PM Mountain time) on a sunny afternoon. Up until
this point I had thought that only nighttime reception was possible,
having not yet tuned an appliance receiver to the WWVB frequency.
this test (screen capture above), the sketch was modified to
display the bit stream of the minute corresponding to
the decode, in a shorter more readable format. A
comment in the original sketch explains, “WWVB sends the time AFTER the
time mark, so we need to add a minute for the correct time.” Between 4
and 8 PM, about 60% of decode tries
were valid. This percentage subsequently decreased, so it is possible
that reception was unusually good on this particular afternoon.
sequences of valid decodes were also observed in the pre-dawn hours.
revised validity checker occasionally reports a false
negative. In other words, it detects a bit error when the program has
correctly decoded day and time, and other values of interest,
for the same minute.
This brief exploration yielded more than the usual share of surprises,
and clarified some previously puzzling things for me. For example, I
had wondered how the MFJ watch was able to detect spring and fall time
changes, and adjust the hour hand accordingly, although not exactly on
the specified 2 AM hour. Daylight Saving Time information is part of
the WWVB message. (It is a 2-bit code: 00=Not DST, 10=DST begins today,
11=During DST, 01=DST ends today.) I was also curious how the radio
watch would know when to trust a time decode. (The watch only needs
hour and minute, and of course DST, but not day or year.) A guess would
be that it reads the mark and reserved bits, same as our first validity
check. It could perform more complex checks, such as requiring decoded
time to increment correctly on two or more successive
don’t know how it actually works.
If the tenths-of-seconds communicated by
WWVB’s UT1 correction is not precise enough,
one can obtain the exact duration of any day (rotation of the earth) by
According to experts the main cause for the slowing of earth’s rotation
is tidal friction: http://www.physlink.com/education/askexperts/ae695.cfm.
Curiously there will come a point when this particular cause is no
longer operative—billions of years hence, they say!
Time Demo: wwvb.mp4
My first Arduino exercise
was a Morse code sender
Later I reconstructed a sine wave
circuit on an Arduino prototyping shield, and integrated this with the
original exercise (details here
and in this follow-up paragraph).
By all rights that should have been the end of it. However, two trains
of thought led to the present extension. First I wanted the ‘sender’
to generate practice text that was more like ordinary language than
random five-character groups. Second,
I thought the device should include a keyer function.
These ideas led to others, and when I told N4EFS about the
came up with the name, “Mother of All Keyers” (MOAK for short).
The name is a joke, of course. Physical
of the MOAK are the same as those commonly found in other keyers, for
example, the audio
February 2017, pages 46-47).
generating circuits would have worked as well, but this one was
ready to use.] There is
not much else, after the Arduino and oscillator, just the LCD and
input/output support. The only unusual aspect of this keyer is its
Arduino sketch), which implements a unique mix of options.
On startup, the device displays a splash screen for five seconds,
followed by ‘Electronic Key’ (the first option), and finally the
current speed setting. The screen then goes dark. It is dark for the
‘Electronic Key’ and ‘Straight Key’ options and illuminated for other
options. The left button on top of the enclosure is the ‘Option’ button
and right is
‘Select’ in the prototype. Pressing the ‘Option’ button steps through
the option list
and pressing ‘Select’ enters (or enables) the currently displayed
Pressing the ‘Option’ button while running an option returns to the
‘Current option’ display, from which point the same or another option
A straight key or paddle may be plugged
into the front panel jack (lower right in the prototype). Connections
are standard for a
right-hand paddle (iambic key). The ‘Straight key’ function uses the
dash side of the key. The speed potentiometer knob on the
changes speed within a pre-determined range of approximately 5 to 35
words per minute. (Full disclosure: The upper end of this range has not
The block diagram
illustrates main components and their interconnections.
Pushbutton debounce circuits, each consisting of a pullup resistor plus
an RC and Schmitt trigger, came from this useful article. These were
constructed on a small generic circuit board (photo right). The front
control, a 10K potentiometer, divides the Arduino’s 5 volt DC supply.
Its wiper connects to an analog pin (A1 in the sketch).
The assignment of connecting pins is largely
and different pins could be used, except that analog pins A4 and A5 are
defaults in the LCD serial communications support library.
The choice of
transmit-out produced an amusing side effect. Since D13 is the
on-board LED indicator pin, the letters ‘H’
sound on power up (4 blinks, then 1). When loading a sketch from the
signals the beginning of the load and ‘E’
Nine currently coded options are
listed and explained more fully in MOAK_User_Guide.pdf.
Two of these options, 5-letter groups and 5-alphanumeric groups were
inherited from the original project. The rest are new.
is gibberish that is similar to English—many
of the ‘words’ are pronounceable. Pseudo-text options were
especially fun to construct, as they required a bit of
background study. Some time ago I had played with the British
National Corpus (BNC), a very large sample (or collection of
samples) of written and spoken English. At that time I excerpted
the XML edition of the BNC to a database, and indexed the data this way
and that, with a view to
doing something interesting with it—don’t know what exactly. For the
present project I computed a few simple statistics from this subset of
BNC, and combined these with intuitive guesses to create
pseudo-text generating rules. These rules,
embodied as arrays and
values near the top of the sketch,
the form of the text generated.
As such, they may
be modified experimentally to produce different flavors
of generated text.
Arduino’s pseudo random number generator
an unexpected way. Documentation for the randomSeed() method suggests
using an analogRead() of an unconnected pin. I tried this, but kept
seeing the same ‘random’ sequences on repeating the same option after a
Analog port readings produce integer values ranging from 0 to 210
− 1. However, the port’s
unconnected input voltage doesn’t exactly roam over the 10-bit
range. Perhaps with a noise source attached
it would. Eventually I
substituted a button press as the seed. The
millis() function returns an unsigned long, which matches the seed
parameter. After making this change, repeating sequences were no longer
The idea of incorporating sending practice came from a ‘CW
application designed by Tom Lewis N4TL (http://www.qsl.net/n4tl/). In the
‘Sending Practice’ option, the LCD
screen displays a string (generated by one of the listening practice
options). For practice, one keys-in the string that was displayed.
Each correctly keyed character gets echoed (as lowercase), while
incorrectly keyed characters are echoed in the way the program
interprets them, or as ‘*’ if not a recognized Morse character.
option is similar, except that the practice text to be keyed is not
only displayed but also sounded out. One may attempt to reproduce the
characters as they were heard, in addition to
relying on memorized dot-dash sequences. Sending
practice options require the use of a paddle—the
program cannot decode characters that are keyed-in with a straight key.
The prototype enclosure is a plastic box, approximately 8-inches wide
by 4-inches high and 2-1/2 inches deep. The Arduino and small PCB are
held more-or-less in place using long #2 machine screws and nuts. A
short USB-B jumper conveys power from outside the box to the Arduino
(and everything else). Point-to-point wiring is the usual rat’s nest,
due in part to the fact that most of the wire I have is springy stuff. —I
must purchase soft wire for the next project!
A 16 x 2 LCD may be substituted for the
20 x 4 display shown in accompanying photos. It should only be
necessary to edit the ROWS and COLS constants near the top of the
sketch. Option names were chosen to fit the smaller display. Similarly,
functions that support scrolling were coded to adjust
automatically for either display size.
The inside-the-box sidetone generator
omitted. The only
components that are required to produce the same functionality
as the MOAK are the
Arduino, LCD display, and option navigation buttons—and
of course, the sketch. If features are added in the future, I will post
a revised sketch.
MOAK demo: moak.mp4
The procedure for changing speed was a little awkward. This revised
includes a new speed adjustment mode. In this mode the LCD displays
current speed in words per minute, as the speed knob is being turned.
To enter this mode, press the ‘Select’ button from within any option
except sending practice options. In other words, press ‘Select’ instead
of the ‘Option’ button. Once
a desired speed has been specified, press ‘Select’ again to return to
normal operation. The User Guide
has been updated to reflect this change. The revised sketch
incorporates a few other ‘invisible’ changes, to improve efficiency and
anticipate possible future enhancements.
Arduino was a piece of cake! —That is, when compared to puzzling out
how to program a PIC microcontroller using Microchip’s
MPLAB X IDE
(version 4.05) and the PICkit™ 3 programmer. Looking
back on it, the effort should not have been as challenging as it seemed
to be at the time, but things that become
obvious in retrospect can be difficult to grasp when the language is
unfamiliar, or when one lacks confidence. Among the things
I did not understand at first were: 1) How to power the microcontroller
chip from USB
through the Programming interface, 2) How to refer to pins
on the chip using names that the compiler would understand, 3) How to
select or enable the chip’s
internal oscillator, 4) how to make timed delays, without a crystal and
finally, 5) how to disable the watchdog timer, or rather that such a
thing as a watchdog timer exists, much
less how to disable it.
Routing USB power to the microcontroller by way of the Programmer
wiring and a software setting. The latter is shown
searches did not return much useful information on the chip that
I was testing, except of course the datasheet. Later I came
to realize that the most relevant information was independent
the specific chip type.
Regardless of which microcontroller it is, Vpp goes to Vpp, Vdd to Vdd,
ground to Vss, data to data, clock to clock. Well, a point of confusion
was that microcontroller pins are multiplexed and serve multiple
just application-defined input or output, but other functions as well.
For example, the COM data input pin on the PIC16LF88 chip is
labeled RB7/AN6/PGD/T1OSI and the clock pin says
RB6/AN5/PGC/T1OSO/T1CLI. For different chips, the number of pins or the
pin numbering scheme may vary, but common functions are similarly
named. The answers were
there—I just did not realize at first that they were answers.
With an aim toward clarity, I tried a
different ways of illustrating connections from the programmer to the
chip. The Visio diagram (left) was about the best I could do. The Vpp
connection (orange line) is needed for programming, but not for running
(or when disconnected from USB and powered via Vdd). On the
microcontroller end, Vpp /
master clear is pulled high through a resistor when powered from the
target side. The
small capacitor from the MCLR pin to ground was recommended in a forum
thread. I am
not sure that it is needed.
These are the basic connections and
setup required to program or run a program on the PIC16LF88,
and probably many other microcontrollers. An external oscillator or
crystal would involve a couple of additional pins. Similarly,
for demonstrating anything, such as blinking an LED, at least one
additional connection would be needed. I used RA0 for the first blink
demo, then added RA1, 2, 3, and 4 just for fun. I have not exercised
My first programming test was intended
to make an LED blink once. Instead it blinked on and off continuously,
as if the thing had a mind of its own. This was extremely puzzling.
There was no way the program could be looping. Even so, I fiddled with
the program structure in crazy ways. The answer came from a Google
search on the terms pickit3
restarts main() this
thread. The following directive fixed the issue once and for
It’s funny how a little thing can gunk
up the works so severely. One can’t
be sure that the cause isn’t an
opaque programming error, or defective
wiring or a bad chip.
However, once the
watchdog timer was disabled, the test program began to behave in the
way. The LED only blinked when instructed to. Humans were once again in
For this first PIC exercise I used the free version of the MPLAB X IDE
with the XC8 compiler. For no particular reason I
decided to make the ‘Hello world’ code imitate an Arduino
sketch, initializing IO pins in a function named setup() and running
the demo in
loop(). Timing was a little funky. (I plan to add a crystal later.) In
order to use the XC8 compiler’s
built-in delay functions an
oscillator frequency should be specified, according
However, the _delay() function, whose argument is a number of
instruction cycles, produces the same duration delay whether or not
_XTAL_FREQ has been defined in the way suggested
at the ‘Developer Help’
page. Clearly there is much to learn, and many more experiments to do.
The present exercise is no more than a sort of necessary first step.
PICkit 3 demo: Hello_world.mp4
DS3231 real-time clock/calendar IC is based on a temperature
KHz crystal oscillator, with a claimed accuracy of ±2 parts per million
at ordinary temperatures (± 2 minutes per year). This little clock IC
all the features that a worthy clock should have, and it includes an
interface! The module pictured on the left was
purchased from Amazon Prime for $5.99, battery included! To get started
with it, I downloaded an RTC library from Adafruit, and ran their
simple and instructive demo from this page. Using a 16 x 2 LCD that
was on hand, I put together a simple clock display (photo right), which
amounted to little more than substituting LCD for Serial as the output
channel in the Adafruit example. In the back of my mind, or maybe
somewhere in the middle, was the thought of interfacing the WWVB receiver. This was not a
particularly compelling idea. Similar interfaces have been done
countless times, and in better ways. On the other hand, I had only a
murky idea how the clock and receiver/decoder could be made to work
together within a single control program. It
seemed, for example, that
the WWVB signal decoding part, which involves timing of level
durations, might complicate updating the clock display. The appeal of
the undertaking was the near certainty of learning something.
In the vein of keeping my options open,
I ordered a 4-line LCD. There
could be no harm in throwing something together on a breadboard, and
fiddling with a few possibilities. Meanwhile, I thought that a timed
interrupt might work for updating the real-time clock display without
interfering with WWVB decoding. Googling this idea led to another fine
instructional example: http://www.instructables.com/id/Arduino-Timer-Interrupts/.
—Interrupt service routines should be sparse. My thought was that the
ISR would not actually update the display, but rather signal when to
Most physical clocks have a convenient
way to adjust the time, such as pushing buttons or turning a knob.
Perhaps I should have taken time to do this. Things did not go smoothly
at first. Once the WWVB simulator was connected, the clock would get
synched to an old (simulated) date/time. Not only that, but due to
coding errors, the wrong year was being set, and Daylight Savings Time
was in effect in January! Those were my errors—nothing wrong with
signal decoding, or with the clock.
When the 4-line LCD came, I added WWVB data to the bottom line of the
display. This brought up an interesting sub-problem, namely how to save
WWVB data when power was removed from the microcontroller. The clock
has a battery and continues to run and keep time whether it is
connected externally or not. However, the Nano does not have a battery.
That is when I learned about Arduino’s EEPROM: https://www.arduino.cc/en/Tutorial/EEPROMWrite.
The complete Arduino (Nano) sketch is here: wwvb-RTC.ino.
When dealing with more than one time source it would be easy to lose
track of which source is responsible for a variable named ‘hour’ or
‘minute’. To help make their meaning clearer, I substituted names like
‘rtcNow’ and ‘wwvbSecond’, where normally simpler names would suffice.
While the display update is interrupt driven, the
internal clock update is not. Whenever a valid decode of WWVB data
occurs, the clock gets updated at that moment. Essentially all decodes
of simulated data are valid. However, as previously discussed, only a
fraction of real WWVB decodes are valid. In the first overnight period
of testing with the real receiver, 37 decodes were valid, the last at
07:26 UTC (2:26 AM Eastern Time). The antenna was the
loopstick-in-the-window setup, same as pictured in the WWVB paragraphs (above).
By the time the above LCD screen photo
was taken, I had transferred the circuit from breadboard to a generic
circuit board. This phase of the project did not proceed smoothly
either. I had intended to socket each of the IC-form components, but
decided for expediency to solder the level converter directly to the
board. This was a mistake. At first it appeared that the receiver had
stopped working, but on investigating I found the trouble was not with
the receiver but the level converter. To correct the problem I socketed
a second converter on a small accessory board and fastened the pieces
together, leaving the original level changer soldered in place, but not
The two I²C devices are wired
side-by-side at one corner of the circuit board. The real-time
clock plugs in battery side up and the 4-wire cable next to it runs to
LCD. A couple of jumper-header combinations serve as switches. For
example to turn off the LCD backlight, the jumper from D2 is moved to
ground. To run the simulator, the yellow jumper from D3 is moved from
the level converter to the output of an off-board TTL inverter, as
indicated in the
testing, no WWVB decodes were classified as valid that were not
actually valid. Therefore it is unlikely that an invalid decode might
misadjust the clock. Nevertheless, the validity checker could be made
stronger. For example, the decoded year should agree with the
clock year ± 1.
moment when seconds tick on the display is
not generally the same instant that the real-time clock increments
seconds internally. Moreover, the WWVB seconds counter can only be
trusted when there has been a valid decode. A shorter update interrupt
interval, say half a second, might improve display accuracy, but that
hardly matters. I even considered using two Arduinos, one dedicated to
the clock and the other to WWVB.
Two issues remain unresolved at this writing. The LCD occasionally
blinks dark-light for a fractional second—I don’t know why. Of more
practical consequence, the clock stops or freezes from time to time,
maybe when processing an invalid sync. Pressing the Arduino reset
button resumes processing, with correct time display and without loss
of WWVB data. If I
figure out what causes the interrupts or processing to stop I will post
an addendum or revised sketch. While
this narrative does not cover all of the project’s
travails, the diagram together with the sketch basically tell
the story, at least to the present point.
To download a video, right click on the mp4 link and select ‘Save link
as...’ or ‘Save target as...’ or play video from browser, if supported.
Project descriptions on this page are intended for entertainment only.
The author makes no claim as to the accuracy or completeness of the
information presented. In no event will the author be liable for any
damages, lost effort, inability to carry out a similar project, or
to reproduce a claimed result, or anything else relating to a decision
use the information on this page.