This project is part of a larger one involving a controller for an amateur radio repeater system. My current controller (http://vk5dj.mountgambier.org/Repeater.html) 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.
Code:
'Interrupt Routine
High_Int_Sub_Start
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
EndIf
Context Restore
High_Int_Sub_End
'end of hardware interrupt routine
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.
John
VK5DJ


Menu
Recent Articles


Using PDS with SPI GLCD based on ST7565R Controller
Graphic LCDs based on the ST7565 are cheaper then GLCDs with other controllers. SPI requires only four pins. If the circuit