Rem ********************************************************************** Rem * * Rem * PICAXE Repeater Controller by VK6HV * Rem * To be used on our local repeater VK6RWR * Rem * * Rem * ((BETA 2008)) * Rem ********************************************************************** REM A NOTE FROM THE BUILDER - I don't code for a living or even as a hobby... so beware! I am more of a hardware person. I like building high REM power tube type (valve) HF amplifiers for the Amateur Radio Service. Rem Rem Not trying to re-invent the wheel, I spent many hours lurking around the Net reviewing personal web sites Rem for a simple, yet standard approach to controlling two VHF surplus radios for my next PICAXE project. The Rem PICAXE and DTMF chip circuit designs were pretty much straight forward. It was the OpAmp audio section that Rem I needed help with. Noting there were many OpAmp circuits on the Net, I settled on a revised one that is Rem currently in use. Also, this time, I decided to try a project from the ground up. Research, design, art work, Rem etching, drilling, soldering, programming and testing. It's been fun and educational. But takes up so much Rem personal time. Rem If you're keen, feel free to tidy up the code, change things or even add a new feature etc. etc. There is less Rem then 100 bytes left. Rem Thanks to: 1) The personal web site of K5LXP Rem 2) The personal web site of N1KDO Rem 3) The personal web site of "Hippy" Rem 4) Stan ZL2AJZ, Mores Code routine (for some reason, I keep coming back to it!) Rem 5) The personal web site of ??? who only a couple months (Feb. 2008) ago had a "bread boarded" Rem beginnings of a project similar to this one, but his site is "off the air"? I can't seem to find Rem it anymore. Rem 6) To those on the PICAXE forum. Especially "Hippy"! and all his posts in the forum archives. Lots Rem and lots of help stashed away in the archives! Rem 7) Many thanks to Wolfgang DL8UAD for this new revised Morse Code technique. The Morse routine will Rem now bang out ALL punctuation! Even a seven element "$" dollar sign! "dit dit dit dah dit dit dah" Rem 8) Credit if I missed anyone. Rem Another note from the builder. This program re-uses the byte variable over and over.... and over! Don't get Rem lost... cause I do! I put in as many "REM" comments as I thought necessary. I hope there is not to many. Rem Just trying to help. Rem ***** THE PICAXE-18X REPEATER CONTROLLER PROJECT HISTORY ***** Rem Latest changes 11 - 2 - 08 Start of project, design (not all mine), art work, etched 1st. version of circuit board. Hum....now on Rem 4th PICAXE-18X repeater controller version. Others.... not so good:-( It's been fun and educational! Rem Latest changes 12 - 4 - 08 Added DTMF(what a bastard!) Make sure DTMF chip data pins connect to the right PICAXE input pins. This Rem will make things so much easier!!! Rem Latest changes 13 - 4 - 08 Toyed around with code for hours and hours...... I'm not sure what it was? Rem Latest changes 14 - 4 - 08 Took out LCD junk! Serial LCD display is way to slow!!! Rem Latest changes 17 - 4 - 08 Added send a BEEP, K or R option. (see change dated 23-6-08) Rem Latest changes 18 - 4 - 08 Added send T_O during timeout and again after unkeying. Rem Latest changes 19 - 4 - 08 Added Initialising Pass code and Get DTMF Key Presses (what a night, burned the midnight oil!) Uses lots of memory Rem but I couldn't figure out any other way. Rem Latest changed 22 - 4 - 08 Added Mute DTMF tones option. I'm not sure I have it right? The output comes on, the Mute LED comes on, the MPF102 Rem JFET does it's thing??? I really need to hook it up to some radios and see if it really mutes. *** SEE 22-8-08*** Rem Latest changes 23 - 4 - 08 Added Do-Loops at the start of a few sub routines to wait for the repeater to unkey before proceeding. Rem Latest changes 5 - 5 - 08 Took out CORLed on Output6 and PTTLed on Output7 due to 3rd circuit board design. Rem Latest changes 5 - 5 - 08 Moved IDLed from Output5 to Output7 due to 3rd. circuit board design. Rem Latest changes 6 - 5 - 08 Hey! I Peeked & Poked and got the initialising to work.... I think? Rem Latest changes 7 - 5 - 08 Added the ability to adjust the ID Timer and Time Out Timer values. Took out static 3 minute and 10 minute timers. Rem Latest changes 20 - 5 - 08 Added lot of comments. Still lots to do! Rem Latest changes 25 - 5 - 08 Changed out Morse Code routine to the present one (thanks Stan!). The old one you had to program every dot, dash and Rem space. It was very simple and required no cheat sheet, but it took forever to enter the callsign in! Something like Rem 60 EEprom locations. Lots better now! Only 11 EEprom locations now, maximum callsign length is "DE_XX#XXX/R" but Rem requires a cheat sheet located at the end of this program. Rem Latest changes 27 - 5 - 08 Added lots of Morse Code info at the end of the program. Also a cheat sheet to cross reference Letters to Numbers to Rem program the call sign in. Some extra punctuation if your keen. Rem Latest changes 4 - 6 - 08 Added a trap to stop a remote password change. You must now change the password during initialising. And only then!!! Rem Anyone can still guess the 3 digit password and make changes. But no one should be able to hijack your controller and Rem require you to travel to some lonely remote hill top repeater site and re-initialise the controller again. Rem Latest changes 5 - 6 - 08 Removed all the IF, THEN and GOTO's for the "Change Password" and "DTMF key presses" at the end of the program. Rem Used Do - Loops instead. Looks better :) Rem Latest changes 6 - 6 - 08 Added traps to force an absolutely correct sequence of 9 valid digit DTMF tones to change controller options. I've Rem tried all kinds of invalid key DTMF key presses, but I can't seem to fail it. (I'm sure all the hackers are out Rem now to prove me wrong:) Rem Latest changes 7 - 6 - 08 Changed ID callsign from 8 available letters and spaces to 11. Ability to add "DE" and a "" before the Rem Latest changes callsign. Now ability to send DE_XX#XXX/R if you like. Rem Latest changes 9 - 6 - 08 Ability to shut the repeater output off. Shuts the PTT line off. I'm not sure it this is the right way to do it or Rem just the cheap and nasty way. Everything functions as normal, just no output. Rem Latest changes 10 - 6 - 08 Added a DO Loop at the beginning of the ChangeDefaultPassCode: routine so it doesn't hang there forever. You must Rem do something with in 1 minute or it just ID's the repeater. Then the controller goes about it's business as usual. Rem Latest changes 12 - 6 - 08 Added the ability to play a 20 or a 60 element message. Rem Latest changes 14 - 6 - 08 Added a Pre PTT Delay. Just an adjustable delay from the time the COR is detected, until the time the PTT line Rem is initiated. Adjustable from 0 - 2.25 seconds. *** This has been removed *** See 30 - 9 - 08 Rem Latest Changes 19 - 6 - 08 Added an adjustable "off" delay for the fan. Rem Latest Changes 20 - 6 - 08 Added the ability to force the controller to ID the repeater in Morse Code by keying up the repeater and pressing Rem the DTMF keys PASSCODE + 000 + 255 Rem Latest Changes 21 - 6 - 08 Changed out the Main RX loops to something a little better and understandable... I hope. Rem Latest Changes 22 - 6 - 08 Added more REM comments. Also, tidied up others too. Rem Latest Changes 23 - 6 - 08 Added "Silence" to the Beep, K or R option after unkeying the controller. Maybe you didn't want one? Rem Latest Changes 2 - 7 - 08 Added the ability to force the controller to play message #1 in Morse Code by keying up the repeater and pressing Rem the DTMF keys PASSCODE + 000 + 254 Rem Latest Changes 2 - 7 - 08 Added the ability to force the controller to play message #2 in Morse Code by keying up the repeater and pressing Rem the DTMF keys PASSCODE + 000 + 253 Rem Latest Changes 29 - 7 - 08 Added a "Pause 500" at the end of the Begin: routine. Why? I just thought it needed one. Rem Latest Changes 2 - 8 - 08 Added more comments. Also tried to fault the controller.... looking for "bugs"! Rem Latest Changes 19 - 8 - 08 Fixed bug in "Time Out" timer routine. Rem Latest Changes 22 - 8 - 08 Changed code to suit new 5 volt relay which switches the audio. I just couldn't get the MPF102 to work properly. Rem Yes, I know, it's an electro-mechanical relay with moving parts! But the specs say the relay has a life span of Rem 10,000,000 operations! And has gold contacts. I think 10,000,000 operations will out last me! Also, it either will Rem pass audio or it will not pass audio! Nothing like half on and half off like the problems with the MPF102 JFET. Rem Latest Changes 24 - 8 - 08 Changed out DTMF Gosubs at the end of the program to Select Case and saved 14 bytes! Rem Latest Changes 25 - 8 - 08 Added the ability to turn on and off the spare MOSFET switch remotely by using DTMF tones. It is non retentive. Rem You must turn the switch back on if the power is removed from the controller. It's just the way I did it. Change it Rem if you like. DTMF keys are PASSCODE + 000 + 252 to turn ON, DTMF keys are PASSCODE + 000 + 251 to turn OFF. Rem Latest Changes 25 - 8 - 08 Change out all the READ EEPROM statements with one and used a Gosub for all the rest. This code occured 9 different Rem time in the controller program. Save about 90 bytes!!! Rem Latest Changes 29 - 8 0 08 Etched out last and final repeater controller board.... I hope! Rem Latest Changes 30 - 8 - 08 A few last REM comments. Updated the schematic. Updated PCB artwork. Rem Latest Changes 30 - 9 - 08 Remove the dalay that was added 14 - 6 - 08. This was no good and causes a few problems, It wasn't what I really Rem wanted. I changed it to a simple digital filter to try to filter the COR a bit and stop the repeater from keying up Rem unnecessarily. Only time will tell if this simple filter works. Rem Latest Changes 14 - 1 - 08 Removed 2 of the 3 Morse Code values required to ID the repeater in CW. Only one valuse now. It's a bit easier now. Rem The other two values are still needed but and now calculated, rather then in EEprom. Rem Latest Changes 21 - 11 - 08 Fixed a few typo errors in the program comments. Just a general tidy up. Rem Latest Changes 7 - 3 - 09 Changed Morse Code routine so it will now bang out ALL punctuation! Even a seven element "$" dollar sign! Rem "dit dit dit dah dit dit dah" May thanks to Wolfgang, DL8UAD. Rem Latest Changes 30 - 12 - 09 Added the option to turn on, or not turn on, the Fan relay when the PTT goes high. This is if you need a relay to Rem switch on a fan that may be on the TX heat sink. Before, the Fan relay always came on with the PTT relay. Rem Latest Changes 2 - 1 - 10 Posted code Ver.3 on the Internet. Downloaded Ver.3 code into the PICAXE-18X and installed the "relay version" of Rem the controller onto the UniLab KL150b repeater. Seems to be working great! Rem Latest Changes 8 - 2 - 10 Just a tiny tiny tidy up. Found a couple typos. That's it. Rem Latest Changes 15 - 11 - 10 Found somewhat of a bug. (Thanks VK6BHY) Not fixed, but noted. Do not program EEprom location 107 or 108 with a value Rem larger then 100! Be realistic and program your Time Out Timer and ID Timer to a normal value. Say 2 or 3 minutes for Rem your Time Out Timer and 10 - 20 minutes for your ID Timer. If it needs to be 90 - 100 minutes, why not just shut it Rem off by programming a value of 0 in EEprom location 107 or 108, which ever is not required. Rem Latest Changes 13 - 2 - 11 BACK TO BASICS! Took all the BS out and left in the basics. Updated the programming guide too. Rem ********************************************************************** Rem * * Rem * * Rem * PIN# Project Use PICAXE Pin Definition * Rem * * Rem * Pin #1 COR [Analog2 / In2} * Rem * Pin #2 Serial Out [programming] * Rem * Pin #3 Serial In [programming] * Rem * Pin #4 MCRL [program reset] * Rem * Pin #5 0 Volts [0 Volts] * Rem * Pin #6 AUDIO RELAY [Out0 / I2C SDA Data] * Rem * Pin #7 BEEP [Out1] * Rem * Pin #8 SPARE SWITCH [Out2] * Rem * Pin #9 FAN [Out3 /PWM Out] * Rem * Pin #10 PTT [Out4 / IC2 SCL Clock] * Rem * Pin #11 MUTE REPEATER LED [Out5] * Rem * Pin #12 MUTE DTMF TONES LED [Out6] * Rem * Pin #13 MORESE CODE ID LED [Out7] * Rem * Pin #14 5 Volts [+5 Volts] * Rem * Pin #15 DTMF BIT 1 [In6 Keyboard Data] * Rem * Pin #16 DTMF BIT 2 [In7 Keyboard Clock] * Rem * Pin #17 DTMF BIT 3 [Analog0 / In0 Infrain] * Rem * Pin #18 DTMF BIT 4 [Analog1 / In1] * Rem * * Rem * The DTMF Tone detected LED is off the DTMF chip! * Rem ********************************************************************** Symbol AudioRelay = Output0 Symbol COR = Input2 Symbol SpareSwitch = Output2 Symbol Fan = Output3 Symbol PTT = Output4 Symbol MuteRepeaterLed = Output5 Symbol MuteDTMFLed = Output6 Symbol IDLed = Output7 Symbol Timer1 = W5 'This is the Time Out timer, it's really just a counter, incrementing 1 count every 17mS. 'it's not perfect, but it works OK. 17mS. plus overheads. Symbol Timer2 = W6 'This is the ID Timer, again, it's really just a counter, incrementing 1 count every 17mS. 'it's not perfect, but it works OK. 17mS. plus overheads. '########################################################################################################################### '# Begin: '# Change Output 0 to an Input and then test it to see if there is 5 volts on it or not, if 5 volts, Goto Initialising, '# if 0 volts, Goto ID_TheRepeater. '# '########################################################################################################################### Begin: PEEK $AE, b0 LET b0 = b0 OR %00000001 'Set appropriate bits POKE $AE, b0 PEEK $06, b0 'Read inputs from PORTB data register POKE $AE, %00000000 'Change pin 6 from and Input back to an Output Pause 500 'Just a pause, doesn't have to be here If b0 = 0 Then Goto ID_TheRepeater1stTime '########################################################################################################################### '# Initialising: '# Writes all the data to EEprom for the repeater call sign, Hang Timer, Timers etc. etc. This is done on power up or MCLR '# reset and only if the initialize switch is in the "initialize" position. '# '########################################################################################################################## Initializing: REM V K 6 R W R EOM 0 0 0 0 EEPROM 1, (24,13,33,10,14,10,255,0 ,0, 0, 0) 'Maximum of 11 letters. EEprom locations 1 - 11. The letter/number 'cheat sheet is at the end of the program code. The longest available call is 11 elements. 'Example: "DE_XX#XXX/R". Use the number 255 to end your callsign if it is shorter then '11 elements. The number 255 is the E.O.M. - End of message designator. EEPROM 12, (13) 'SENDS LETTER K, EEprom location 12 EEPROM 13, (3,15) 'SENDS LETTERS T_O, EEprom locations 13 - 14 EEPROM 15, (5,15) 'SENDS LETTERS N_O, EEprom locations 15 - 16 EEPROM 17, (10) 'SENDS LETTER R, EEprom locations 17 EEPROM 100, (123) 'PASSCODE, EEprom location 100, Default Passcode is 123 EEPROM 101, (112) 'TONE, Tone Pitch for Speaker Output, Callsign ID, around 110 - 115 is good EEPROM 102, (6) 'MORSE SPEED - EEprom Value. Dit length = Dit length x 1, Dash length = Dit length x 3, 'Character Space = Dit length x 3, Word Space = Dit length x 5 EEPROM 103, (10) 'PRE BEEP DELAY, Delay after the COR has dropped and before the Roger Beep. Delay in 10mS x N, 'maximum 2.55 seconds EEPROM 104, (15) 'HANG TIMER, This is the Hang Time Delay in 100mS x N, maximum 25.5 seconds EEPROM 105, (1) 'SEND - Silence or "ROGER BEEP" or the LETTER "K" or the LETTER "R" after unkeying. Silence = 0, 'Beep = 1, "K" = 2 and "R" = 3 EEPROM 106, (2) 'TIMER1 - This is the TIME OUT TIMER, 0 - 20 minutes (much more then 20 minutes will not work!) 'A value of 0 = off. EEPROM 107, (15) 'TIMER2 - This is the ID TIMER, 0 - 20 minutes (much more then 20 minutes will not work!) 'A value of 0 = off. EEPROM 108, (0) 'MUTES DTMF TONES, 0 = No, 1 = Yes EEPROM 109, (0) 'TURN FAN ON OR NOT, This is to use the Fan Relay or not. 0 = No, 1 = Yes EEPROM 110, (2) 'Silence, Beep or notify in CW the letters N_O that DTMF tones were an incorrect sequence or value. '0 = Silence, 1 = Beep and 2 = N_O. 0 (zero) is good if you have an IRLP node operating. No matter 'what, after a correct sequence of 9 digits, the controller will still send a letter "K" in Morse. EEPROM 255, (0) 'SWITCH PTT LINE OFF, *** BEWARE, THIS CAN MUTE THE REPEATERS TRANSMITTER RADIO *** '0 = No, 1 = Yes, (0 = PTT Switches On and Off as required, 1 = PTT Always Off!!! '########################################################################################################################### '# InitializingThreeBeeps: '# Sent here from the initial power up if the "Initialize switch S2 is in the "Initialize" position. This keys up the '# repeater and sends three 250mS. tones to let the operator know the controller is ready to receive a change in the '# default passcode. Then Goto ChangeDefaultPassCode. '# '# Key up and press 3 valid tones to change the passcode within 1 minute! If you wait to long, you will hear the repeater '# ID. You missed your chance! You need to recycle the power again and key in a 3 digit tone before the 1 minute expires! '# '# Note: If you leave the "initialize" switch in the initialize position when you key in the new passcode, the DTMF tones '# are 100% muted. If you move S2 to the "normal" position, then key in the tones, then it will depend on the setting of '# EEPROM memory locatoin 111 if the DTMF tones are muted or not. '# '# *** NOTE*** AFTER ENTERING A NEW PASSCODE, DON'T LEAVE THE INITIALIZE SWITCH S1 IN THE INITIALIZE POSITION AFTER '# CHANGING THE PASSCODE! MOVE IT TO THE NORMAL POSITION! OTHERWISE THE DTMF TONES AND REPEATER AUDIO ARE MUTED ALL THE '# TIME! (don't forget) '# '# ID Led is on Output 7. '# Fan is on Output 3. '# COR is on Input 2. '# Beep is on Output 1. '# '########################################################################################################################### InitializingThreeBeeps: Gosub SwitchPTTLineOn Pause 1000 For b10 = 1 to 3 High IDLed Gosub RogerBeep Pause 250 Low IDLed Pause 250 Next B10 = 0 Gosub SwitchPTTLineOFF Goto ChangeDefaultPassCode '########################################################################################################################### '# ID_TheRepeater1stTime: '# Check to see on power up if the value of EEPROM location 107 is 0. If so, goto MainRXLoop3, else ID the repeater. '# '# ID_TheRepeater: DEFAULT: VK6RWR '# Check to see on power up if the value of EEPROM location 107 is 0. If so, goto KeyUpRepeater, else ID the repeater. '# Loop until the repeater is "unkeyed" because someone is still talking. Zero Timer2. Then switch on PTT, send the repeater '# callsign, in Morse Code, Before unkeying, goto EndID '# '########################################################################################################################### ID_TheRepeater1stTime: Gosub ZeroAllBytes Read 107, b7 If b7 = 0 Then Goto MainRXLoop3 ID_TheRepeater: Gosub ZeroAllBytes Read 107, b7 If b7 = 0 Then Goto KeyUpRepeater Do Loop until COR = 1 Timer2 = 0 Gosub SwitchPTTLineON Pause 500 Gosub ZeroAllBytes Gosub GetMorseSettings For b7 = 1 TO 11 Read b7, b4 IF b4 = 255 Then Goto EndID Gosub Morse Next Goto EndID '########################################################################################################################### '# Morse: '# This is the subroutine to handle the Morse Code. Space, Dot & Dah lengths. Turn the IDLed on and off. Speaker tone etc. '# b0 - b3 are from the "GetMorseSettings" routine. They are as follows: Quiet = 0, Tone = b0, Dit Length = b1, '# Dah Length = b2, Character_Space = b2, Word_Space = b3, '# '# Encoded_Character = b4 Encoded character number from the cheat sheet at the end of the program. '# Even_Or_Odd_Character = b5 Result of the modulus divide by 2, checks to see if it's odd or even. (dit or dah) '# Index = b7 A variable to count as the encoded characters are indexed through. '# '# IF b4 = 255, then E.O.M. "End Of Message" is so it doesn't bang out extra "character spaces" in the repeater callsign '# when you've not used all 11 of them. '# '# Morse Code routine from Stan, ZL2APS. Also many thanks to Wolfgang, DL8UAD for his idea which now allows the Morse '# routine to bang out ALL punctuation! Even a seven element "$" dollar sign! "dit dit dit dah dit dit dah" '# '########################################################################################################################### Morse: If b4 = 0 then Word_space Do b5 = b4 // 2 'returns remainder, odd or even (dit or dah) b4 = b4 / 2 'shift right If b5 = 0 then Gosub dit If b5 = 1 then Gosub Dah Loop until b4 = 1 Gosub Character_space Return Dit: High 7 Sound 1, (b0,b1) Low 7 Sound 1, (0,b1) Return Dah: High 7 Sound 1, (b0,b2) Low 7 Sound 1, (0,b1) Return Character_space: Sound 1, (0,b2) Return Word_space: Sound 1, (0,b3) Return '########################################################################################################################### '# MainRXLoop1: DEFAULT: 10 '# Gosub SwitchPTTLineOFF, Gosub ZeroAllBytes, Read EEPROM 107 into b7, if it's 0, Goto MainRXLoop3. Else DO. '# Start of DO, 17mS. clock pulse, increment Timer2 + 1, crunch the maths, check the COR, if it's 0 then Goto KeyUpRepeater '# If b6 = b7 then Goto ID_TheRepeater '# '# *** NOTE *** *** NOTE *** *** NOTE *** *** NOTE *** *** NOTE *** *** NOTE *** *** NOTE *** '# Don't program EEPROM location 107 with a value of 20 or more. Otherwise the ID Timer will not work properly! '# '# MainRXLoop2: DEFAULT: 5 '# Same as MainRXLoop1 except in the DO. If b6 = b7 then Goto MainRXLoop3 '# '# MainRXLoop3: '# Zero Timer2, now just loop until the COR is 0 (active) Just hang out here and do nothing until '# someone keys up the repeater '# '# Fan is on Output 3. '# COR is on Input 2. '# '########################################################################################################################### MainRXLoop1: Gosub SwitchPTTLineOFF Gosub ZeroAllBytes Read 107, b7 If b7 = 0 Then Goto MainRXLoop3 Do 'This sould be a Pause 20 (20mS.) but taking into account execution time overheads. Pause 17 Timer2 = Timer2 + 1 b6 = w6 / 3000 If COR = 0 Then Goto KeyUpRepeater If b6 = b7 Then Goto ID_TheRepeater Loop MainRXLoop2: Gosub SwitchPTTLineOFF Gosub ZeroAllBytes Read 107, b7 If b7 = 0 Then Goto MainRXLoop3 Do Pause 17 'This should be a Pause 20 (20mS.) but taking into account execution time overheads. Timer2 = Timer2 + 1 b6 = w6 / 3000 If COR = 0 Then Goto KeyUpRepeater If b6 = b7 Then Goto MainRXLoop3 Loop MainRXLoop3: Timer2 = 0 Do If COR = 0 Then Goto ID_TheRepeater Loop '########################################################################################################################### '# KeyUpRepeater: '# Gosub SwitchPTLineON '# '# KeyUpRepeater2: '# This is the main "radio keyed up" loop when someone is using the repeater. Start of DO, checks "pins" from DTMF chip to '# see if any DTMF tones have been sent. Then increment both the ID Timer and the Time Out Timer. 20mS. clock pulse for the '# Timers (1mS). Gosubs for KeyUpRepeater2Timer1 and KeyUpRepeaterTimer2. These Gosubs check to see if Timer1 or Timer2 '# have timed out. This loops until the COR = 1 (not active). '# '# Note: There is so much execution time in this bit of code that a 1mS is all that is needed rather the 20mS. '# '# COR is on Input 2. '# '########################################################################################################################### KeyUpRepeater: Gosub SwitchPTTLineON KeyUpRepeater2: Do b0 = pins b0 = b0 AND %11000011 If b0 >= 1 Then Goto CheckPasscodeAndKeyInData Timer1 = Timer1 + 1 Timer2 = Timer2 + 1 Pause 1 Gosub KeyUpRepeater2Timer1 Gosub KeyUpRepeater2Timer2 If COR = 1 Then Goto UnKeyRepeater Loop '########################################################################################################################### '# KeyUpRepeater2Timer1: DEFAULT: 3 '# Zero All Bytes. Read the value from EEPROM location 106 and put it into variable b7, crunch maths, if b7 = 0 then Return. '# If b6 = b7, Goto TimedOutFirstID, Return to KeyUpRepeater2. '# '# Note: "If b7 = 0, this shuts off the Time Out Timer if a 0 is in EEPROM location 106. '# '# *** NOTE *** *** NOTE *** *** NOTE *** *** NOTE *** *** NOTE *** *** NOTE *** *** NOTE *** '# Don't program EEprom 106 location with a value greater then 20. Otherwise the Time Out Timer will not work properly! '# '########################################################################################################################### KeyUpRepeater2Timer1: Gosub ZeroAllBytes Read 106, b7 b6 = w5 / 3000 If b7 = 0 Then Return EndIf If b6 = b7 Then Goto TimedOutFirstID Return '########################################################################################################################### '# KeyUpRepeater2Timer2: DEFAULT: 10 '# Zero All Bytes. Read the value from EEPROM location 107 and put it into variable b9, crunch maths, if b9 = 0 then Return. '# If b8 and b9, Goto ID_TheRepeater. Return to KeyUpRepeater2. '# '# Note: "If b9 = 0, this shuts off the ID Timer if a 0 is in EEPROM location 107. '# '# *** NOTE *** *** NOTE *** *** NOTE *** *** NOTE *** *** NOTE *** *** NOTE *** *** NOTE *** '# Don't program EEprom 107 location with a value greater then 20. Otherwise the ID Timer will not work properly! '# '########################################################################################################################### KeyUpRepeater2Timer2: Gosub ZeroAllBytes Read 107, b9 b8 = w6 / 3000 If b9 = 0 Then Return EndIf If b8 = b9 Then Goto ID_TheRepeater Return '########################################################################################################################### '# UnKeyRepeater: '# Before the PTT is dropped, set Timer1 to zero. Gosub PreBeepDelay. This is a delay from the time the COR is dropped, '# COR = 1,(inactive) and the time of the "Beep, K or R". Gosub and test if a Beep, K or R needs to be sent. Then Gosub the '# Hang Timer. Hang Timer delay is the time delay after "Silence, Beep, K or R" until the time the PTT line (Output 4) is '# shut off by the controller. A delay of about .5 seconds is good. Check the COR and see if the repeater is still "keyed up". '# If so, then don't unkey and Goto KeyUpRepeater, else Goto MainRXLoop1. '# '# COR is on Input 2 '# PTT is on Output 4 '# '########################################################################################################################### UnKeyRepeater: Timer1 = 0 Gosub PreBeepDelay Gosub SendSilence_Beep_K_Or_R Gosub HangTimer If COR = 0 Then Goto KeyUpRepeater Goto MainRXLoop1 '########################################################################################################################### '# PreBeepDelay: DEFAULT: 10 '# Zero all the bytes. Read the value from EEPROM location 103 and put it into variable b1, For-Next Default 10 times with '# a 10mS. pause. This equals a 100mS. "pre beep" delay before the BEEP, then Returns. '# '########################################################################################################################### PreBeepDelay: Gosub ZeroAllBytes Read 103, b1 For b0 = 1 to b1 Pause 10 Next Return '########################################################################################################################### '# HangTimer: DEFAULT: 15 '# Zero all the bytes. Read the value from EEPROM location 104 and put it into variable b1, For-Next default 10 times with '# a 100mS. pause. This equals a 1500mS. "Hang Timer delay after the BEEP, then Returns. '# '########################################################################################################################### HangTimer: Gosub ZeroAllBytes Read 104, b1 For b0 = 1 to b1 Pause 100 Next Return '########################################################################################################################### '# RogerBeep: DEFAULT: 101 = 112 (about 1000Hz.) 102 = 6 (times 10mS. duration) '# Zero all the bytes, Read the values from EEPROM locations 101 and 102 and put them into variables b0 and b2. '# '# Note:These are values from the morse code routine for "tone" and "dash length" Then Returns. '# '# Sound out on Output 1 '# IDLed out on Output 7 '# '########################################################################################################################### RogerBeep: Gosub ZeroAllBytes Gosub GetMorseSettings High IDLed Sound 1, (b0, b2) Low IDLed Return '########################################################################################################################### '# TimedOutFirstID: '# ZeroAllBytes, Zero out Timer1, Gosub GetMorseSettings, these values are for the morse code routine. This sends the '# letters "T O" in Mores Code right over the offending person talking on the repeater and then turns the output of the '# repeater off. Continues at TimedOutSecondID: '# '########################################################################################################################### TimedOutFirstID: Gosub ZeroAllBytes Timer1 = 0 Gosub GetMorseSettings For b7 = 13 TO 14 Read b7, b4 Gosub Morse Next Gosub SwitchPTTLineOFF '########################################################################################################################### '# TimedOutSecondID: '# DO, increment Timer2, pause 20mS. and Loop until the COR = 1 (inactive) until the offending person unkeys the repeater. '# Gosub GetMorseSettings, these values are for the morse code routine. This sends the letters "T_O" in Mores Code after '# the offending person talking has unkeyed the repeater. This is to let the offender:) know he or she has "TIMED OUT". '# '# Pause 20 in this routine is a '***** 20mS. clock pulse to keep Timer2 timing (counting) ***** '# '########################################################################################################################### TimedOutSecondID: Do Timer2 = Timer2 + 1 Pause 20 Loop until COR = 1 Pause 250 Gosub SwitchPTTLineON Pause 250 Gosub ZeroAllBytes Gosub GetMorseSettings For b7 = 13 TO 14 Read b7, b4 Gosub Morse Next If COR = 0 Then Goto KeyUpRepeater Gosub HangTimer Goto MainRXLoop1 '########################################################################################################################### '# ZeroAllBytes: '# Zeros all bytes b0 - b9 (Words w0 - w4) and then returns to where ever it was sent from. Since the varibles are used '# over and over. they must be "zeroed" before the next use as they hold old values from a previous block of code. '# '########################################################################################################################### ZeroAllBytes: w0 = 0 'b0 and b1 w1 = 0 'b2 and b3 w2 = 0 'b4 and b5 w3 = 0 'b6 and b7 w4 = 0 'b8 and b9 Return '########################################################################################################################### '# GetMorseSettings: '# Reads the values from EEPROM locations 101 - 104 and put them in to variables b0 - b3. This is required many times in the '# controller program. '# '########################################################################################################################### GetMorseSettings: Read 101, b0 Read 102 ,b1 b2 = b1 * 3 b3 = b1 * 5 Return '########################################################################################################################### '# SendSilence_Beep_K_Or_R: DEFAULT: 1 ((Send "BEEP")) '# Zero all bytes, Read the value from EEPROM location 105 and put it into variable b0. Select Case for Silence, Beep, '# Letter "K" or Letter "R". Letters "K" or "R" are sent in Morse Code. '# '########################################################################################################################### SendSilence_Beep_K_Or_R: Gosub ZeroAllBytes Read 105, b0 Select Case b0 Case 0 Return Case 1 Gosub RogerBeep Case 2 Gosub SendLetterK Case 3 Gosub SendLetterR Endselect Return '########################################################################################################################### '# SendLetterK: '# Zero all bytes, Gosub GetMorseSettings, these values are for the morse code routine. Read the value in EEPROM location '# 12 and put it into variable b4. This will bangs out the letter "K" in Morse code, then Returns. '# '# SendLettersN_O: '# Zero all bytes, Gosub GetMorseSettings, these values are for the morse code routine. Read the values in EEPROM locations '# 15 and 16 and put them into variable b4 one at a time with the For-Next. This will bangs out the letters "N" and "O" in '# Morse code, then Returns. '# '# SendLetterR: '# Zero all bytes, Gosub GetMorseSettings, these values are for the morse code routine. Read the value in EEPROM location '# 17 and put it into variable b4. This will bangs out the letter "R" in Morse code, then Returns. '# '########################################################################################################################### SendLetterK: Gosub ZeroAllBytes Gosub GetMorseSettings Read 12, b4 Gosub Morse Return SendLettersN_O: Gosub ZeroAllBytes Gosub GetMorseSettings For b7 = 15 TO 16 Read b7, b4 Gosub Morse Next Return SendLetterR: Gosub ZeroAllBytes Gosub GetMorseSettings Read 17, b4 Gosub Morse Return '########################################################################################################################### '# EndID: Checks the COR, if it is = 0 (active) then goto KeyUpRepeater. If not, Gosub the Hang Timer, the Goto MainRXLoop2. '# '########################################################################################################################### EndID: If COR = 0 Then Goto KeyUpRepeater Gosub HangTimer Goto MainRXLoop2 '########################################################################################################################### '# SentBadData: '# Loops until the COR = 1 (inactive) Repeater unkeyed. Then Gosub ZeroAllBytes, Select Case for a 0, 1 or 2. If Case 0, '# then send silence, If Case 1, send Roger Beep. If Case 2, send N_O in Morse Code. In all Cases, HangTimer, then either '# check the COR and see if it = 0. (active) If COR = 0 then KeyUpRepeater or Goto MainRXLoop1. '# '# SentGoodData: '# Loops until the COR = 1 (inactive) Repeater unkeyed. Then Gosub UnMuteDTMFTones, UnMuteDTMFTones, Then Gosub '# PreBeepDelay, a short delay. Then Gosub SendLetterK, sends the letters "K" in Morse Code. Gosub HangTimer. Check the COR, '# and see if it = 0. (active) If COR = 0 then KeyUpRepeater. If COR = 1 then Goto MainRXLoop1. '# '########################################################################################################################### SentBadData: Do Loop until COR = 1 Gosub ZeroAllBytes Read 110, b0 Select Case b0 Case 0 Gosub UnMuteDTMFTones Gosub HangTimer Goto MainRXLoop1 Case 1 Gosub UnmuteDTMFTones Gosub PreBeepDelay Gosub RogerBeep Gosub HangTimer If COR = 0 Then Goto KeyUpRepeater Goto MainRXLoop1 Case 2 Gosub UnMuteDTMFTones Gosub PreBeepDelay Gosub SendLettersN_O Gosub HangTimer If COR = 0 Then Goto KeyUpRepeater EndSelect Goto MainRXLoop1 SentGoodData: Do Loop until COR = 1 Gosub UnMuteDTMFTones Gosub PreBeepDelay Gosub SendLetterK Gosub HangTimer If COR = 0 Then Goto KeyUpRepeater Goto MainRXLoop1 '########################################################################################################################### '# MuteDTMFTones: DEFAULT: 0 '# Zero All Bytes. Read the value of EEPROM location 108 and put it into variable b0. Select Case, if b0 = 0 then DTMF '# Tones are NOT muted. If b0 = 1 then DTMF Tones ARE muted. '# '# If the controller detects DTMF tones while the COR = 0, (active) it will come here and check if the tones should be '# muted while you are making a change to the default settings. You wouldn't want anyone to hack your passcode! The tones '# are muted on Output pin #0. This mutes the audio line from the receiver to the transmitter. '# '# UnMuteDTMFTones: '# Turn off MuteDTMFLed, turn on Audio Relay, Return '# '# Audio Relay is on Output 4 '# MuteDTMFLed is on Output 6 '# '########################################################################################################################### MuteDTMFTones: Gosub ZeroAllBytes Read 108, b0 Select Case b0 Case 0 High AudioRelay Low MuteDTMFLed Case 1 Low AudioRelay High MuteDTMFLed Endselect Return UnMuteDTMFTones: Low MuteDTMFLed High AudioRelay Return '########################################################################################################################### '# SwitchPTTLineON: DEFAULT: 1 '# Zero All Bytes. Read the value in EEPROM location 255 and put it into variable b0. Select Case. If b0 = 0 then the '# repeater output is ON or OFF as required. If b0 = 1, then the *** Repeater PTT is off all the time! *** '# '# This is to shut the repeater output off. If the default is changed to a value of 1 in EEPROM location 255, then it '# will disable the PTT line and not let it operate. There will be no output but still receive signals on the receiver as '# it normally would. I'm not sure if this is how other repeater controllers do this, I'm not a repeater guru, but it's how '# I did it. '# '# SwitchPTTLineOFF: '# Turns the PTT Line low when required. '# '# PTT is on Output 4. '# '########################################################################################################################### SwitchPTTLineON: Gosub ZeroAllBytes Read 255, b0 Select Case b0 Case 0 'This should operate the repeater as normal Gosub TurnFanOnOrNot High PTT High AudioRelay Low MuteRepeaterLED Case 1 'This should mute the repeater and disable the repeater transmitter! Low PTT Low AudioRelay High MuteRepeaterLED Endselect Return SwitchPTTLineOFF: Low AudioRelay Low PTT Low Fan Return '########################################################################################################################### '# TurnFanOnOrNot: DEFAULT: 0 (fan relay not energized when PTT goes high) '# This is an option to turn the fan relay on when the PTT goes high. It is for turning on a fan that is pointed at or '# bolted onto the TX heat sink. 0 = off, 1 = on '# '# Fan is on Output3 '# '########################################################################################################################### TurnFanOnOrNot: Gosub ZeroAllBytes Read 109, b9 If b9 = 0 then Low Fan else High Fan End If Return '########################################################################################################################### '# TurnOnSpareSwitch: DEFAULT: Passcode + 000 + 252 = ON Passcode + 000 + 251 = OFF '# Turns on or off the spare MOSFET transistor. '# '# This will not be maintained if power is removed from the controller. You must turn it back on again if required! '# '# Spare MOSFET Switch or Relay is on Output 2. '# '########################################################################################################################### TurnOnSpareSwitch: High SpareSwitch Do Loop until COR = 0 Goto SentGoodData TurnOffSpareSwitch: Low SpareSwitch Do Loop until COR = 0 Goto SentGoodData '########################################################################################################################### '# ChangeDefaultPassCode: DEFAULT: 123 '# Changes the default "Passcode" here. This comes from the very first power up with the "initializing" switch S2 closed. '# The operator must key up the transmitter and key in 3 valid DTMF tones using keys 0 and 9 to represent one large number '# between 000 and 255. This will change the default password in EEPROM location 100 and send the letter K in Morse to let '# the operator know they have entered a valid 3 digit password. If the COR is dropped while keying in the 3 DTMF tones or '# a non valid number larger then 255 is entered, the letters N_O will be sent in Morse. You must recycle the power and ;# re-initialize again. Remember to put the switch back in the NORMAL position after entering a new valid passcode. DON'T '# FORGET! Again, the default pass code is the number 123. '# '# You can also change the password by putting the initializing switch in the initialize position and pressing and '# releasing the MCLR switch. This is switch S1. This will beep three times again and wait for the operator to key in 3 '# valid numbers for a new passcode. Changing the passcode this way will not erase any previously changed default settings. '# Example: You will not have to change the callsign from the default callsign back to your repeater callsign again. '# '# Note: If you leave the initialize switch in the initialize position when you key in the new passcode, the DTMF tones are '# 100% muted. If you move S2 to the other position, then key in the tones, then it will depends on the setting of EEPROM '# memory locatoin 111 if the tones are muted or not. '# '# There is now a 1 minute timer to stop the program from hanging here. '# '# *** NOTE*** AFTER ENTERING A NEW PASSCODE, DON'T LEAVE THE INITIALIZE SWITCH S2 IN THE INITIALIZE POSITION AFTER '# CHANGING THE PASSCODE! MOVE IT TO THE NORMAL POSITION! OTHERWISE THE DTMF TONES AND REPEATER AUDIO ARE MUTED ALL THE '# TIME! (don't forget) '# '# DTMF BIT 1 is on Input 6. '# DTMF BIT 2 is on Input 7. '# DTMF BIT 3 is on Input 0. '# DTMF BIT 4 is on Input 1. '# '########################################################################################################################### ChangeDefaultPassCode: Timer2 = 0 Do Timer2 = Timer2 + 1 Pause 20 If Timer2 > 3000 Then Goto ID_TheRepeater Loop until COR = 0 Gosub SwitchPTTLineON Gosub MuteDTMFTones Gosub ZeroAllBytes FirstDTMFTone1: 'get first keypad press Do If COR = 1 Then Goto SentBadData b4 = pins b4 = b4 AND %11000011 Loop until b4 > 0 Gosub GetDTMFData b4 = 0 b1 = b0 FirstDTMFTone2: Do If COR = 1 Then Goto SentBadData b4 = pins b4 = b4 AND %11000011 Loop until b4 = 0 SecondDTMFTone1: 'get second keypad press Do If COR = 1 Then Goto SentBadData b4 = pins b4 = b4 AND %11000011 Loop until b4 > 0 Gosub GetDTMFData b4 = 0 b2 = b0 SecondDTMFTone2: Do If COR = 1 Then Goto SentBadData b4 = pins b4 = b4 AND %11000011 Loop until b4 = 0 ThirdDTMFTone1: 'get third keypad press Do If COR = 1 Then Goto SentBadData b4 = pins b4 = b4 AND %11000011 Loop until b4 > 0 Gosub GetDTMFData b4 = 0 b3 = b0 ThirdDTMFTone2: Do If COR = 1 Then Goto SentBadData b4 = pins b4 = b4 AND %11000011 Loop until b4 = 0 '########################################################################################################################### '# WriteNewPasscode: '# This is part which writes the passcode after "power up". Put Initialising switch S2 in the right position and keying '# in 3 DTMF valid tones. The program checks that the tones equal a number between 000 and 255. Numbers larger then 255 '# return will return "N_O" in Morse Code after the operator unkeys. ONLY 3 Digits are required here!!! '# '########################################################################################################################### WriteNewPasscode: w3 = b1 * 100 If w3 > 200 then Goto SentBadData b1 = b1 * 100 b2 = b2 * 10 w3 = b1 + b2 + b3 If w3 > 255 then Goto SentBadData Write 100, w3 Gosub UnMuteDTMFTones Goto SentGoodData '########################################################################################################################### '# CheckPasscodeAndKeyInData: DEFAULT: 123 '# Zero All bytes, Mute the DTMF tones if required. The program will come here if the COR is activated and the controller '# detects DTMF tones. These are the first 3 of 9 tones required to make a change to the default settings. So key up and '# press the 3 valid tones that are the controllers passcode. Remember.... valid tones, 0 - 9! '# '# DTMF BIT 1 is on Input 6. '# DTMF BIT 2 is on Input 7. '# DTMF BIT 3 is on Input 0. '# DTMF BIT 4 is on Input 1 '# '########################################################################################################################### CheckPasscodeAndKeyInData: Gosub MuteDTMFTones Gosub ZeroAllBytes GetFirstDTMFTone1: 'get first keypad press Do If COR = 1 Then Goto SentBadData b4 = pins b4 = b4 AND %11000011 Loop until b4 > 0 Gosub GetDTMFData b4 = 0 b1 = b0 GetFirstDTMFTone2: 'stay here loop until the key press is released. Do If COR = 1 Then Goto SentBadData b4 = pins b4 = b4 AND %11000011 Loop until b4 = 0 GetSecondDTMFTone1: 'get second keypad press Do If COR = 1 Then Goto SentBadData b4 = pins b4 = b4 AND %11000011 Loop until b4 > 0 Gosub GetDTMFData b4 = 0 b2 = b0 GetSecondDTMFTone2: Do If COR = 1 Then Goto SentBadData b4 = pins b4 = b4 AND %11000011 Loop until b4 = 0 GetThirdDTMFTone1: 'get third keypad press Do If COR = 1 Then Goto SentBadData b4 = pins b4 = b4 AND %11000011 Loop until b4 > 0 Gosub GetDTMFData b4 = 0 b3 = b0 GetThirdDTMFTone2: Do If COR = 1 Then Goto SentBadData b4 = pins b4 = b4 AND %11000011 Loop until b4 = 0 '########################################################################################################################### '# CheckPasscodeData: '# This is the password check when keying in DTMF tones to change options. It juggles the first 3 (DTMF tones) numbers to '# make one large number for b1, b2 & b3. (1st, 2nd & 3rd key presses) Then it checks that the passcode is valid. If '# valid, then clear the bytes and gets the next six DTMF key presses. If invalid, the letters "N_O" will be sent in Morse '# Code when the TX is unkeyed. '# '########################################################################################################################### CheckPasscodeData: w4 = b1 * 100 If w4 > 200 then Goto SentBadData b1 = b1 * 100 b2 = b2 * 10 w4 = b1 + b2 + b3 If w4 > 255 then Goto SentBadData b1 = b1 + b2 + b3 b0 = 0 Read 100, b0 If b1 <> b0 Then Goto SentBadData Gosub ZeroAllBytes '########################################################################################################################### '# GetFourthDTMFTone: through GetNinthDTMFTone: '# This is where the program comes if the controller detects valid DTMF tones. Hopefully you are trying to change one of '# the controllers default settings. You must stay "keyed up" continuously and press 9 valid DTMF tones. Only the key '# numbers 0 - 9 only!!! The first three numbers pressed are the passcode. The next 3 tones is the EEPROM memory location '# to write to and that last three tones pressed is the data to write it the memory location. '# '# The program is here for the 4th - 9th key presses. That's if the first three were the correct passcode! '# '########################################################################################################################### GetFourthDTMFTone1: 'get fourth keypad press Do If COR = 1 Then SentBadData b7 = pins b7 = b7 AND %11000011 Loop until b7 > 0 Gosub GetDTMFData b7 = 0 b1 = b0 GetFourthDTMFTone2: Do If COR = 1 Then Goto SentBadData b7 = pins b7 = b7 AND %11000011 Loop until b7 = 0 GetFifthDTMFTone1: 'get fifth keypad press Do If COR = 1 Then Goto SentBadData b7 = pins b7 = b7 AND %11000011 Loop until b7 > 0 Gosub GetDTMFData b7 = 0 b2 = b0 GetFifthDTMFTone2: Do If COR = 1 Then Goto SentBadData b7 = pins b7 = b7 AND %11000011 Loop until b7 = 0 GetSixthDTMFTone1: 'get sixth keypad press Do If COR = 1 Then Goto SentBadData b7 = pins b7 = b7 AND %11000011 Loop until b7 > 0 Gosub GetDTMFData b7 = 0 b3 = b0 GetSixthDTMFTone2: Do If COR = 1 Then Goto SentBadData b7 = pins b7 = b7 AND %11000011 Loop until b7 = 0 GetSeventhDTMFTone1: 'get seventh keypad press Do If COR = 1 Then Goto SentBadData b7 = pins b7 = b7 AND %11000011 Loop until b7 > 0 Gosub GetDTMFData b7 = 0 b4 = b0 GetSeventhDTMFTone2: Do If COR = 1 Then Goto SentBadData b7 = pins b7 = b7 AND %11000011 Loop until b7 = 0 GetEighthDTMFTone1: 'get eighth keypad press Do If COR = 1 Then Goto SentBadData b7 = pins b7 = b7 AND %11000011 Loop until b7 > 0 Gosub GetDTMFData b7 = 0 b5 = b0 GetEighthDTMFTone2: Do If COR = 1 Then Goto SentBadData b7 = pins b7 = b7 AND %11000011 Loop until b7 = 0 GetNinthDTMFTone1: 'get ninth keypad press Do If COR = 1 Then Goto SentBadData b7 = pins b7 = b7 AND %11000011 Loop until b7 > 0 Gosub GetDTMFData b7 = 0 b6 = b0 GetNinthDTMFTone2: Do If COR = 1 Then Goto SentBadData b7 = pins b7 = b7 AND %11000011 Loop until b7 = 0 '########################################################################################################################### '# WriteDataAgain: '# After receiving 6 valid key presses, juggle the numbers to acquire one large number for b1, b2, b3 (4th, 5th & 6th key '# presses) and b4, b5, b6 (7th, 8th & 9th key presses). Write to EEPROM. b1 is the EEprom memory location and b4 is the '# data to be written there. '# '# ***if b1 = 100 (4th, 5th & 6th key presses) then someone is trying to write to the password memory location*** !!! '# ***if w4 > 255 then Goto SentBadData. Only decimal numbers 000 - 255 are valid *** '# '# Sending DTMF tones PASSCODE + 000 + 255 forces the repeater controller to ID. '# Sending DTMF tones PASSCODE + 000 + 252 forces the repeater controller to turn ON spare MOSFET switch. '# Sending DTMF tones PASSCODE + 000 + 251 forces the repeater controller to turn OFF spare MOSFET switch. '# '########################################################################################################################### WriteDataAgain: w4 = b1 * 100 If w4 > 200 then Goto SentBadData b1 = b1 * 100 b2 = b2 * 10 w4 = b1 + b2 + b3 If w4 > 255 then Goto SentBadData b1 = b1 + b2 + b3 If b1 = 100 Then Goto SentBadData '***PASSWORD CHECK*** for memory location #100 w4 = b4 * 100 If w4 > 200 then Goto SentBadData b4 = b4 * 100 b5 = b5 * 10 w4 = b4 + b5 + b6 If w4 > 255 then Goto SentBadData b4 = b4 + b5 + b6 Gosub UnMuteDTMFTones If b1 = 000 and b4 = 255 Then Goto ID_TheRepeater 'forces the repeater to ID! If b1 = 000 and b4 = 252 Then Goto TurnOnSpareSwitch If b1 = 000 and b4 = 251 Then Goto TurnOffSpareSwitch Write b1, b4 If b1 = 255 and b4 = 000 Then Goto ID_theRepeater Goto SentGoodData '########################################################################################################################### '# GetDTMFData: '# b0 = b0 AND %11000011 This masks out the input pin "In2" (inout #2), physical pin #1 This is the COR pin and it's high '# almost all the time. '# '# All this rubbish below is because the "Data Out" pins on the DTMF chip don't line up with the right "Input" pins on the '# PICAXE-18X. (took me hours and hours to figure out what the heck was going on! Definitely burned the midnight oil on '# this one!) '# '# DTMF DATA BIT 1 is on PICAXE Input 6 '# DTMF DATA BIT 2 is on PICAXE Input 7 '# DTMF DATA BIT 4 is on PICAXE Input 1 '# DTMF DATA BIT 8 is on PICAXE Input 0 '# '########################################################################################################################### GetDTMFData: b0 = Pins b0 = b0 AND %11000011 Select Case b0 Case 1 b0 = 8 Case 2 b0 = 4 Case 64 b0 = 1 Case 65 b0 = 9 Case 66 b0 = 5 Case 128 b0 = 2 Case 129 b0 = 0 Case 130 b0 = 6 Case 192 b0 = 3 Case 194 b0 = 7 End Select Return REM FOR THOSE WHO DON'T KNOW MORSE CODE:) REM A .- B -... C -.-. D -.. E . F ..-. REM G --. H .... I .. J .--- K -.- L .-.. REM M -- N -. O --- P .--. Q --.- R .-. REM S ... T - U ..- V ...- W .-- X -..- REM Y -.-- Z --.. REM 1 .---- 2 ..--- 3 ...-- 4 ....- 5 ..... REM 6 -.... 7 --... 8 ---.. 9 ----. 0 ----- REM FULL STOP [.] .-.-.- COLON [:] ---... REM COMMA [,] --..-- SEMICOLON [;] -.-.-. REM QUESTION MARK [?] ..--.. EQUAL SIGN double dash [=] -...- REM APOSTROPHE ['] .----. PLUS [+] .-.-. REM EXCLAMATION MARK [!] -.-.-- HYPHEN minus [-] -....- REM FWD SLASH [/] -..-. UNDERSCORE [_] ..--.- REM PARENTHESIS open [(] -.--. QUOTATION MARK ["] .-..-. REM PARENTHESIS closed [)] -.--.- DOLLAR SIGN [$] ...-..- REM AMPERSAND [&] .-... AT SIGN [@] .--.-. REM *** ENCODED CHARACTER NUMBERS *** REM LETTERS, NUMBERS AND PUNCTUATION USED TO PROGRAM YOUR MESSAGES IN THE REPEATER CONTROLLER REM A 6, B 17, C 21, D 9, E 2, F 20, REM G 11, H 16, I 4, J 30, K 13, L 18, REM M 7, N 5, O 15, P 22, Q 27, R 10, REM S 8, T 3, U 12, V 24, W 14, X 25, REM Y 29, Z 19, REM 1 62, 2 60, 3 56, 4 48, 5 32, REM 6 33, 7 35, 8 39, 9 47, 0 63, REM FULL STOP [.] 106 COLON [:] 71 REM COMMA [,] 115 SEMICOLON [;] 85 REM QUESTION MARK [?] 76 EQUAL SIGN double dash [=] 49 REM APOSTROPHE ['] 94 PLUS [+] 42 REM EXCLAMATION MARK [!] 117 HYPHEN minus [-] 97 REM FWD SLASH [/] 41 UNDERSCORE [_] 108 REM PARENTHESIS open [(] 45 QUOTATION MARK ["] 82 REM PARENTHESIS closed [)] 109 DOLLAR SIGN [$] 200 REM AMPERSAND [&] 34 AT SIGN [@] 86 REM THE NUMBER 255 IS NOT ACTUALLY AN ENCODED CHARACTER IN THIS PROGRAM, BUT IS RESERVED FOR REM E.O.M., "END OF MESSAGE" IN THE MORSE CODE ROUTINE.