ATtiny CTCSS Encoder

As a follow-up of my Arduino based CTCSS encoder project, the goal of this project was to reduce the cost, size and number of components of the original Arduino version.

For this reason this new versio is based on the Atmel ATtiny85 microcontroller, a low cost small 8-bit MCU.
The advantage of this microcontroller is that it can be programmed using a Arduino Nano as programmer.
The code contains a small wiring example of how to use the circuit.

The code is written for the ctcss tones 79,7 Hz and 131,8 Hz,
however, this can be easily changed into the frequencies one might need.
To calculate a new tone the following formula can be used:
OR0A = 1MHz / ( ( 128 * Tone ) - 1 )
As the internal Clock of the ATtiny isn't very accurate, the resulting value of this calculation might need some correction.

As the output is a square-wave a lowpass filter at the output is needed before feeding the signal into most transceivers

/********************************************************************************
 *                                                                              *
 *                       ATtiny85 HAM RADIO CTCSS ENCODER                       *
 *                                Version: V1.0                                 *
 *                                                                              *
 *                Created by Geert Vanhulle - ON7GF - August 2024               *
 *                                                                              *
 * 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    *
 *                                                                              *
 ********************************************************************************
 *                                                                              *
 * Dual tone CTCSS encoder 79,7Hz en 131,8Hz:                                   *
 *                                                                              *
 * Hardware : ATTiny wiring                 +-----+                             *
 *                                       --1|     |8--  Vcc                     *      
 *                                 LED1  --2|     |7--  Button                  *
 *                                 LED2  --3|     |6--                          *
 *                                  GND  --4|     |5--  ctccss-out              *
 *                                          +-----+                             *
 *                                                                              *
 ********************************************************************************/


volatile bool btn=false;
byte t=0;

void setup() {

  // Tone
  DDRB |=  (1 << PB0);
  TCCR0A &= ~(1 << COM0A1); TCCR0A |=  (1 << COM0A0);
  TCCR0B &= ~(1 << WGM02);  TCCR0A |=  (1 << WGM01);  TCCR0A &= ~(1 << WGM00); 
  TCCR0B &= ~(1 << CS02);   TCCR0B &= ~(1 << CS01);   TCCR0B &= ~(1 << CS00);
  // Button
  DDRB  &= ~(1 << PB2);
  MCUCR |=  (1 << ISC01); MCUCR &= ~(1 << ISC00);
  GIMSK |=  (1 << INT0);
  // LED's 
  DDRB |= (1 << PB3);  DDRB |= (1 << PB4);

}

void loop() {

  if (btn) {
     for (float n=0;n++; n<16000) {}
     t++;
     if (t>2) {t=0;}
     switch (t){
        case 0:   TCCR0B &= ~(1 << CS02); TCCR0B &= ~(1 << CS01); TCCR0B &= ~(1 << CS00);
                  PORTB &= ~(1 << PB4); PORTB &= ~(1 << PB3);
        break;
        case 1:   TCCR0B &= ~(1 << CS02); TCCR0B |=  (1 << CS01); TCCR0B |=  (1 << CS00);
                  OCR0A = 0x62; // 79,7 Hz
                  PORTB |=  (1 << PB4); PORTB &= ~(1 << PB3);
        break;
        case 2:   TCCR0B &= ~(1 << CS02); TCCR0B |=  (1 << CS01); TCCR0B |=  (1 << CS00);
                  OCR0A = 0x3B; // 131,8 Hz
                  PORTB &= ~(1 << PB4); PORTB |=  (1 << PB3);
        break;   
     }
     btn=false;
  }
}

ISR(INT0_vect) {
    btn=true;
}