Build a Longwave AM Radio ReceiverFollow Krzysztof as he constructs a digital direct-conversion
receiver for long waves. Tuning is controlled by a USB serial
connection with a computer running terminal-emulating software. The
LM3S811-based system proves you can build a radio receiver with a
few discrete components.
I always wanted to build a radio receiver that could be digitally
tuned, without knobs or variable capacitors, just a link to a
computer. It would be a software-defined radio that processes the
signal in the digital domain. It would consist of a radio frequency
amplifier and conditioner, an ADC, and a processor that performs
demodulation and any other required operations on a sampled version
of the signal. Using this technology, it is possible to build a
receiver that equally receives analog amplitude modulated
(AM),single-sideband (SSB) modulated, and FM signals,as well as
digital on-off keying (OOK), frequency- shift keying (FSK), and
others, using the same hardware, but different software. Figure 1
shows the most important blocks of a softwaredefined radio.

When I first saw the Luminary Micro ARM Cortex-M3 microcontrollers,
I realized that it might be possible to develop a software-defined
radio. I wanted to build a modern radio that was as simple as
possible, with as few parts as possible. This led to a receiver
with weak performance,but that was acceptable. The main purpose of
this project was to prove that it is possible to develop a
software-defined radio using a microcontroller with simple hardware
(see Photo 1)。 I also wanted the receiver to operate without a
computer in stand-alone mode, so all of the processing had to be
performed by the microcontroller.
Photo 1-This is a working prototype of the radio. The only part not
shown is the antenna, connected to the right.
Those requirements were hard to meet. Because the processing had to
be done in real time, the microcontroller had to have enough
processing power to process the samples fast enough. This seemed to
be the biggest problem. A Luminary Micro LM3S811 was the perfect
solution because it has a 50-MHz clock generating 50 MIPS,which is
a considerable amount of processing power.
The ADC is an important part in a software-defined radio. It has to
be fast enough to sample the input signal at a rate more than twice
the maximum received frequency. Because the LM3S811 has a 10-bit
resolution and a 500,000-samples-per-second ADC, it is an excellent
candidate for the task. This rate makes receiving frequencies from
0 to 250 kHz possible. Therefore,it can cover a major part of the
LF broadcast band and many other broadcasts on frequencies below
that band. This is an acceptable range for an experimental
receiver.
I considered using the undersampling technique to receive higher
frequencies,but the performance (bandwidth)of analog input circuits
of ADC would have been a limiting factor. With a 500-ksps sampling
rate and 50 MIPS,the microcontroller had only 100 instructions to
read and process the sample. That is not much. Therefore,processing
had to be limited to only the most necessary operations.
THE DESIGNLuckily, the antenna, filter, and RF amplifier do not consume any
of the microcontroller‘s processing power. I used a long wire hung
in the garden as the antenna. The input filter is a
threepole,low-pass LC filter. The RF amplifier is a simple
transistor-based circuit. In the next stage, the ADC, after proper
initialization, works independently from the CPU without consuming
any processing power. It reports incoming data by generating an
interrupt. The following stage (the processing stage) is the most
important one because it is responsible for processing the data in
the interrupt service routine (ISR)。
The processing stage is determined by the modulation the device is
meant to receive. The digital radio is supposed to receive AM
signals. In this case, the processing is simple because the AM
modulation is basic. The AM signal‘s spectrum consists of both
upper and lower sidebands that carry the information about the
signal and a carrier frequency. The simplest AM receiver is an
envelope detector. Its principle of operation is based on the
detection of the envelope of a received AM signal. This approach,
however,requires that all but one AM signal are removed from the
input signal by filtering. This is usually done with tuned LC tanks
in the analog domain.
On a microcontroller, especially one that can quickly perform
accurate multiplication, it would be much easier to demodulate the
signal by direct conversion. Direct conversion is easy to
implement. The direct conversion receiver relies on the
multiplication of the incoming signal by a sine wave of the
frequency equal to the carrier frequency of a desired signal. For
AM signals, the result of the multiplication is ready to be sent to
a loudspeaker or headphones. The method doesn‘t require an
intermediate frequency and it is simple in implementation;
therefore, it fits nicely in my project.
The processing stage is fully implemented in software. Figure 2
shows this stage. In this stage, each sample from the ADC is
multiplied by a sample of a sine wave generated by a local
oscillator. The oscillator, implemented in software, is an array of
sine samples stored in the microcontroller's RAM together with a
pointer to the array. A current sample from the array is chosen by
the most significant bits (MSBs) of the pointer. The pointer is
increased with every input sample from the ADC by a certain
value(Increase)。 The Increase value determines the frequency of the
local oscillator. As you can see, the principle of operation of
this local oscillator is the same as the principle of direct
digital synthesis.
LOCAL OSCILLATORThe local oscillator is the only tuned element in this radio;
therefore, its settings determine the received frequency value. The
only way to change the local oscillator‘s frequency is to change
the value its pointer is increased each step. To calculate the
value, each sample from the ADC is multiplied by a sample sine wave
in the mixer. The ADC outputs a new sample every 2 μs. Every 2 μs,
a new sample of a sine wave is acquired from the local oscillator.
The samples of one full sine wave are stored in an array with 1,024
elements. If you take one sample from this array every 2 μs (the
Increase value equals 1), you will get a sine wave with a period of
2.048 ms (i.e., 1,024 × 2 μs)。 This results in a frequency of
approximately 488 Hz. The resulting frequency is:

To increase accuracy, I used more bits for the pointer (24)and
addressed the sine table by its 10 MSBs. This enables me to tune
the local oscillator more precisely because the pointer can be
increased by a noninteger value. The radio is tuned by changing the
value of the Increase variable. With every sample, the pointer to
the sine wave table is increased by a value determined by:
fGEN is the desired local oscillator frequency. fADC is the sample
rate of the ADC.
DACThe result of multiplication is a sample of a mixed signal that is
ready to be converted back to the analog domain. The output samples
are provided every 2 μs because I do not use decimation of samples.
This makes it difficult to use an integrated audio DAC. I used a
simple R-2R ladder DAC instead. Its main advantages are that it can
be updated any time, timing constraints don‘t have to be met during
data transfer, and it can be cheap.
An R-2R ladder has parallel data input, so it has to be connected
directly to a microcontroller's port. The LM3S811 has ports
accessible in an 8-bit fashion; therefore, you should use an 8-bit
DAC. This number of bits is small enough to be easily handled by
discrete elements and not to be ruined by elements‘inaccuracy,
while still giving an acceptable quality of sound. The main
drawback of this solution is that the output can not be loaded with
low-impedance speakers. Therefore,it needs a separate amplifier.
Sample values after multiplication are 21 bits long and signed. The
values are shifted right by 13 bits because only 8 MSBs can be sent
to a DAC. The samples are stored as signed variables, and the DAC
can accept only unsigned values, so you need to add 128 to every
sample. This adds a constant offset to the output voltage, but it
is easily removed by a coupling capacitor.
The DAC works at 500 ksps, so the output signal has a wide
spectrum. A simple RC low-pass filter is used to filter the output
and attenuate frequencies above a useful audio limit.
FROM THEORY TO PRACTICEI used an EK-LM3S811 evaluation kit, which is built around the
LM3S811 microcontroller and a few other useful components. I wrote
the firmware using an evaluation version of the Keil μVision IDE
and compiler provided in the kit. The firmware is written in C
language and uses the Stellaris Peripheral Driver Library.
The microcontroller can be clocked at its maximum speed equal to 50
MHz thanks to an integrated PLL. To accompany the digital portion
of the design, I prepared prototyping boards with input and output
analog circuits. They are connected to the board using gold pins
(see Figure 3)。 The supply voltage for the analog part is 3.3 V and
5 V directly from USB. USB voltage can be found on the kit‘s L1
ferrite choke pad.
点击查看Figure 3The board with the input circuit contains an input LC filter,an RF
amplifier, biasing circuits, and a low-pass antialiasing filter.
The amplifier is a three-stage transistor amplifier. The first
stage works in common source configuration, while the second and
third work in common emitter configuration. The potentiometer is
used to set the output signal amplitude. The amplifier is powered
by a 5-V supply taken directly from the USB connector. This was an
adequate solution because no significant improvement was observed
when using a separate power supply for the amplifier. The amplifier
is connected to ground potential by a central heating pipe and to
the antenna hung in my garden-approximately 30 m(100′) of wire hung
3 m (10′) above ground. A good ground is important. The antenna is
connected to the filter input and a large value resistor. The
resistor drains static charges that may be present on the antenna.
After amplification, the signal is biased to half the
microcontroller's supply voltage and filtered to attenuate
frequencies above Nyquist‘s frequency(half the ADC sampling
frequency)。 The filter's output is connected to the ADC1 input.
The most important part of this design is a programmed
microcontroller on the EK-LM3S811 board. The software is simple.
All of the processing is done in an ISR executed every time a new
sample is ready. The samples are 10-bit unsigned values that need
to be converted to signed values by subtracting 512 from each
sample. Then they are multiplied by a sine sample and sent to a DAC
by writing the shifted multiplication result to the appropriate
port. Although it is possible to filter the output values in the
digital domain, it turned out that an IIR filter that has steep
frequency response is difficult to implement in fixedpoint
arithmetic. Problems with limit-cycles and overall stability occur.
On the other side, FIR filters cannot provide the required
frequency response without considerable length; therefore, they are
too time-consuming to fit within the 100-clock-ticks limit.
Fortunately, tests have shown that filtering is not absolutely
necessary. The radio works well even without any filtering in the
digital domain. The ISR is responsible for processing the incoming
samples. In its current form, it executes in 60 to 80 clock
ticks,depending on optimization settings. Including 12 clock ticks
for entering and leaving the interrupt, this does not leave much
time for more processing.
The EK-LM3S811 board‘s display caused problems. Its noisy DC/DC
converter degraded the signal quality, so I turned it off during
reception.
The ADC sample rate does not equal 500 ksps, so it had to be
calculated by reading settings for reception of a strong AM signal
of a known frequency. It was found to be approximately 520,850
samples per second. I accounted for this during the frequency
calculations of local oscillator frequency to be able to tune to
desired frequencies accurately.
The output board contains output circuits, including a DAC and a
filter followed by an emitter follower. The DAC is a simple R-2R
ladder. I used discrete resistors instead of a ready-made ladder
because the ready ladders are hard to find. Although using discrete
resistors poses some problems with accuracy, it is an adequate
solution. I used inexpensive 5% resistors and found that their
resistance didn‘t vary that much. They can be safely used in my
application without remarkable degradation of signal quality. The
DAC's output is connected to another simple RC low-pass filter
followed by an emitter follower constructed with a single
transistor. Thanks to this emitter follower, it is possible to
connect headphones directly to the device. Another possibility is
to use a loudspeaker with a built-in amplifier if the output signal
is too quiet.
The receiver is powered via a USB supply. It consumes about 100 mA
from the USB 5-V supply. The code and data take less than 10 KB of
flash memory.
TUNING THE RADIO
The radio is controlled via a USB interface, which conveniently
provides the power supply as well. Drivers that come with the board
create a virtual COM port to communicate with the microcontroller
via its UART. I set the transmission speed at 115,200 bps, 8 bits,
1 stop bit, and no parity bits.
The virtual COM port can be used by any terminal application,such
as HyperTerminal in Windows. There are simple commands to tune the
radio to a specific frequency and switch between modes of
operation. Some examples of commands are: the letter "s" followed
by a frequency value and Enter key to set the received frequency,
keys '[', '{', '-','=', '}', ']' to increase and decrease frequency
by different steps; the letter "p" to store current frequency in
flash memory; and the letter "q" to switch modes between Radio and
Recording mode. For example, typing s177000,followed by the enter
key, in a terminal window will set the received frequency to 177
kHz.
In Recording mode, the radio stores 4,096 samples of input signal,
stops acquisition, sends the entire buffer of 4,096 samples to the
PC as ASCII characters, and then repeats the whole operation until
the "q" key is received again. This mode can be used to prepare a
spectrogram of frequencies from 0 to fADC/2. Refer to Photo 2 for a
sample spectrogram created from data gathered in this mode of
operation and processed in Matlab. (Octave is fine as
well.)Frequencies from left to right are 0 to approximately 260,425
Hz.

One important thing to remember about UART is that the LM3S811 has
built-in receive and transmit buffers and can generate interrupts
when a buffer is filled to a given level. If those buffers are
switched on (and they are, by default), the UART does not generate
an interrupt for each received character separately. This feature
is useful when transmitting data, but I chose to disable the buffer
and to have an interrupt generated each time a character is
received. I wanted the radio to respond immediately to each
increase/decrease frequency command.
STAND-ALONE MODE
I was determined to build a device that could work in stand-alone
mode without connecting to a computer, so I decided to store the
current frequency in nonvolatile memory. At power-up, the radio
restores the saved configuration. It is the simplest solution for
stand-alone operation.
In microcontrollers, the configuration is usually stored in small
built-in EEPROM memory. The LM3S811 does not have any EEPROM
memory. Therefore, I had to use program flash memory instead.
Luckily, the LM3S811 has 64 KB of flash memory. That is much more
than I needed for this project. The program occupies less than 16
KB (Keil‘s compiler evaluation version limit) of memory, so there
is plenty of space left. I set the address where the settings are
stored arbitrarily to 0x4000. Writing of specific flash memory
addresses is simple in Luminary Micro devices, because dedicated
functions are provided in the library supplied with the kit.
Reading is even simpler. Flash memory is accessed the same way as
the RAM-only the address is different. The only thing to remember
when using flash memory to store settings is that rewriting a flash
memory cell is not possible. It has to be erased first. An erase
can be done only in whole 1-KB blocks, so be careful not to erase
any other bytes when changing only one.
In my radio, it is also possible to use the onboard potentiometer
to change the frequency, but this method is less accurate than
using a terminal. To tune the radio this way,the user button has to
be pressed for around 0.4 s. Then,the radio enters tuning mode, the
OLED display is turned on, and displays the current frequency,
which can be changed using the potentiometer. When the required
frequency is set, the user button is pressed again for around 0.4 s
and the radio comes back to normal mode of operation. The input
signal and potentiometer voltage are connected to different input
pins and use separate ADC sequences, so they do not have to share
the same interrupt. This solution saves some execution time. It is
convenient because a mode check isn't necessary in ISRs.
RECEPTION
Broadcast station reception with this radio differs a little from
reception with an analog tuner. Due to a fixed tuning step, it
might be impossible to tune to the exact station frequency. This
would result in fadeouts of sound(when the frequency of a local
generator is almost the same as the carrier frequency) or
"metallic" sound (when the frequency differs by a few hertz)。 For
this reason, I increased the number of bits of the local
oscillator‘s array pointer. This created a frequency step small
enough to tune to a station and listen to it comfortably. Assume
that the desired frequency equals 190 kHz. If you refer to Equation
1 and Equation 2, you can compare the performance of two
oscillators, one with a 10-bit pointer and one with a 24-bit
pointer. With the array pointer being a 10-bit integer value, the
possible local oscillator frequencies around the desired one would
be:

In the first case, the desired signal would be modulated with a
frequency signal of around 250 Hz, resulting in a strange,
"metallic" voice. In the second case,tuning is far more accurate
and the sound of a received station is natural.
With analog receivers, there is no need to worry about tuning
accuracy that much, because the demodulation is done in a different
way that prevents the effects of inaccurate tuning from becoming
audible.
On the other hand, the chosen method makes reception of single
sideband(SSB) signals possible. Another advantage of this radio is
that the received frequency,after being set, does not change
significantly with time. It is stabilized by the microcontroller‘s
quartz oscillator.
WHERE TO GO FROM HERE
There is plenty of room for improvement. You can improve input and
output analog circuits to decrease noise and distortions and
increase sensitivity. The input filter is simple and not too well
matched to the antenna impedance. The output filter and audio
frequency amplifier are also candidates for improvement,although
they are good enough for a simple radio like this one. As for the
software,there is not much more that can be squeezed into a
100-cycle limit for a receive routine.
This project shows that it is possible to build a working digital
radio receiver using a few discrete components and a multipurpose
microcontroller. Although the LM3S811's designers did not expect
that it would be used as a radio receiver,its speed and features
are sufficient to build one. Modern microcontrollers are truly
multipurpose!
Krzysztof Klimaszewski (krzysztof.klimaszewski@gmail.com) is
working on a Ph.D. in multimedia telecommunications at Poznan
University of Technology (Poznan,Poland)。 He currently holds a
degree in electronics and telecommunications. His interests include
constructing various electronic circuits, radio communications,and
multimedia processing.
PROJECT FILESTo download code, go to ftp://ftp.circuitcellar.com/
pub/Circuit_Cellar/2009/222.
SOURCEEK-LM3S811 Evaluation kit and LM3S811 microcontroller
Luminary Micro, Inc.
www.luminarymicro.com