Proton BASIC Compiler - Creating tones for Radio Teletype

  • PicŪ Basic

  • Creating tones for Radio Teletype

    Radio teletype (RTTY) is a useful means of transmitting simple data by radio. The code provided generates RTTY tones and models one way of sending string data from a PICŪ to a PC running Ham Radio Deluxe.

    This project is part of a larger one involving a controller for an amateur radio repeater system. My current controller ( has become very complex and as a result it is easy to lose track of which functions are set and which are not. I needed a system of sending the status of the controller to the managing stations.

    There are a number of programs available for the PC that can decode various digital signals. My favourite is Ham Radio Deluxe as it caters for a wide range of digital modes and in particular RTTY . HRD also has the capacity to adjust to 'off frequency' signals so the setting of the RTTY tones is less critical.

    Why RTTY?
    (1) the data rate is potentially simple to generate in a PICŪ,
    (2) it does not put undue restrictions on the audio path to the transmitter or the path through the receiver as the tones are in normal speech frequencies (nominally 2125 and 2295Hz with a shift of 170Hz)
    (3) the ready availability of free or inexpensive decode programs.

    A search of the internet for ideas on generating RTTY tones was not fruitful although there was one C solution to the problem. Fortunately Wastrix (William) and CaptainSlarty (Joe) came to my rescue with suggestions. The idea of using the HPWM command was tried and although it worked there were a large number of switching clicks that introduced errors. Joe had previous experience with RTTY and came up with a routine using Timer0. In the final product I used his idea. Interestingly there were still clicks in my version while there were none in Joe's test routines. Many experiments later it became clear that the tone routines themselves were not at fault but as soon as additional code was added the 'random' clicks returned. The clicks were not altogether random, they were usually worse shortly after switch on and then settled down to a pattern over many seconds.

    How does it work?
    The PICŪ used was a 18F452 but most devices could be used. Note that the minimum tone frequency is determined by the oscillator frequency. I used a 20MHz crystal. An interrupt routine is at the heart of the process.

    Firstly Timer0 is initialised with high priority interrupts and 16 bit operation
    TMR0IP = 1 'timer0 high priority interrupt enable
    T0IE = 1 'enable timer0 interrupt
    T0CON = %10001000 'enabled, 16 bit, internal clock, 1:2 prescaler
    GIE = 1 'enable global interrupts

    Next the Timer 0 module High Byte register is loaded with $FB and then the Low Byte Register is loaded with the value to create the mark or space tone. The high byte register should be loaded first (see datasheet).

    Timer0 counts from the value in the timer registers until the 16bit value overflows causing an interrupt and setting TMR0IF (Timer 0 interrrupt flag). The interrupt routine flips the designated port and reloads the timers. As the interrupt happens at the rate set in the timer registers a square wave 'tone' is created. Note that it is not necessary to reset the TMR0IF as this is done automatically during the context restore. Additionally the global interrupt is automatically stopped on entry and restarted on exit so there is no need to code this.

    'Interrupt Routine
    ISR:                                    ' Interrupt Service Routine
                   Context Save
                    If TMR0IF=1 Then
                          TMR0IF = 0               ' clear Timer0 interrupt flag 
                          Toggle OutputPort              
                          TMR0H= T1H             ' reload timer count - high - do high first
                          TMR0L= T1L              ' reload timer count - low
                Context Restore
    'end of hardware interrupt routine
    Notice that the interrupt routine is wrapped within High_Int_Sub_Start and High_Int_Sub_End compiler commands to ensure that any system variables used in the interrupt routine are saved and restored. Similarly Context Save and Context Restore are used to ensure that the registers are saved and recovered. It was found necessary to include both sets to significantly reduce the numbers of clicks causing errors.

    The rest of the program reads strings (SendStr), pulls them apart a letter at a time, converts each letter to the equivalent Baudot (GetBaudot) and sends it to the SendChar routine where each character is rotated through to send either a space or a mark. Each character is made up of 1 start bit (2125=Space), 5 character bits (0=space, 1=mark), 2 stop bits(2295=Mark). The routine SendFigsLtrs checks if the character has changed from a letter to a figure or vice versa and if necessary loads a Letters or figures character to be sent first.

    As this is a test program, the Initialise routine sends some 'diddles' which are actually repeated Letters command, it then sends 3 rows of 30 RYRY (traditional test routine for RTTY) and then drops into the main routine for sending the strings. In this case one predefined string (IntroStr) in EEDATA is sent once and then a second string (StringToGo) is sent for ever.

    Hardware for this test routine consisted of the 18F452 on a protoboard, 20MHz crystal, and a resistor/capacitor low pass filter on pin 38 to the sound card of my computer running HRD. The low pass filter was essentially the one in the PDS Manual for tone generation. There was plenty of bypassing on the +5V rail.

    The image shows a section of the HRD screen with the RTTY print out at top while the waterfall below shows the incoming audio. The audio is not without variation but it seems to work fine. Here is the source code.

  • Recent Activity


    Sleep and how to use it

    Thread Starter: Tim

    Hi, I need to save power in a device (16f1823) so thought, sleep a lot. But I never really used the command before. Reading the data sheet I...

    top204 Yesterday, 12:14 Go to last post