' SYNC2.BAS PIC16F628 Freakin' Beacon Project ' PicBasic Pro Compiler ' William Coleman Consulting ' ' 03/30/05 SYNC1: Created GPS synchronized version of FB1 and FB2. ' Syncin' Beacon SB1/SB2. ' Stripped out long delays and QRSS modes to free up code space ' (Commented out). Deleted seldom used characters AR, AS, KN, SK. ' 04/02/05 Changed message point limit from 127 to 99 to free bytes for GPS ' time slots: 1 byte for each 5-second slot. Shortened prompts, ' deleted CW "Y?" and "OK" when changing message. ' *** If someone needs more FB1/FB2 functions AND GPS trigger, let them use ' *** Key or PTT output from SB1/SB2 board to trigger FB1/FB2 board. ' *** Having any beacon functions in GPS triggered board is a bonus. ' Deleted comma, question mark, and BT. Deleted "A" 5 WPM, "E" 52 WPM. ' Deleted "F" 5 sec delay. Deleted trigger input. ' Deleted period, @ characters. ' 04/08/05 Simplified odd/even minute check. Found major bug! Variable "Pointer" ' was being corrupted in NMEA sentence parsing routine. Changed to "Y." ' Beacon sync now works with Magellan or Axiom GPS, even with all ' NMEA sentences turned on. ' 04/09/05 Removed some test code. Changed default message to "WvvvZ" to require ' GPS trigger at 0 or 60 seconds (even minute 0 sec or odd minute 0 sec). ' 04/13/05 Created SYNC2.PJT and SYNC2.BAS. Changed default message to "vvvWZ" so ' that message will play once for testing purposes before pausing to Wait ' for a GPS trigger. ' Configure PORTA as Digital Inputs, not Analog Inputs CMCON = 7 ' Configure RA0 & RA1 as Outputs ' Configure RA2-RA4 as Inputs TRISA = %00011100 ' Configure RB0-RB7 as Outputs TRISB = %00000000 ' Assign names to pins program var PORTA.3 ' Ground to enter program mode Serial_in var PORTA.4 ' Serial input for programming PTT var PORTB.0 ' PTT output, active high Key var PORTB.1 ' Key output, active high Serial_out var PORTB.2 ' Serial output for programming Sidetone var PORTB.3 ' Sidetone output EL_pwr var PORTB.4 ' Extra low power, active high Low_pwr var PORTB.5 ' Low power, active high Med_pwr var PORTB.6 ' Medium power, active high High_pwr var PORTB.7 ' High power, active high ' Initialize variables to default states element var byte ' Back to byte. Was word for QRSS. element = 60 ' element time = 60 ms (20.8 WPM) dittime var byte dittime = 5 ' dittime = 60 ms (20.8 WPM) dahtime var byte dahtime = 15 ' dahtime = 180 ms (20.8 WPM) pointer var byte command var byte verify var byte newchar var byte Keyflag var byte X var byte Y var byte GPSmin var byte GPSsec var byte slotseconds var byte ' Initialize EEPROM with "vvv" test message. Wait for GPS trigger. ' Set GPS time slots 00 secs for even & odd minutes. Data "v","v","v","W","Z" Data @100,1,0(11),1,0(11) Start: if program = 1 then goto main serout serial_out,6,[13,10] pointer=0 ' *** Show message on screen. *** loopecho: Read pointer, command serout serial_out,6,[command] pointer = pointer + 1 if pointer = 99 then goto doneecho if command = "Z" then goto doneecho goto loopecho doneecho: serout serial_out,6,[13,10,"Chg msg? y/n",13,10] serin serial_in,6,10000,Main,verify if verify <> "y" then goto GPSslots serout serial_out,6,[13,10,"Ent msg then Z",13,10] pointer = 0 prog: serin serial_in,6,newchar write pointer,newchar serout serial_out,6,[newchar] if newchar = "Z" then goto doneecho pointer = pointer + 1 if pointer = 99 then goto loopecho goto prog ' *** Show GPS time slots on screen. *** GPSslots: serout serial_out,6,[13,10] serout serial_out,6,[13,10," Even Odd",13,10] For pointer=100 to 111 slotseconds=5*(pointer-100) read pointer, X read pointer+12, Y serout serial_out,6,[#slotseconds," sec ",#X," ",#Y,13,10] Next pointer serout serial_out,6,[13,10] serout serial_out,6,[13,10,"Chg GPS? y/n",13,10] serin serial_in,6,verify if verify != "y" then goto main serout serial_out,6,[13,10,"5 sec slots, 0-55 if even mins, 60-115 if odd mins",13,10] serout serial_out,6,[13,10,"set/clr? s/c",13,10] serin serial_in,6,verify serout serial_out,6,[13,10,"sec?",13,10] if verify = "s" then goto Setslot if verify = "c" then goto Clrslot goto GPSslots Setslot: ' 5 second time slots stored in locations 100-123 serin serial_in,6,#slotseconds slotseconds=slotseconds & 127 X=slotseconds//5 If X<>0 then goto GPSslots pointer=slotseconds/5 pointer=pointer+100 X=1 Write pointer, X goto GPSslots Clrslot: ' 5 second time slots stored in locations 100-123 serin serial_in,6,#slotseconds slotseconds=slotseconds & 127 X=slotseconds//5 If X<>0 then goto GPSslots pointer=slotseconds/5 pointer=pointer+100 X=0 Write pointer, X goto GPSslots ' Main loop Main: serout serial_out,6,[13,10,"run..."] gosub HighP ' High power is default gosub Keyup ' Ensure unkeyed, key flag cleared pointer = 0 Loop: Read pointer, command if command = "a" then gosub send_a if command = "b" then gosub send_b if command = "c" then gosub send_c if command = "d" then gosub send_d if command = "e" then gosub send_e if command = "f" then gosub send_f if command = "g" then gosub send_g if command = "h" then gosub send_h if command = "i" then gosub send_i if command = "j" then gosub send_j if command = "k" then gosub send_k if command = "l" then gosub send_l if command = "m" then gosub send_m if command = "n" then gosub send_n if command = "o" then gosub send_o if command = "p" then gosub send_p if command = "q" then gosub send_q if command = "r" then gosub send_r if command = "s" then gosub send_s if command = "t" then gosub send_t if command = "u" then gosub send_u if command = "v" then gosub send_v if command = "w" then gosub send_w if command = "x" then gosub send_x if command = "y" then gosub send_y if command = "z" then gosub send_z if command = "1" then gosub send_1 if command = "2" then gosub send_2 if command = "3" then gosub send_3 if command = "4" then gosub send_4 if command = "5" then gosub send_5 if command = "6" then gosub send_6 if command = "7" then gosub send_7 if command = "8" then gosub send_8 if command = "9" then gosub send_9 if command = "0" then gosub send_0 if command = " " then gosub space if command = "/" then gosub slash if command = "B" then gosub WPM10 if command = "C" then gosub WPM15 if command = "D" then gosub WPM21 if command = "H" then gosub HighP if command = "K" then gosub Keydown if command = "L" then gosub LowP if command = "M" then gosub MediumP if command = "P" then gosub PTTon if command = "Q" then gosub PTToff if command = "S" then gosub Second if command = "T" then gosub Tenth if command = "U" then gosub Keyup if command = "W" then gosub WaitTrig if command = "X" then gosub ExtraP if command = "Z" then goto main pointer = pointer + 1 if pointer = 99 then goto main Goto Loop send_a: gosub dit gosub dah pause element pause element return send_b: gosub dah gosub dit gosub dit gosub dit pause element pause element return send_c: gosub dah gosub dit gosub dah gosub dit pause element pause element return send_d: gosub dah gosub dit gosub dit pause element pause element return send_e: gosub dit pause element pause element return send_f: gosub dit gosub dit gosub dah gosub dit pause element pause element return send_g: gosub dah gosub dah gosub dit pause element pause element return send_h: gosub dit gosub dit gosub dit gosub dit pause element pause element return send_i: gosub dit gosub dit pause element pause element return send_j: gosub dit gosub dah gosub dah gosub dah pause element pause element return send_k: gosub dah gosub dit gosub dah pause element pause element return send_l: gosub dit gosub dah gosub dit gosub dit pause element pause element return send_m: gosub dah gosub dah pause element pause element return send_n: gosub dah gosub dit pause element pause element return send_o: gosub dah gosub dah gosub dah pause element pause element return send_p: gosub dit gosub dah gosub dah gosub dit pause element pause element return send_q: gosub dah gosub dah gosub dit gosub dah pause element pause element return send_r: gosub dit gosub dah gosub dit pause element pause element return send_s: gosub dit gosub dit gosub dit pause element pause element return send_t: gosub dah pause element pause element return send_u: gosub dit gosub dit gosub dah pause element pause element return send_v: gosub dit gosub dit gosub dit gosub dah pause element pause element return send_w: gosub dit gosub dah gosub dah pause element pause element return send_x: gosub dah gosub dit gosub dit gosub dah pause element pause element return send_y: gosub dah gosub dit gosub dah gosub dah pause element pause element return send_z: gosub dah gosub dah gosub dit gosub dit pause element pause element return send_1: gosub dit gosub dah gosub dah gosub dah gosub dah pause element pause element return send_2: gosub dit gosub dit gosub dah gosub dah gosub dah pause element pause element return send_3: gosub dit gosub dit gosub dit gosub dah gosub dah pause element pause element return send_4: gosub dit gosub dit gosub dit gosub dit gosub dah pause element pause element return send_5: gosub dit gosub dit gosub dit gosub dit gosub dit pause element pause element return send_6: gosub dah gosub dit gosub dit gosub dit gosub dit pause element pause element return send_7: gosub dah gosub dah gosub dit gosub dit gosub dit pause element pause element return send_8: gosub dah gosub dah gosub dah gosub dit gosub dit pause element pause element return send_9: gosub dah gosub dah gosub dah gosub dah gosub dit pause element pause element return send_0: gosub dah gosub dah gosub dah gosub dah gosub dah pause element pause element return slash: gosub dah gosub dit gosub dit gosub dah gosub dit pause element pause element return Dit: Key = 1 sound sidetone,[110,dittime] Key = 0 pause element Return Dah: Key = 1 sound sidetone,[110,dahtime] Key = 0 pause element Return Space: pause element pause element pause element Return WPM10: element = 120 ' B dittime = 10 dahtime = 30 return WPM15: element = 84 ' C dittime = 7 dahtime = 21 return WPM21: element = 60 ' D dittime = 5 dahtime = 15 return HighP: High_pwr = 1 ' H Med_pwr = 0 Low_pwr = 0 EL_pwr = 0 return MediumP: High_pwr = 0 ' M Med_pwr = 1 Low_pwr = 0 EL_pwr = 0 return LowP: High_pwr = 0 ' L Med_pwr = 0 Low_pwr = 1 EL_pwr = 0 return ExtraP: High_pwr = 0 ' X Med_pwr = 0 Low_pwr = 0 EL_pwr = 1 return WaitTrig: ' W Wait for GPS trigger. ' Read GPS NMEA sentence ' serin2 required for 4800b ' serin2 mode determination: ' bit 15 not used ' bit 14 inverted=1, value = 2^14 = 16384 ' bit 13 no parity=0 ' bits 12-0 = (1000000/4800b)-20 = 188 ' serin2 mode = 16384+188=16572 ' ' Use serial_in pin, set 4800b no RS-232 drivers, wait for "RMC," in ' NMEA sentence, discard 2 hour digits, get 2 minute digits and ' 2 second digits. serin2 serial_in,16572,[wait("RMC,"),skip 2,dec2 GPSmin,dec2 GPSsec] if GPSmin.0 == 0 then Skipadd ' If GPSmin is odd add 60 to GPSsec GPSsec=GPSsec+60 Skipadd: X=GPSsec//5 if X <> 0 then goto Minusone Y=GPSsec/5 Y=Y+100 Read Y, X If X<>0 then goto Slotmatch ' Repeat test for GPSsec-1 in case GPS outputs ' only even seconds. Minusone: GPSsec=GPSsec-1 X=GPSsec//5 if X <> 0 then goto WaitTrig Y=GPSsec/5 Y=Y+100 Read Y, X If X<>0 then goto Slotmatch goto WaitTrig Slotmatch: return Keydown: Key = 1 ' K Keyflag = 1 ' used to enable SOUND during T, S, & F Return Keyup: Key = 0 ' U Keyflag = 0 ' used to disable SOUND during T, S, & F Return Second: if Keyflag = 1 then sound sidetone, [110,83] ' keyed so sidetone for 83*12ms = 996ms else pause 1000 ' S Hold 1 second endif Return Tenth: if Keyflag = 1 then sound sidetone, [110,8] ' keyed so sidetone for 8*12ms = 96ms else pause 100 ' T Hold 0.1 seconds endif Return PTTon: PTT = 1 ' P Return PTToff: PTT = 0 ' Q Return END