Nov 28, 2020:
Revised: v1.1

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


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:

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:

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.


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


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.


Software: This ZIP file includes the HEX files for directly programming the ATtiny85 chip.
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.