A Multi-tone Crystal-controlled CTCSS Tone Encoder

It’s
useful to have a multi-tone CTCSS encoder on the test bench. This
compact battery powered encoder includes all 50 tones. Tone selection
is displayed on a small 64 x 32 OLED display.
Two
versions are described here, one using the same tiny single-sided PCB
as my previous CTCSS encoder, the other using a PCB designed for the
test bench or for mobile use
Introduction
Professional
two-way radio users as well as many amateur radio operators use CTCSS
tones for shared repeater access. You can read about CTCSS tones and
their use here.
That
webpage also describes several of my simple Direct Digital Synthesis
(DDS) based CTCSS encoders. There, I briefly mentioned that I had
also designed a multi-tone version of the CTCSS encoder during the
development process. I hadn't bothered to complete construction
or document the design further because I didn’t think there would be
much interest in such a device.
That
assumption proved to be
wrong. Very wrong. I’ve had frequent requests since that time
asking for
details of the multitone encoder. Along with bench testing, many
mentioned they wanted it for mobile use. It seems they access a
number of different repeaters requiring a variety of different CTCSS
tones.
The basic four-tone CTCSS encoder I had designed was insufficient. Some
also mentioned they found accessing the CTCSS menus in
their smart mobile and handheld transceivers to select a different tone
each time an absolute royal pain. They needed something simple and easy
to use.
A number of these also mentioned the limited number of suitable commercial multitone CTCSS encoders available now. Prices for these devices also appear, to me at least, very high, well out of the range of the average ham. Others noted some limitations, with one multitone encoder kit only supporting a limited range of CTCSS tones.
So,
finally, in response to this surprising level of interest and in light
of the very low cost of my design, here are the details. My multi-tone
CTCSS encoder design is simple. It allows user selection of any
of the fifty standard CTCSS tones using a standard rotary encoder.
A low cost OLED display shows the selected tone. It filters and outputs
the tone on a standard audio 3.5mm socket. The minimal number of parts
are all widely available and inexpensive. If your built my
earlier CTCSS encoder, it's possible to upgrade it to this new multitone design at
minimal cost.
I estimate the new parts cost from the usual
online suppliers (in late 2020) for the basic version to be less than
$US10 and the bench/portable version should cost less than $US20. If you have
your own 3D printer, the cost for the bench/portable
version would probably be around $US15. A well-stocked parts bins and a
home-made PCB could reduce this cost by at least 50% or more. (The price of a
comparable commercial unit delivered is about $US100 at time of
writing)
CTCSS Tone Selection
As
I originally briefly considered the requirements for a multitone CTCSS
encoder design, it was clear there was no need for a standard rotary
encoder with its usual integrated pushbutton switch. With just one of
50 tones to be selected, the integrated tuning step push switch
normally used to select 1, 10, 100 or 1000 Hz encoder tuning steps in
other DDS designs was clearly not required.
I wondered if it might be possible to use the absolute
cheapest of ultra-standard rotary encoders, the type used in the rotary
wheel of almost every PC mouse. A typical example is shown here.
Figure 1: Mouse wheel rotary encoder
At
time of writing, in late 2020, these cost less than 20 US cents
delivered.
However, these represented a problem for me. Previous software I
had developed for using rotary encoders on a single I/O pin assumed the
use of cheap 'pulse' rotary encoders. At
rest, these present an 'open circuit' on both output pins. However,
these mouse encoders, like the other category of rotary encoders,
the ‘level' type, rest with their outputs in either a 'short circuit' or 'open circuit' state.
Further
issues that I only recognised later were mechanical. They require a
special control knob to fit that hexagonal hole. Also, these
encodersare
made with (at least) five different shaft heights.
Fortunately, in the case of the control knob, my 3D printer came to the rescue.
Anyway,
in my original rush to try this idea out, and given I did not require the tuning
step selection push-switch, a little careful thought over a cup of coffee and a few tests
identified a further simplification of my rotary encoder software which
allowed this encoder to be used, once again requiring just one I/O pin.
Circuit Description
In a typical design of such a multitone encoder, the typical I/O requirements for a design might look something like this:
- DC supply: 2 pins (3.3V or 5V, and ground)
- Rotary encoder: 3 pins (including the encoder’s integrated push-button)
- Cheap 16x2 alphanumeric LCD display: 6 pins (4 for data, 2 for control)
- External crystal: 2 pins
- Audio output: 8 pins (assuming a parallel output to a digital-to-analog converter and buffer)
This
gives a total of 21 pins. Usually, this would require a chip such as
the ATmega328. However, in this new design, the pin count is much
lower:
- DC supply: 2 pins (3.3V or 5V, ground)
- Rotary encoder: 1 pin (!)
- Alphanumeric display: 2 pins (I2C bus)
- External crystal: 2 pins
- Audio output: 1 pin (with pulse-width modulation)
This adds up to just 8 pins! That makes a much smaller and less expensive device such as the ATtiny85 feasible.
Here
is the resulting schematic of my multi-tone CTCSS encoder. It uses only
18 components. Everything controlled by the small 8-pin ATtiny85.
Figure 2 : Basic multitone CTCSS encoder uses a mouse rotary encoder and RC output PWM filtering
No pullup resistors are required on the I2C bus lines to the display. The display includes these inside the module.
An
external crystal is absolutely essential for reliable CTCSS tone generation.
Like the other CTCSS encoders described on my website, this new encoder
delivers crystal-accurate digital CTCSS tones accurate to within
0.025%, with vanishingly low output distortion, typically less than
0.7%.
In
this case, a low cost 8MHz crystal generates the
clock for the ATtiny85. This accurately controls the timing of the
internal DDS tone software. The CTCSS tone is generated
using pulse-width modulation (PWM). This is filtered either with an RC
filter (Figure 2) or with an optional third-order elliptical low pass
filter (Figure 3). Both filters prevent any of the PWM carrier reaching
the output.
The
simple RC filter approach in Figure 2 reduces the PWM carrier to
30dB below the wanted CTCSS tone. The elliptical LC filter improves the PWM rejection to 60dB.
Both elliptical and RC filter methods work equally well on standard
amateur radio and commercial two-way radio applications. The LC
filter option is shown in Figure 3 and requires several extra
parts.

Figure 3 : The optional three-pole elliptical filter improves PWM carrier rejection
Since
miniature inductors are not always easy to find for L1, two sets of
elliptical filter components are described in Figure 3 to allow use of
either a 15mH or a 47mH inductor. In all cases, with either the
original RC filter or either of the two LC filters, no evidence of the
64kHz PWM carrier could be detected on the transmitted FM signal with a
spectrum analyzer.
Depending on the value of R2 in Figure 3,
the maximum output level can be set to 300mVpp (R2=100k) or 3.0Vpp (R2
= wire link) with a 3.3V supply. (Do NOT use a 5V supply! The OLED display is only rated for 3.3V operation). The multitone encoder with the OLED display requires about 40mA.
As
mentioned earlier, tone selection is handled with a rotary encoder.
Along with a pair of resistors which form a simple 2-bit digital to
analog converter, the encoder is connected to the ATtiny85 via a single
I/O pin. Careful choice of resistor values and a noise-limiting
capacitor allow the encoder rotation direction and pulses to be
determined.
The
selected frequency is shown on a compact 64 x 32 pixel OLED display. A
pair of carefully designed fonts have been developed to allow all four digits of the CTCSS tone to be unambiguously displayed without the need for an additional space-filling decimal point.
Figure 4 : The small 64 x 32 pixel OLED display shows the selected tone
I
used a 0.42” 70 x 40 pixel I2C (4-pin) OLED in the prototypes pictured
here (All I had at the time) but the software is compatible with the
slightly larger 0.49” 64 x 32 pixel OLED display. (Oddly, this latter
part has a larger display yet is mounted on a physically smaller
daughterboard!)
The software is also compatible with most
0.91” 128 x 32 pixel OLED (Some displays give a compressed pixel
display, and a few “slow response” displays don’t work at all) and most
0.96” 128 x 64 pixel OLEDs worked fine. The display does not fill the
latter 64 pixel height display, of course, since the font is designed
for 32 pixel height displays. However, the image is larger on these
128x64 OLEDs, potentially useful for those with even worse eyesight
than me.
I’m sure it’s obvious, but these other
OLEDs won’t fit in the 3D-printed case described below although a
little trimming of the cover display hole will allow the 0.49” OLED to
fit perfectly.
All these displays use the ‘standard’
SSD1306 controller. A few OLEDs use the (less expensive?) SH1106
controller and these will not work with this software.
As
noted earlier, the multi-tone CTCSS encoder is operated from a pair of
AAA cells. The low current drain delivers good battery life, typically
delivering anywhere from three to six months of intermittent use on the
test bench.
Mobile
use would require an additional external 13.8V to 3.3V regulator. An
LM317 and a pair of resistors would work fine but would require a
modest (e.g. 25mm x 25mm finned) heatsink on the LM317. A variety
of more efficient switch-mode regulator modules are available for
modest cost from the usual online sources.
Software
The
software is based around a software core responsible for generating the
direct digital synthesis of the selected CTCSS tone. Initially, the
generator starts at 123.0 Hz but any tone can be subsequently selected
by the user with the rotary encoder.
The rotary encoder
uses a simple hardware 2-bit analog to digital converter using a pair
of resistors. These detect the direction of rotation and the number of
turns. The software is all event-interrupt driven. A timer-based
interrupt approach would cause undesirable tone distortion and output
gaps.
The 50 CTCSS tones used in this design are:
Table 1 : Most CTCSS systems support this iIndustry standard set of 50 CTCSS tones
The
various national CTCSS standards frequently specify just 38 or 39
tones, but this wider set of 50 tones supported by this design (Table 1) is
generally considered the ‘standard’ CTCSS tone set in the industry.
Tones
NOT currently supported in this design include a CTCSS tone just above
254 Hz which is reported to be used in some UK analog FM PMR446
transceivers, an unusual 150.0 Hz tone used in a few military mobile radio systems, and a 55 Hz
tone used by a few Chinese transceivers for a tone-based squelch-tail
elimination scheme. A few tones below 67 Hz are also reported to be
occasionally used (62.5 and 64.7 Hz, for example) but these non-standard tones are also not included
in this design.
Incidentally, some
radios and decoders cannot support a number of the more demanding
CTCSS tones such as 177.3, 179.9 and 189.9 Hz. Encoding these is easy,
of course, and they are
included in the above set. (Getting a software-based decoder working
with these tones while avoiding false triggering on the adjacent tones
is a serious technical challenge!)
Construction
Two
different single-sided PCBs may be used to build my multitone
CTCSS encoder, both using standard through-hole components. The
first uses the same PCB as used for my earlier simple CTCSS encoder.
This is described here because it may be easier for some to use with
mobile transceivers where multiple tones are required and space is limited.
Version 1 : Compact Version
This
small 25 x 25mm (1” x 1”) PCB is shown in Figure 5. Gerber files can be
obtained from the Download section below. It could be made much smaller
using SMD parts, but the approach described here makes it easier to
build.

Figure
5: The multitone CTCSS encoder may be constructed using the same basic
single-sided 1”x1” PCB used in my earlier CTCSS encoder designs
This
PCB includes provision for installing two SMD resistors adjacent to pin
1 under the board. However, for this multitone encoder, these are not
required. Instead, the pad next to pin 1 should be bridged across to
the pad connected to terminal “S” to allow an external wired connection
to be made at pad “S”.
The rotary encoder in this case is
wired to the pad marked “S” (for switch) on the overlay. There are a
couple of extra resistors required with the rotary encoder, so check on
the schematic for details. These are mounted off the board.
The
display can be wired to the PCB using the pads marked for Jumper A and
B which connect to pin 5 and 7 of IC1. The display’s Vcc connection
should go to pad “d” and the ground connection to pad “g”.
The
wiring diagram in Figure 6 provides the details for construction of
this version of the multitone encoder. Note that the use of this PCB
assumes the use of the basic RC output filter as shown in the schematic
in Figure 2.

Figure 6: The multitone CTCSS encoder is easy to assemble using this wiring diagram
And
here is a photo of this version. This has been in extensive use on my
bench during the development of my CTCSS decoder software.
Figure 7: Version 1 of the multitone CTCSS encoder is very easy and inexpensive to build
Version 2 : Benchtop Version
A
second single-sided PCB was designed for a compact battery-powered
benchtop version (Figure 8). It may also be equally useful
for mobile applications. This PCB measures just 50 x 25mm (2” x
1”). It includes provision for the improved LC output filter and
requires no wiring other than to the battery.
The tone
output uses a PCB-mounted compact “PJ-321” type 3.5mm mono audio socket
(J2). These are available from parts suppliers at very low cost, but
many will likely have a suitable socket in their parts bin, recovered
from old AM pocket radios and similar devices.
Figure 8 : This PCB better suits benchtop use and is specifically designed for a mouse encoder.
There
is one short jumper that must be fitted to the PCB along the RH side of
IC1 between the display and the pad adjacent to pin 5 of IC1. Depending
on your choice of output level, a second jumper may also be required to
be fitted in place of R4. Start construction with these jumpers, and
then fit the remaining passive components.
The crystal (X1)
should now be fitted. Next, fit the 1k linear potentiometer (RV1) and
the mouse rotary encoder (SW1). These mouse encoders are made for
different mouse wheel axis heights (i.e. 5, 7, 9, 11 and 13 mm are
commonly available). I used an 11m height encoder to match the height
of the output level control (RV1) but your potentiometer may differ
from the one I used. If you are using a recycled mouse encoder, fitting
it may require some minor adjustment to ensure the Tone knob correctly
aligns with the Level knob.

Figure 9 : A view under the cover, the revised PCB holds the rotary encoder on the LH
side
and the level variable resistor on the RH side. The output socket
is visible under a blob of
hot glue (centre RH edge) while the power switch is barely
visible under the wiring (Top right).
The
3D printed case was designed assuming the use of this 11mm height
encoder although the case is flexible enough to allow for other similar
encoder axis heights. The two 3D printed knobs have also been designed
for this project, for the rotary encoder and the output variable
resistor (RV1).
A four-way Dupont PCB mounting socket strip
is fitted for the display to suit the usual matching pins normally
fitted to the display module by the vendors. An 8-pin DIL socket should
also be fitted for the ATtiny85.
Programming the ATtiny85
Other pages on my website describe how to program the ATtiny85. One example is here. The HEX file for programming the chip can be downloaded via the link in the Downloads section below.
After programming the flash memory with the HEX file, program the ATtiny fuses with the following HEX values:
Extended: &FFh
High: &57h (Disable RST, Save EEPROM)
Low: &EFh (for external 8MHz crystal)
Note:
If you want to add new features or change the software at some later
date, reprogramming of the ATtiny85 will require the use of a
specialized HV programmer because these fuse settings disable the Reset
function of the chip to allow access to other Pin 1 functions.
Building the Enclosure
A
compact 3D-printed case and two knobs have been designed for the
benchtop version of the multitone CTCSS encoder. The case includes an
integrated battery holder provision for a pair of AAA batteries and a
slide switch for power.
Figure 10 : A 3D-printed enclosure was designed for the CTCSS encoder
The
battery holder is designed to take a set of standard AAA battery spring
contacts. Suitable battery spring contacts can be recycled from most
old remote controls or elderly cordless telephones. Alternately, for
those making a number of these for a club build, for example, it is
possible to purchase a set of suitable standard AAA “battery shrapnel”
(Really, that’s what the manufacturers call these things!) from a
variety of parts suppliers.
There are also files for 3D
printing the two knobs required. The LH knob is designed to fit the
mouse encoder. It includes a retainer which slides into the matching
slot in the front panel. This prevents stress on the mouse encoder.
Once printed, if your 3D printer lacks adequate resolution to print the
hex exactly, careful trimming of the stub with a very sharp hobby knife
will work perfectly. Take your time, and trim very thin slices off
opposite sides. It takes a couple of minutes. If you mess up, just
print another knob.
The RH knob just slides into place over the knurled shaft of the level control.
Figure 11 : The two knobs can also be 3D-printed to further reduce construction cost
The
battery contacts simply slide and lock into place. It’s best to solder
the red and black DC wires onto the battery contacts before pushing
them into the case. The heat of a soldering iron can easily melt the
printed PLA plastic case.
Figure 12 : Inside view with display removed
Similarly,
add the wiring to the power switch first, and then hot-glue it into the
case. It’s a standard DPDT slide switch. Solder the power connections
to the PCB, and hot-glue the completed PCB into the case.
Insert
the programmed ATtiny85 and the OLED display, push on the printed
knobs, screw the cover on the case carefully, using countersunk
2mm self-tapping screws, and add the case label, if desired. This can
be printed on a colour laser or inkjet printer, covered with clear
self-adhesive transparent plastic and glued to the case. I use either
spray adhesive, roll-on adhesive or double-sided sticky tape for this,
usually the nearest of these items to hand at the time.
Figure 13 : Front/top panel label artwork for the project
The encoder is now complete and ready for use.
Downloads:
Software: This
ZIP file includes the HEX
files for directly programming the ATtiny85 chip.
- The standard 'pulse' type encoder software is: CTCSSMultiGen_64x32_72x40_PencoderV02.hex
- The 'level' type mouse rotary encoder software is: CTCSSMultiGen_64x32_72x40_mouse_encoderV02.hex
Due to unauthorised copying and reselling of my designs and software, please email me if you would
like a copy of the software. Please clearly state in your email that the software you want is for your
personal use and you will not copy or distribute the software to any other individual or entity. My email address is on the main page of this website.
3D Files: This ZIP file contains all of the STL files for the enclosure cover, base, and two knobs.
Panel Artwork: The JPG file for the front panel artwork.
Basic PCB: This
ZIP file contains the Gerber industry-standard file set for the simple (Version 1) single-sided 25 x 25 mm PCB.
TestBench PCB: This
ZIP file contains the Gerber industry-standard file set for the larger (Version 2) single-sided 50 x 25 mm PCB.
Want to go back to the main page? Click
here to
return directly.