Amplitude Demodulating BPSK31

BPSK31 has become a very popular digital communication mode among amateur radio operators due in no small part to its efficiency and narrow bandwidth. You can easily demodulate BPSK31 signals with readily available DSP software, or even using an Arduino.

Never the less, I thought it would be fun to build an analog BPSK31 demodulator that would output digital bits via simple two wire bus, and hit upon the idea of doing this relatively easily using amplitude demodulation.

Amplitude demodulating phase modulated data??

Amplitude demodulating phase modulated data??

I know, I know, a proper PSK demodulator would implement a costas loop or similar phase detection circuit. This approach is a hack for sure, and won’t work as well as a proper phase demodulator, but has the advantage of being easily constructed with a hand full of “jellybean” components that are probably already sitting in your parts bin.

BPSK31 Modulation

With BPSK31, text is encoded into binary data using a varicode scheme, with two 0 bits delimiting the start/end of each character.

Data is transmitted at 31.25Hz, with a phase shift of 180 degrees representing a binary 0, and no phase shift representing a binary 1. In order to minimize the signal’s bandwidth during phase changes, the amplitude of the signal is reduced when sending a 0 bit, resulting in a waveform that looks something like this:

BPSK31 modulated waveform

BPSK31 modulated waveform

So a BPSK31 signal changes in both phase and amplitude whenever a 0 bit is sent, and both phase and amplitude remain the same whenever a 1 bit is sent. These amplitude changes form the basis of the demodulation circuit.

Circuit Description

The following circuit takes in BPSK31 audio, demodulates the data, and outputs bits via the data and clock lines:

BPSK31 AM demodulator schematic

BPSK31 AM demodulator schematic

The heart of the circuit is U1, a TL082 dual op-amp which, along with diodes D1 and D2, performs full-wave rectification of the input signal. It has a gain of 10 (G = R5/R4), and the low-pass filter formed by C1 and R5 integrates the rectified signal, resulting in an output waveform which represents the amplitude envelope of the input signal:

BPSK31 input (yellow) vs rectifier output (blue)

BPSK31 input (yellow) vs rectifier output (blue)

U2, a TL081, is a non-inverting amplifier configured for a gain of 101. This stage is not necessarily required as the BPSK31 audio signal could be amplified externally, but it is useful for weaker signals, and the second low-pass filter formed by C2 and R7 help to further smooth the envelope waveform:

Rectifier output (yellow) vs amplifier output (blue)

Rectifier output (yellow) vs amplifier output (blue)

The amplified envelope waveform is then fed into U3, which is half of an LM393 dual comparator. The comparator’s reference voltage and hysteresis (set by R11, R12, R8 and R9) causes its output to go high when the input signal rises above 2V, and to go low when the input signal falls below 1V:

Comparator input (yellow) vs comparator output (blue)

Comparator input (yellow) vs comparator output (blue)

At this point, the binary bits from the BPSK31 signal have effectively been recovered, as long as you know when to sample it:

Decoding the comparator output (blue)

Decoding the comparator output (blue)

Rather than have a microcontroller or PC continually sample the comparator’s output, clock recovery is performed by U5, a 555 timer configured as an astable multivibrator running at ~31.25Hz.

But a free-running 555 timer simply isn’t adequate here. First of all, we need to synchronize the 555 clock with the transmitter’s clock. Secondly, even if we were somehow auto-magically synchronized with the transmitter’s clock, a 555 timer just isn’t stable enough to maintain an accurate frequency over any significant period of time.

However, both of these problems are solved by connecting the comparator U3’s output to the 555 timer’s reset input (pin 4).

When the BPSK31 signal’s amplitude is large, the comparator’s output goes high, turning on the 555 timer:

555 reset input (yellow) vs 555 output (blue)

555 reset input (yellow) vs 555 output (blue)

If the BPSK31 signal is transmitting a 0, the signal’s amplitude will drop before the 555 timer sends its first clock pulse. When the signal falls, so will the comparator’s output, simultaneously turning off the 555 timer and bringing the 555 timer’s output low:

555 reset input (yellow) vs output (blue) during a 0 bit

555 reset input (yellow) vs output (blue) during a 0 bit

However, if the BPSK31 signal is transmitting a 1, the signal’s amplitude will remain high for longer than the 32mS period of 31.25Hz, thus the comparator’s output will remain high, and the 555 timer will remain on, pulsing the clock line at a rate of ~31.25Hz:

555 reset input (yellow) vs output (blue) during a 1 bit

555 reset input (yellow) vs output (blue) during a 1 bit

R1 should be adjusted so that the frequency is at or near 31.25Hz. The duty cycle will be greater than 50%, and the frequency doesn’t have to be perfectly exact, but it should be close:

555 couter's output frequency

555 couter’s output frequency

As you can see, my 555 timer’s clock is slightly slower than 31.25Hz, but that’s OK; since the maximum number of consecutive 1’s that any character contains is 9 (see the PSK31 varicode character set defined here), the 555 timer only has to be accurate for 9 clock cycles.

Thus, resetting the 555 timer every time a 0 bit is transmitted negates the need for a highly stable time base, and further ensures that the 555 timer will be automatically re-synchronized with the transmitter’s clock whenever a 0 bit is received.

Finally, U4, another LM393 dual-comparator, is used to ensure that the 555 reset pin is isolated from any external circuitry, and to provide uniform output characteristics for both the clock and data lines. As with U2, this is not necessarily required, but is probably a good idea.

To decode the data, just sample the comparator U4b’s output on the falling edge of U4a’s output:

Demodulated ASCII 'r' (10101)

Demodulated ASCII ‘r’ (10101); yellow=clock, blue=data

I wrote some simple Python code to read the data bits via an FTDI TTL-232R UART cable in bit-bang mode, and was able to successfully decode self-generated BPSK31 audio, as well as some pre-recorded off-the-air transmissions:

Decoding pre-recorded off-the-air BPSK31 QSO's

Decoding pre-recorded off-the-air BPSK31 QSO’s

The circuit constructed on a scrap of PCB

The circuit constructed on a scrap of PCB

Conclusion

This is a fun little circuit that is easy to build with readily available parts. It does however bring with it all the normal detriments of amplitude demodulation, meaning that it is more sensitive to noise and variations in the amplitude of the input signal than traditional phase demodulation. As such, practical use would necessitate the addition of pre-filtering and AGC circuits (although in fairness these are typically required regardless of the demodulation method).

With that said, well filtered BPSK31 signals are easily demodulated, and can be decoded by just about anything that has two free I/O pins.

9 thoughts on “Amplitude Demodulating BPSK31

  1. Pingback: Nerfd.net - RF News & Info | Amplitude Demodulating BPSK31 with opamps.

  2. Pingback: Demodulating BPSK31 With OpAmps and 555s | Hackaday

  3. Pingback: Demodulating BPSK31 With OpAmps and 555s | Hack The Planet

  4. Pingback: Demodulating BPSK31 With OpAmps and 555s | Ad Pub

  5. Pingback: Demodulating BPSK31 With OpAmps and 555s | 0-HACK

  6. This is really really cool, even though I probably only understood about half of it at most. Great blog, absolutely love it.

Leave a Reply

Your email address will not be published. Required fields are marked *