Kits and Projects (Demos)

    This page is no longer being updated.
       You will be redirected to the new Demos page momentarily.
            Thank you for your patience.

As 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.

Pixie    Pixie is a 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 to nothing has a charm similar to that of making a high frequency contact with one watt or less power. In the demo videos linked below, Pixie is the small green circuit board. Other components of the test setup, such as the battery, speaker, Morse code key, and even the corner bolts, are not part of the deal. The transparent enclosure shown in the photo (left) is an old phono cartridge case.

    Pixie receiving: Pixie-rcv.mp4
    Pixie transmitting: Pixie-xmt.mp4

ZZRX-40 (Top and Back)

    The ZZRX-40 is a 40-meter CW or SSB receiver kit. It can be operated in crystal mode or can be tuned (with a fine touch) over a wider range of frequencies, by configuring jumpers to use an internal VFO. The internal tuning control is a varactor.  The kit, which includes the bright red enclosure
shown in the photo was enjoyable and instructive to build.

    ZZRX-40 (Four State QRP Group)
        CW: cw.mp4
        SSB (internal VFO): ssb.mp4
        External VFO: xVFO.mp4
        Frequency: Freq.mp4

One-watter (Enclosed)One-watter (Circuit board)    The one-watter 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 capacitors, and also my first time winding small toroids—interesting!  As with the Pixie, the switches, knobs and enclosure, etc. are not included.  

    (Kits and Parts dot Com): One-watter_demo.mp4

    Kits and Parts promises a 5 watt Class-C amplifier kit soon ( With a bit of luck this page will include one more demo after Christmas.


EZ Keyer III

    After 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 small self-contained battery-operated keyer is not a bad idea.  It can be taken anywhere and used for
CW training or practice.

    EZKeyer III (
Four State QRP Group): testMsg.mp4

Capacitance Tester    The JYE Tech Capacitance meter kit was featured in a recent issue of QST 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 range of values, with the midpoint taken as the capacitance measure.

    JYE Tech Capacitance Meter Kit (Amazon): JYE-demo.mp4

Dip Meter

    In the vacuum-tube era (also known as my youth) dip meters were called grid dip meters and were considered a useful if not essential part of the radio tinkerers 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.

    Trying out the MFJ-201 dip meter: dip_meter_test.mp4

CPO in enclosure    N4YG DDS Code Practice Oscillator: This kit is a tone generatornot a keyer.  The tone produced is a pleasing one, a sine wave or pure tone, 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 built-in amplifier didn
t work so I added a ‘temporary jack 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-watters transmit signal. This would be better done electronically. The power supply is a 9 volt battery and 7805 regulator.

    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 

Audio Oscillator    WB9YBM Analog Audio Oscillator:  QST, February 2017, pages 46-47 This 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 Id cut in two for the N4YG oscillator modifications).  It was fortunate to have tested 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.  It is pin 6.  Upon correcting this error, the breadboard circuit functioned as described in the article.  However, I prefer a lower frequency tone, so tried a few combinations of R1, R2, and C2 + C3.

Tone frequency as function of RC
    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 tone control. 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 the 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 should indicate an open circuit (infinite resistance).

 Continuity Tester

    The tester pictured above has three light emitting diodes (some additional wiring is not visible under the PCB). When a cable is connected between the two SO-239 jacks (or the RCA phono jacks), pressing the left pushbutton (left end of circuit board) tests the center 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 LED illuminated).

    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 as to 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., stopping 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 programs 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 was 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).

Revision 4

    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.

Combined minimized circuits

    Since the diagram above represents a combination of three independently derived circuits, some redundant elements are obvious
(duplicate inverters). 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

Debouncing a pushbutton: 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 this project the options are different AF filters, each enabled through an analog switch, specifically one-fourth of a 4016.  That part is 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.

    Demo: TTL/debounce.mp4

    Arduino: 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 ‘Hello world’ sketch called Blinkcounts. Elsewhere 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 delay).

    Both the project sketch (program code) and accessory hardware evolved through a couple of iterations. First I made an on-board LED blink the letter 
‘v’. 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 buffer that operated the small relay. Preliminary testing was done on a breadboard, with clip leads from the relay to a real Morse key’s contacts.

    I began to tire of listening to
“The quick brown fox jumped over the lazy dogs back,” but couldn’t 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 constant, 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 is: sndSpeed = 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) is Morse.ino.txt. 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 oscillator.

    Demo: Morse_code.mp4

Improvement: 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 supply.

Oscillator and keyer components on prototype shield
All of the discrete components fit on top of the board, but 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 sounds good enough.

Demo: hybrid-shield-demo.mp4


    AD7C 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.

Components of DDS VFO

    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 pulses per revolution (600). For this particular encoder I modified the Sketch to decrease its sensitivity to a comfortable level.

Modification to decrease encoder sensitivity

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 turn).

    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.

One step per button press

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 not interesting.

    At 7 MHz the VFO’s output was 0.8 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.

Demo: AD7C_VFO.mp4

I have not yet enclosed the VFO in a box. The rotary 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.  

VFO Enclosure: I 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.

Rotary Encoder Mount (Red Green method)

    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 tools (and skill level) a homemade bezel would have been as rough as the original cut.

    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.

Front with bezel

    Raspberry Pi: 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 built-inno operating system, as such. This difference has broad implications. Arduino is a real-time device, while Raspberry Pi’s sophisticated OS manages resource sharing. Raspberry Pi applications are small fish in a big pond.

Station callsign

    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 os.system call.

Software keyer

    Pi exercise 2 - failure to success: For 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 level), 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 software 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
the event handlers invoked 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 dot or dash stream and nothing else.  The part of the revised program that produces dots, dashes, and characters (the main part) executes a continuous loop. Moreover, the revised program runs ‘nice-ly, relinquishing time when idle.

    Transfer to PCB: 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 together!

    When the sanded end came apart I pushed the top of the plug back on and rechecked 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 call into question the sanity of whoever thought it up:

There must be a better way! 

    Demo: python-keyer-revised.mp4

Touch sensor key paddle

    Touch sensor paddle: As mentioned in the preceding paragraphs I originally used touch sensors for testing the Python keyer. For curiosity and comparisons sake I decided to mount these sensors in the shape of a paddle. The ‘feel 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 and 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 additional wire is needed, as the sensors require power.  

    Paddle demo: pi-keyer-redux.mp4

Example applications

Pi Linux applications: 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

Small touchscreen

    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.

ADS-B antenna on stand    ADS-B antenna: 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, and From these and similar articles it seemed the design of choice for this frequency and service is a collinear, made from 75-ohm coax.

    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 construction articles.

    After just a moment’s hesitation I clipped the F connectors off the ends of the 4-foot length of RG6X, and cut the remainder into 15 cm pieces. Following published guidance, I trimmed 2 centimeters of braid and foam from each end of the cut pieces.

Section of RG8X

    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 (photo) came 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 1090 MHz, 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.

Collinear at 1090 MHz in SDR#

    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 bandwidth to 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 test ModeSDeco2.

Eample data display from modeSDeco2

    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 disconnecting 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.

ModeSDeco2 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


    XBee friends: 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 between ArduinosXBees 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 workhow 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 sketchthere werent manywas 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, as shipped. 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 I 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 asymmetry.
Other variants, different numbers of LEDs or different Arduino pins, etc. should require only minor program changes.
    XBee demo: XBee/friends.mp4

Staying in touch: How 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 gamein 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.

(revised sketch) My 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.


Icom R100 receiver

    Decoding ACARS: Shortwave listening (SWL-ing) is not what it used to be.  Before 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.

ACARSDeco2 (left) and acarsd (right)

    Elsewhere 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 voice band—the 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 named acarsd that seemed to be more widely used than ACARSDeco2. I was curious as to what 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 dongle 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 volume level (on the acarsd status bar), by increasing or decreasing the volume in SDR#.  Sources also gave different recommendations for the volume 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 decoding programs could be run at the same time on the same computer, one with the dongle and the other with a separate receiver.

acarsd example

    To test this idea I connected a 2-meter JPole antenna to our
Icom R100 receiver, 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.

ACARS demo: acarsdeco2+acarsd.mp4 - In the part of the demo where both applications are shown side-by-side, sound is from the external receiver (131.725 MHz).


Arduino Nano 3-pack
    Arduino 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 to the Unos 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.

Wi-Fi enabled Nano    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.

Background: 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 well.
The hypothesis: 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 where the radials are buried, and water makes the ground more conductive. We think this change affects antenna performance in a favorable way. On the other hand, a great many factors influence high frequency radio reception. (Other things are never equal.) It is 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 data on ground moisture or wetness, together with some sort of systematic assessment of antenna 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.

Sensor-connected Arduino

Agriculture: 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 low-cost probes, but it wasn’t until the context shifted to home gardening that readily accessible search results began to appear.

Low cost capacitive soil moisture sensorTesting sensor    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 from weather. On seeing a reference to this sensor I guessed that it could be used to test the Arduino-based data acquisition concepts, if not to exercise all components of the project, except whatever probe would eventually be deployed in the ground outside. 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).

Internet of Things: It was obvious that if the planned application should not have to remain connected 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 interface. My wife had previously experimented with a temperature and humidity demo application that interacted with an on-line ‘Internet of Things platform, 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 wetness data.

    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. This means 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 plaster-of-paris: This simple probe seemed almost too good to be true.

Probes in progress

Probe studies: 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 bench-tested 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 applying low-level (sine wave) test signals from 1 KHz to 1 MHz and measuring the probes’ 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.

Gypsum probe adapter

    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, I 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 capacitive probe. The header is wired to a 3.3 volt Nano pin for V+. As far as I know it doesn't matter (except for calibration) whether V-in or a 3.3 volt source is used.

Chart view (   
ThingSpeak: This open-source ‘Internet of Things resource provides truly amazing capabilities to the amateur experimenter, including integration with the powerful MATLAB computing platform (See, also I decided to give my first ThingSpeak chart a high-sounding title, while in truth the physical meaning of its source data is a bit shaky.  Perhaps with further experimentation and calibration it would be possible to transform sensed values to millisiemens or some such standard for consistency, but that goal seems fanciful at this point. It is also unclear how probe conductivity relates to soil conductivity—gypsum 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 not sure.

    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 ThingSpeak is also well explained on-line, and with demonstration examples. Finally, the sketch for this project illustrates all these pieces—the sketch is basically an assemblage of examples, tweaked specifically for the soil moisture study.

Next Steps: 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 statistical nature.  
    Wi-Fi Enabled Nano Demo: Nano/Soil_moisture_monitor.mp4

AD9834 Test Rig

AD9834 DDS (Part 1): 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. The 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 the Analog 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, there 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 other documentation.

PCB Connector Labels    The PCB connector labels (left) were a mixture of familiar and unfamiliar terms. Power connections and SDA / SCK were familiar, and RST for ‘reset
was meaningful, although I didnt 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.
75 MHz crystalNano to PCB pin mappings    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... Mr. Franks 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.

Sine, square, and triangular waves

    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 capacitively coupled. 

Voltage output by frequency

    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.

AD9834 DDS Demo: RTTY.mp4

    AD9834 DDS and FSK (Part 2): The above demo video introduces something that was not discussed in the accompanying write-up, viz 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 diagram below.

Two-controller configuration
    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).

One-controller configuration

For 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!

Receiving and decoding FSK on 7.1 MHz

    In the screen capture image, Termite (lower left) 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 output. 
Although differing in detail, these reference circuits exhibit common features, which I attempted to understand and duplicate.  

Breadboard amplifier

    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 about 3 volts P-P across a 50 ohm resistor. So far so good, although the second stage transistor got very hot. To address 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.

Amplifier on PCB

Transistor socketLow power    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 key 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 h
owever 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...)

    Footnote: One 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 afterward.

Deviation Map

    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, by Trident Amateur Radio Club president Ron (K4TCP).

    Radio amateurs deploy GPS modules in a variety of applications, including APRS (, high-altitude ballooning (, 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 was a 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. These modules consist of a postage-stamp size evaluation board containing 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).

Neo-6M (left) and Neo-M8N (right)    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 latter method.

    Software serial: I have long had difficulty with directions that appear to omit a frame of reference.  For example, if the weatherman says that a 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.” Well, who 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 They are all basically the same, up to naming of variables and choice of transmit-receive pins. I have copied a pass-through sketch, making only minor changes, from the aforementioned link here.

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 shows 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.

FullExample.ino Output Example

    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 ( 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.

M8N on breadboard

The breadboard photo above shows a Neo-M8N connected to an Arduino Nano by way of a bi-directional level converter. The 3.3 volt pin on the Nano supplies power to the GPS module, while GPS receive and transmit wires connect to Nano pins 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 sketches and wiring are consistent. Connections (in the photo) between Arduino pins 0 and 1 and the level converter at B1 and B2 are not relevant to the configuration being demonstrated.

    A flashing green LED on the Neo board indicates that the module is receiving
sufficient satellite data for a valid fix. This indicator is handy for checking things out at the bench, without 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 is that the M8N processes data from Russian as well as United States satellites. When 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 altitude 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:

    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

Receiver-decoder and Nano

What time is it?  From 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 atomic 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 time standards when I first started looking into the subject. However, I have learned that International 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 earths rotation. The current method of measuring and recording Astronomical Time is UT1.

    Longwave 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) that WWV 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 UT1.

    People for whom imprecision causes distress may wish to know current astronomical time to the nearest one tenth second, rather than UTC from GPS or WWV or
from the computer (Network Time Protocol). Thanks 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 from WWVB.]

    Few radio receivers tune as far down in the longwave spectrum as WWVB transmits. Fortunately, WWVB receiver chips are inexpensive, for example: [The similar one in the accompanying illustrations was purchased from England a couple of years ago.]

Simulator test setup    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 not expect to receive anything. That is why the receiver/decoder is not connected to the Arduino in this photo.  The larger illustration at the beginning of this write-up and the dashed line (left) shows where the receiver connects when actively participating.  The (real) green wire at the bottom comes from another Arduino that is running a WWVB simulator from:

    The decoding program (Arduino sketch) that I used may be found in the comments section of a YouTube video demonstration by ‘rbton
( 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.

Decoding simulated signal

Simulation: The above clip shows decoding of the simulator output. At this point I had attempted unsuccessfully to receive and decode 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).  

Real decodes: It’s 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.

First valid decode

    As shown, the current UT1 (astronomical time) correction (called DUT1 ) is +0.2 seconds. Between this first decode and daybreak
just over 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 decided 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.

Ferrite loop on window ledge

    To my astonishment this slightly revised setup immediately produced valid decodes while it was still daylight—4 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.

Valid daylight decodes

Before 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. —Moderately long sequences of valid decodes were also observed in the pre-dawn hours.

    The 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.

Summary: 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 decodes. —I 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 visiting According to experts the main cause for the slowing of earth’s rotation is tidal friction: Curiously there will come a point when this particular cause is no longer operative—billions of years hence, they say!

    Time Demo: wwvb.mp4

Mother of All Keyers

    MOAK: My first Arduino exercise was a Morse code sender (described above). Later I reconstructed a sine wave oscillator 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 project she came up with the name, “Mother of All Keyers” (MOAK for short).

    The name is a joke, of course. Physical components of the MOAK are the same as those commonly found in other keyers, for example,
the audio oscillator (QST, February 2017, pages 46-47). [Other sidetone 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 control program (MOAK Arduino sketch), which implements a unique mix of options.

Default startup optionSpeed Adjustment    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 option. Pressing the ‘Option’ button while running an option returns to the ‘Current option’ display, from which point the same or another option may be selected.

    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 front 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 been exercised.)

Block Diagram with Pin Numbers

Debounce circuits    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 panel speed 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 arbitrary 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 D13 for transmit-out produced an amusing side effect. Since D13 is the on-board LED indicator pin, the letters ‘H and ‘E sound on power up (4 blinks, then 1). When loading a sketch from the IDE, H signals the beginning of the load and ‘E signals completion.
    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.

Pseudo-text Option    
Random pseudo-text is gibberish that is similar to Englishmany 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 the 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, influence 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 behaved in 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 restart. 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 observed.

Send practice Option   
The idea of incorporating sending practice came from a ‘CW Trainer’ application designed by Tom Lewis 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. The 
Listen and Send 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.


Packaging of Components

    Packaging: 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 can be omitted. The only
components that are required to produce the same functionality as the MOAK are the Arduino, LCD display, and option navigation buttonsand of course, the sketch. If features are added in the future, I will post a revised sketch.

    MOAK demo: moak.mp4

Speed adjustment mode    Addendum: The procedure for changing speed was a little awkward. This revised sketch 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.

PICkit 3 Programmer and Breadboard

    Hello world: 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.

Edit Project Properties - Power check-box

Connections from programmer to microcontroller    Routing USB power to the microcontroller by way of the Programmer involves both wiring and a software setting. The latter is shown above. Google 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 of 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 functions, not 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 couple of 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 application input yet.

    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 all —

Watchdog timer off

    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 intended way. The LED only blinked when instructed to. Humans were once again in charge!

Imitate Arduino
    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 compilers built-in delay functions an oscillator frequency should be specified, according to 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 

Block Diagram

DS3231 moduleSimple clock    Real-Time Clock: The DS3231 real-time clock/calendar IC is based on a temperature compensated 32 KHz crystal oscillator, with a claimed accuracy of 2 parts per million at ordinary temperatures ( 2 minutes per year). This little clock IC supports all the features that a worthy clock should have, and it includes an IC 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: —Interrupt service routines should be sparse. My thought was that the ISR would not actually update the display, but rather signal when to update it.

Interrupt Service Routine

    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:

Save and restore sync data

    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).

Annotated example of WWVB sync

    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 connected.

Circuit Boards and LCD

    The two IC 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 the 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 block diagram.

During 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.

The 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 to use the information on this page.