Some time ago I've published an article how to build a CTCSS encoder using an Arduino.
Now I've receive a question from Konstantinos, SV1ONW where the answer might interest other people too.
He wanted to use the CTCSS encoder in their local repeater, but for this only a single tone is required,
and to avoid the need to select the correct tone with the up/down push-buttons he asked me if it was
possible to have the encoder produce a single tone only.
A solution would be to simply take the same code and boot with the requested frequency,
however this still leaves the risk of the floating up/down inputs that could by accident alter the frequency.
So I've adapted the code here and removed the push-button code and added some comment how to setup the frequency.
Finally, in order to get a nice sine-wave one needs to add a low-pass filter on the output-pin "D9".
I've added a drawing here on top of the page of a filter that I've build that seems to be working fine :
/******************************************************************************** * * * ATMEGA328P HAM RADIO CTCSS ENCODER * * Version: V3.1 * * * * Created by Geert Vanhulle - ON7GF - June 2019 * * * * Released under GPL3 - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 * * * * Derivative work can only be distributed under these same license terms * * For the full license text goto: fsf.org - The Free Software Foundation * * * ********************************************************************************/ /* ---------------------------------------------------------------------------- * * this is a single frequency version of the original CTCSS project * on an othere article here on my website. It's a reduced code version * * a lowpass filter needs to be added to get a nice sinewave * ---------------------------------------------------------------------------- */ // tabel gegevens byte ocrL[50]; byte ocrH[50]; // ctcss tonen float ctcssFreq[] = { 67.0, 69.3, 71.9, 74.4, 77.0, 79.7, 82.5, 85.4, 88.5, 91.5, 94.8, 97.4, 100.0, 103.5, 107.2, 110.9, 114.8, 118.8, 123.0, 127.3, 131.8, 136.5, 141.3, 146.2, 151.4, 156.7, 159.8, 162.2, 165.5, 167.9, 171.3, 173.8, 177.3, 179.9, 183.5, 186.2, 189.9, 192.8, 196.6, 199.5, 203.5, 206.5, 210.7, 218.1, 225.7, 229.1, 233.6, 241.8, 250.3, 254.1 }; // Change this variable to get the correct tone from the list above // To do so you need to count the position in the list starting from zero // For example: 67Hz = 0 --- 69.3Hz = 1 --- 71.9Hz = 2 --- and so on... // Here the variable is set for 88Hz = 8 int ctcsstone=8; void setup() { ctcsscalc(); /* frequentie-deler */ // configuratie Timer1 TCCR1A = 0x50; TCCR1B = 0x0A; TCCR1C = 0x00; // zet pin PB1 = OCR1A = "D9" als output DDRB |= 1 << PB1; // zet het deeltal in het output compare register OCR1AH = ocrH[ctcsstone]; OCR1AL = ocrL[ctcsstone]; } void loop() { } // bereken deeltal ocrnx voor elke frequentie void ctcsscalc() { int N = 8; int clk = 16; // 16 MHz clock for (int n=0; n<50; n++) { int ocrLH = ( clk * 1000000 ) / (( 2 * N * ctcssFreq[n] ) - 1 ); ocrH[n] = ocrLH >> 8; ocrL[n] = ocrLH & 0x00FF; } }