Skip to content

Sines in a Tin

This is one of the first real RF projects I’ve completed in 2022. It can generate low-amplitude sine waves from 1 Hz to about 35 MHz. The main goals of this project were to create an easily adjustable source signal for testing receiver circuits and to experiment with very low-power digital mode transmissions - and for this you need clean signals with very low harmonic levels.

It’s in a box


Here is the completed setup, packaged in an Altoids-sized tin can. There’s a mini-USB connector at the top to power and control this “Sine Tin”, and an SMA connector on the right for the output signal.

The frequency response is not 100% flat: the output level varies between ≈ 300 and 900 mVpp, depending on the selected frequency. And there is a DC offset of some +600 mV.

But the signal is quite clean (at least for an RF beginner like me): there are few harmonics and aliased frequency spurs, and they are generally at least 40 dB weaker than the main frequency:

10 MHz spectrum

That’s a 10 MHz output signal. It has a 2nd harmonic at -44 dB, and the rest lower than that. The most surprising outcome was that the whole frequency range from 1 Hz up to 40 MHz shows a similar result, so this little box can also be used for generating clean audio tones.


Some peaks shown above are from other sources - they also show up when the Sine Tin is not powered on. Once you are detecting microvolt signals, they show up uninvited everywhere!

What’s inside


The main ingredients of the Sine Tin are, from left to right:

  • a “Blue Pill” ARM µC board, based on the STM32F103C8
  • an AD9850 DDS frequency synthesizer breakout board
  • a home-brew 5th order low-pass filter
  • an SMA connector, soldered to the inside of the box

The whole setup is built on a single-sided 5x7 cm experimenter’s PCB with solder pads. There are no wires on the underside, everything is soldered on the top side, with a few pins and wires just barely sticking through. On the bottom is a piece of paper, but the PCB also has some small silicon “bumper” pads.

Height is an issue with a construction such as this, especially since the lid considerably overlaps the bottom part. The SMA connector and micro-USB jacks both need to be placed very close to the bottom to avoid interfering with the closed lid.

Also visible in a few places are the soldered-in “Swiss machined pins”, which make it very easy to insert test wires, as well as the more permanent output wires to the SMA connector.

Design choices

The AD9850 breakout board (available from various Chinese outlets) produces sine waves by synthesizing them digitally. See Direct Digital Synthesis for details. This is based on a 125 MHz crystal and due to a 32-bit divider, the frequency can be set in steps of 0.0291 Hz, all the way up to around 40 MHz.

The breakout board contains its own LPF filter, but since there were still quite a few harmonics coming through, I decided to add an extra 30 MHz low-pass filter, which is the upper limit of what I might need for ham radio use.


There is an online tool at which makes filter design extremely easy. I opted for a 5th-order Chebyshev configuration which requires two inductors.

The calculated filter response for 0.1 dB ripple in the passband is as follows:


This should nicely suppress all the residual signals above 30 MHz.

Filter construction

A low-pass filter with only resistors and capacitors would be very lossy, as the main signal path would end up going through each resistor. In RF-land, there is really no other way than to use inductors - and hand-winding toroids is one of the all-time charms (and chores) of ham radio.

The first step is to figure out what type of toroid and what number of wire turns to use to get to the desired 348 and 432 nH. There’s a great resource online at, with all the types of toroids they sell and all the calculations needed.

Type “6” is good for 3-40 MHz, and since these are very small inductances, the “T30-6” looks like a suitable core (30 is the outer diameter, i.e. 0.30” ≈ 7.5 mm). Here are the calculations:

348 nH

432 nH

So that’s 10 and 11 turns, respectively - piece of cake! I used 0.2 mm enameled wire and went about “needling” the wire through, a very therapeutic activity. There’s an excellent 8-min video by Alan Wolke on how to make these coils.

With the toroids made, and some 20/50/100 pF ceramic caps from my parts bin, I made a tiny carrier PCB with the complete filter. The big question now is: will it work as expected? Well, my first attempt actually failed. I had a 4-th order filter which didn’t behave as expected at all: a strange 26 MHz dip, and worse.

But this second one worked, well above my expectations, as verified with a tool called a Vector Network Analyzer. In my case the amazingly low-cost, small, and useful NanoVNA:


This image is very crowded: the main trace is a light-blue line which slopes down from the top, showing the filter attenuation (increasing downwards) with frequency once past 30 MHz - with a very sharp dip at around 80 MHz before rising again.

As it turns out, these results match the prediction surprisingly well up to 70 MHz or so.

Initial trials

debug build

Now it’s time to combine the various parts of this project and add the connections to power it all up, with additional wires for the debugger (SWD + UART).

Then comes the other side of the coin: software to drive this thing. My goal, as mentioned before, is to make it all controllable over USB, using a serial connection. At the very least, I need to be able to enter a frequency setting and see the output signal adjust to it in real time.

This is where software development for the Blue Pill shows an inconvenience: it has no on-board debugger and no USB driver in its boot ROM. The only way to get the initial software into this µC is to connect a debugger such as an ST-Link, or in this case a Black Magic Probe.

But for various reasons, I wanted to get rid of this debug-wiring setup as quickly as possible. This requires uploading a small USB boot loader to the board, which is then used to update each actual application software revision over that same serial USB connection.

To Do

The custom-made USB loader will be described in a separate article.

Note that the AD9850 has been connected in parallel mode, i.e. using eight separate I/O pins instead of via SPI. The Blue Pill has enough I/O pins anyway, and the layout of PA0..PA7 are such that the connections also help create a sturdy mechanical link between the two boards.

As side effect, setting up the AD9850 takes well under 1 µs and needs only a few lines of code:

void setDDS (uint32_t fract, uint8_t cmd =0) {
    MMIO8(pdata) = cmd;
    wclk = 1;
    wclk = 0;
    for (int i = 0; i < 4; ++i) {
        MMIO8(pdata) = fract >> 24;
        fract <<= 8;
        wclk = 1;
        wclk = 0;
    fqud = 1;
    fqud = 0;

The first trials were done by simply hard-coding a fixed frequency, compiling and uploading the app, and running it. This was used to prove that the basic design works.

Disaster strikes

But some very strange things were starting to happen. The Sine Tin worked, but I had trouble uploading, and it never started up properly when plugged into only USB. Very consistent and confusing, until I measured the 3.3V voltage while plugged into USB: 4.6V - whoops …

It looks like the voltage regulator on the Blue Pill got damaged, the problem is that it’s on the underside of the board and totally inaccessible at this stage of the build. The solution was this:


A spare MCP1702 3.3V regulator as 3-pin TO-92 part was mounted sideways, and the 5V input trace from the USB jack was cut. The actual repair took some tricky soldering: a wire attached to the 5V pin and re-routed to the new “outboard” regulator.

After this fix, everything made sense again. I have no idea what caused the damage (maybe it was already bad before). The total current consumption from the 5V line is about 80 mA.

Serial commands

For actual day-to-day use, the Sine Tin really needs to have some sort of command interface. This has been implemented in a little app called stm32x/sinetin, which listens to incoming commands over its serial USB connection. Hitting the RETURN key produces this output:

AD9850 sine wave generator v0.1

  <N> h    - set freq to <N> Hz
  <N> k    - set freq to <N> kHz
  <N> m    - set freq to <N> MHz
  <N> +    - set xtal calib to 125 MHz + <N> Hz
  <N> -    - set xtal calib to 125 MHz - <N> Hz
  q        - quit, close USB connection

The calibration adjustment option can be used to compensate for crystal inaccuracies and drift when calculating the exact dividers which control the AD9850 chip.

To generate a 5 MHz sine wave, I can now simply enter “5m”, and get this feedback:

f = 5000000 Hz

That’s it. It’s very basic, there is no backspace/editing/echoing, but it’s enough to set any frequency between 1 Hz and well over 30 MHz, in 1 Hz resolution if needed.

There’s considerably more one can potentially do with this Sine Tin, such as frequency sweeps, producing single-tone SSB signals, WSPR, QRSS, and more. But that’ll be for another time …