My project is to send aloft, a balloon carrying a GPS receiver, 2M FM amateur radio and a digital camera. Wanting to 'roll my own' or 'homebrew' the payload TM circuitry rather than buying it, steered me into using RTTY.
While APRS and AX.25 provide data integrity, my programming skills lacked the expertise to implement this method. So I started thinking about using the amateur radio standard AFSK RTTY at 170Hz shift. Data integrity should be maintained fairly accurate because the receiving station and payload will be in Line of Site with each other. The payload TM signal should be very strong at the receiving station(s).
Searching this site and using Google, I could only find a couple of articles in the PICAXE forum and none on this forum. My PIC of choice is the PIC16F627.
Reading the GPS NEMA 0183 data was simple, converting the $GPGGA NEMA string ASCII data into Baudot and readying it for transmit it was a bit trickier.
I have a test array sending Baudot to my o'scope and the data pulses are 22mS, and meet the 45.5 baud Baudot format.
I welcome any comments, suggestions or critiques.
Here is my code:
Code:
'PICBASIC PRO program to read a 4800 BAUD GPS GPGGA NEMA
' 0183 string and transmit it using BAUDOT (RTTY) with standard amateur
' radio AFSK 170Hz shift, using the XR2206 modem.
'
'
INCLUDE "BS2DEFS.BAS"
DEFINE HSER_CLROERR 1 'USART CLEAR OVERFLOW ERROR
DEFINE HSER_TXSTA 24H 'SET USART TX STAUS REG
DEFINE HSER_RCSTA 90H 'SET USART RC STAUS REG
DEFINE HSER_BAUD 4800 'SET USART BAUD RATE
define HSER_SPBRG 50 'SET PIC OSC FOR 4800 BAUD
RXDATA var BYTE (80) 'ALLOCATE 80 BYTES FOR USART RX DATA
PIR1 = $0C 'ASSIGN USART RX INTERUPT REG
PTT VAR PORTB.2 'ASSIGN PTT PIN
O Var PORTB.1 'ASSIGN BAUDOT OUTPUT PIN
I VAR BYTE
L VAR BYTE
'---------------------READ $GPGGA DATA-----------------------------
' Read serial port and wait for "GGA", then load RXDATA with entire
' GPGGA string. Continue loading data for the next 80 characters or
' unitl a "$" is detected.
' Sample GPGGA string:
' $GPGGA,150735.000,3444.9047,N,11849.3610,W,1,09,0.9,1019.8,M,
' -31.9,M,,0000*50
LOADDATA:
HSERIN [WAIT (71,71,65), STR RXDATA \80\24]
'---------------------PTT------------------------------------------
' Send PTT to radio and wait .5 seconds. Your radio interface circuitry
' should receive this PTT signal.
HIGH PTT
PAUSE 500
'---------------------MARK Tone------------------------------------
' Transmit Mark tone of 2295Hz for 2 seconds. No reason, I just
' want to...
HIGH O
PAUSE 2000
'---------------------SEND LTRS 5X TO SYNC RCV STATION-------------
' Transmit LTRS data "11111" 5 times to synchronize recieving station's
' timing. This alerts the receiving station that the next characters are
' BAUDOT letter characters. The LTRS data only needs to be sent one time.
FOR I = 1 TO 5
GOSUB RTTYLTR
NEXT I
'----------------------SEND FIGS 5X--------------------------------
' Transmit FIGS data "11011" 5 times. This alerts recieving station
' that the next characters are to be BAUDOT FIG characters. The FIGS
' data only needs to be sent one time.
FOR I = 1 TO 5
GOSUB RTTYFIG
NEXT I
'----------------------SEND CR AND LF -----------------------------
' Transmit Carriage Return (CR) and Line Feed (LF) 5 times to
' format receiving station display. This ensures the received GPS
' Baudot data will start on a new line.
FOR I = 1 TO 5
GOSUB RTTYCRLF
NEXT I
'----------------------Read GPS ASCII Data-------------------------
' Read RXDATA and convert it to BAUDOT. Since we are only expecting
' 14 unique characters in the NEMA GPGGA string, there is no need to
' convert the entire alphabet and other special characters to BAUDOT.
' Depending on your geographic location, you may want to add an "E"
' and/or "S" to the RXDATA and character routines below.
FOR L = 0 TO 80
IF RXDATA (L) = 0 THEN GOSUB RTTY0
IF RXDATA (L) = 1 THEN GOSUB RTTY1
IF RXDATA (L) = 2 THEN GOSUB RTTY2
IF RXDATA (L) = 3 THEN GOSUB RTTY3
IF RXDATA (L) = 4 THEN GOSUB RTTY4
IF RXDATA (L) = 5 THEN GOSUB RTTY5
IF RXDATA (L) = 5 THEN GOSUB RTTY6
IF RXDATA (L) = 7 THEN GOSUB RTTY7
IF RXDATA (L) = 8 THEN GOSUB RTTY8
IF RXDATA (L) = 9 THEN GOSUB RTTY9
IF RXDATA (L) = "N" THEN GOSUB RTTYN
IF RXDATA (L) = "W" THEN GOSUB RTTYW
IF RXDATA (L) = "," THEN GOSUB RTTYSPACE 'Convert "," to SPACE
IF RXDATA (L) = "." THEN GOSUB RTTYPERIOD
NEXT L
'---------------------DISABLE PTT AFTER ALL DATA IS TRANSMITTED----
LOW PTT
'------------------------------------------------------------------
PAUSE 60000 'WAIT 60 SECONDS
GOTO LOADDATA 'GO BACK AND READ GPS DATA AGAIN
'---------------------BAUDOT BIT TX SUBROUTINES--------------------
' EACH BAUDOT WORD CONTAINS A 22mS LOW START BIT, 5 22mS HIGH OR LOW
' DATA BITS AND A 44mS HIGH STOP BIT. THE BAUDOT DATA IS SENT LSB FIRST.
' THE ENTIRE BAUDOT WORD IS 176mS LONG.
' START BIT DATA BITS STOP BIT
' 22mS + 110mS + 44mS
'
' IN THE RTTY0: SUBROUTINE BELOW, L2 BRINGS PORTB.1 LOW FOR 44mS(22mS X 2).
' THE FIRST 22mS LOW IS THE START BIT AND THE LAST 22mS IS BIT0. H2
' BRINGS PORTB.1 HIGH FOR 44mS. THE FIRST 22mS IS BIT1 AND THE LAST 22mS
' IS FOR BIT2...ETC.
'
' L1 = LOW PORTB.1 FOR 22mS
' H2 = HIGH PORTB.1 FOR 44mS
' H5 = HIGH PORTB.1 FOR 110mS...ETC
'
RTTY0: 'TX BAUDOT "0"
GOSUB L2 'TX START BIT and BIT0(LSB)
GOSUB H2 'TX BIT1 and BIT2
GOSUB L1 'TX BIT3
GOSUB H3 'TX BIT4(MSB) and STOP Bit
RETURN
RTTY1: 'TX BAUDOT "1"
GOSUB L1 'TX START BIT
GOSUB H3 'TX BIT0, BIT1 AND BIT2
GOSUB L1 'TX BIT4
GOSUB H3 'TX BIT4(MSB) and STOP Bit
RETURN
RTTY2: 'TX BAUDOT "2"
GOSUB L1 'TX START BIT
GOSUB H2 'TX BIT0 AND BIT1
GOSUB L2 'TX BIT3
GOSUB H3 'TX BIT4(MSB) and STOP Bit
RETURN
RTTY3: 'TX BAUDOT "3" OR 01100011
GOSUB L1 'TX START BIT
GOSUB H2 'TX BIT0 AND BIT1
GOSUB L3 'TX BIT2, BIT3 AND BIT4
GOSUB H2 'TX STOP BIT
RETURN
RTTY4: 'TX BAUDOT "4"
GOSUB L2 'TX START BIT and BIT0(LSB)
GOSUB H1 'TX BIT1
GOSUB L1 'TX BIT2
GOSUB H1 'TX BIT3
GOSUB L1 'TX BIT4
GOSUB H2 'TX STOP BIT
RETURN
RTTY5: 'TX BAUDOT "5"
GOSUB L5 'TX START BIT AND BIT0 - BIT3
GOSUB H3 'TX BIT4 and STOP Bit
RETURN
RTTY6: 'TX BAUDOT "6"
GOSUB L1 'TX START BIT
GOSUB H1 'TX BIT 0
GOSUB L1 'TX BIT1
GOSUB H1 'TX BIT2
GOSUB L1 'TX BIT3
GOSUB H3 'TX BIT4(MSB) and STOP Bit
RETURN
RTTY7: 'TX BAUDOT "7"
GOSUB L1 'TX START BIT
GOSUB H3 'TX BIT0 - BIT2
GOSUB L2 'TX BIT3 AND BIT4
GOSUB H2 'TX STOP BIT
RETURN
RTTY8: 'TX BAUDOT "8"
GOSUB L2
GOSUB H2
GOSUB L2
GOSUB H2
RETURN
RTTY9: 'TX BAUDOT "9"
GOSUB L4
GOSUB H4
RETURN
RTTYN: 'TX BAUDOT "N"
GOSUB RTTYLTR
GOSUB L3
GOSUB H2
GOSUB L1
GOSUB H2
GOSUB RTTYFIG
RETURN
RTTYW: 'TX BAUDOT "W"
GOSUB RTTYLTR
GOSUB L1 'TX START BIT
GOSUB H2
GOSUB L2
GOSUB H3 'TX BIT4(MSB) and STOP Bit
GOSUB RTTYFIG
RETURN
RTTYSPACE: 'TX BAUDOT "SPACE"
GOSUB L3
GOSUB H1
GOSUB L2
GOSUB H2
RETURN
RTTYPERIOD: 'TX BAUDOT "."
GOSUB L3
GOSUB H5
RETURN
RTTYCRLF: 'TX BAUDOT CR & LF
GOSUB L4
GOSUB H1
GOSUB L1
GOSUB H2
GOSUB L2
GOSUB H1
GOSUB L3
GOSUB H2
RETURN
RTTYLTR: 'TX BAUDOT LTR
GOSUB L1 'TX START BIT
GOSUB H7 'TX SEVEN HIGH PULSES BIT0 - BIT4 AND A STOP BIT
RETURN
RTTYFIG: 'TX BAUDOT FIG
GOSUB L1 'TX START BIT
GOSUB H2
GOSUB L1
GOSUB H4
RETURN
'-------------------RTTY HIGH/LOW PULSE LENGTH SUBS----------------
' IN BAUDOT, THE START BIT IS LOW FOR 22mS AND EACH DATA BIT IS 22mS
' IN DURATION AND EITHER A LOW (0) OR HIGH (1). WHILE THE STOP BIT
' IS HIGH FOR 44mS.
L1: 'HOLD PORTB.1 LOW FOR 22mS IN DURATION
LOW O
PAUSE 22
RETURN
L2: 'HOLD PORTB.1 LOW FOR 44mS IN DURATION
LOW O
PAUSE 44
RETURN
L3: 'HOLD PORTB.1 LOW FOR 66mS IN DURATION
LOW O
PAUSE 66
RETURN
L4: 'ETC
LOW O
PAUSE 88
RETURN
L5: 'ETC
LOW O
PAUSE 110
RETURN
H1: 'HOLD PORTB.1 HIGH FOR 22mS IN DURATION
HIGH O
PAUSE 22
RETURN
H2: 'HOLD PORTB.1 HIGH FOR 44mS IN DURATION
HIGH O
PAUSE 44
RETURN
H3: 'ETC
HIGH O
PAUSE 66
RETURN
H4: 'ETC
HIGH O
PAUSE 88
RETURN
H5: 'ETC
HIGH O
PAUSE 110
RETURN
H7: 'ETC
HIGH O
PAUSE 154
RETURN
End
Bookmarks