Morse Code Radio Tower
'**************************************************************************************** 
'PICAXE-08 memory workout demo via Eric van de Weyer & Stan.SWAN Ver 1.02 27th June 2003 
'For Silicon Chip August 2003 PICAXE article. Author - Stan.SWAN => s.t.swan@massey.ac.nz 
'Ref. Edwin.C =>chick@chickene.freeserve.co.uk -June 2002 RSGB "RadComm" "28" version too 
'Program (derived from a Basic Stamp-1 idea ) sends short repeating Morse Code ID message  
'**************************************************************************************** 
'Almost unbelievably up to ~35 Morse characters can be stored in the tiny PICAXE-08 RAM ! 
'Output here just simple Piezo speaker at PICAXE Pin 0, but could be used to key a Tx etc 
'Only other component needed = 10k pull up R pin 3 to +ve rail to avoid "floating" 1/0 
'Note - although now near obsolete for messages,International Morse Code ( CW ) still has  
'wide use for beacons etc since decoding can be via eye or ear,& even unskilled observers  
'can thus "read" simple IDs & status at just a few (5?)words per minute.Of course sending 
'SOS via torch etc still suits emergencies! Scouting days now long past? Morse chs.are... 
' A o-o		B -ooo 		C -o-o 		D -oo 		E o 		F oo-o 
' G --o 	H oooo 		I oo 		J o--- 		K -o- 		L o-oo 
' M -- 		N -o 		O --- 		P o--o 		Q --o- 		R o-o 
' S ooo 	T - 		U oo- 		V ooo- 		W o-- 		X -oo- 
' Y -o-- 	Z --oo 		1 o---- 	2 oo--- 	3 ooo-- 	4 oooo- 
' 5 ooooo 	6 -oooo 	7 --ooo 	8 ---oo 	9 ----o 	0 ----- 
' Full stop o-o-o- 		Comma --oo-- 			Slash -oooo-  
' 
'By tradition 1 dah/dash = 3 dits/dots with letter space = 3 dits & word spacing 7 dits 
' 
'How DOES this work !?  
'Each character to be generated is programmed in as a number whose binary equivalent 
'then generates the code !  
'The 5 MSBs(Most Significant Bits =LHS)represent dots & dashes, with dit=0 & dah=1.  
'The last 3 LSB (Least Significant Bits = RHS) indicate how many elements in a character.  
'Hence V=00010100 (100 =4 elements). Bit 5 is meaningless here. 
'Converting to decimal yields 20.  
'Another ? K=10100011 = decimal 163 ( 011= 3 elements) 
'Here's is a list of these characters (abreviated as characters in comments)  
'& their equivilent number 
'**************************************************************************************** 

'A - 66 	B - 132 	C - 164 	D - 131 	E - 1 		F - 36  
'G - 195 	H - 4 		I - 2 		J - 116 	K - 163 	L - 68 
'M - 194 	N - 130 	O - 227 	P - 100 	Q - 212 	R - 67 
'S - 3 		T - 129 	U - 35 		V - 20 		W - 99 		X - 148 
'Y - 180 	Z - 196 	1 - 125 	2 - 61 		3 - 29 		4 - 13  
'5 - 5 		6 - 133 	7 - 197 	8 - 229 	9 - 245 	0 - 253 
'= - 141 	/ - 149 	. - 86 		, - 206 
' 
'"  W E  L  C   O   M  E -  T   O  - H E  R E  F  O   R  D  -  R  A I  L - -"  
'  99,1,68,164,227,194,1,0,129,227,0,4,1,67,1,36,227,67,131,0,67,66,2,68,0,0 (26) 

'" E  V E  N  I  N   G  -  A  T  - H E  R E  F  O   R  D  -  R  A I  L - -"  
'  1,20,1,130,2,130,195,0,66,129,0,4,1,67,1,36,227,67,131,0,67,66,2,68,0,0(26) 

'**************************************************************************************** 
'	Picaxe 08m - 233 bytes of 256 used - 8 June 06 
'**************************************************************************************** 

Symbol Character 	= b0 		'Set register for character. 
Symbol Index1 		= b1 		'Loaded with number of characters in message 
Symbol Index2 		= b2 		'Counts the number of elements 
Symbol Elements 	= b3 		'Set register for number of elements in ch. 
Symbol WhichLED 	= b4 		'Red or White LED to Light 
Symbol Loop		= b5		'Sleep Loop value 
Symbol Counter		= W3		'Night Counter 
Symbol DayPlus		= W4		'Light Variable +10 
Symbol Light 		= W5 		'ADC variable to see if sun is out! 
Symbol Voltage		= W6		'ADC variable for Battery Voltage 

'***** ADC Pin Assignments ***** 
Symbol Battery		= 1		'ADC Pin 
Symbol LLevel		= 4		'ADC Pin 

'***** Morse Code Vairables ***** 
'	 		5 WPM  	(Divide values by 2 to give 10WPM [7,21,42]) 
Symbol Dit_length	= 14 		'Set length of a dot (14 milliseconds) = 5WPM  
Symbol Dah_length 	= 42 		'Set length of a dash (42 mS = 3 dots long) 
Symbol Wrd_Length 	= 86 		'Set space between words (86 mS = 2 dashes or 6 dots) 

'***** Constants ***** 
Symbol Tone 		= 100 		'Sets the tone frequency ( range 20 - 127 ) 
Symbol Quiet 		= 0 		'Set quiet tone 
Symbol DayNight		= 450		'Day Night Threshold	 = 2.3V @ ADC input 
Symbol NightCount	= 300		'Times to repeat code after dusk 38sec * 300 = 3.1Hrs 
Symbol LowBatt  	= 820		'8 Volts 2x4K7 resistors = 4.0V @ ADC input 

'**************************************************************************************** 
'			Program Start 
'**************************************************************************************** 
	Counter = 0				'Set Counter to 0 
	DayPlus = DayNight + 10			'Set Variable 
Start:
	gosub Test				'Test for Voltage and light level 
	if Light > DayNight then Daytime 	'if over DayNight value it is day - use White LEDs 
	goto NightTime
'**************************************************************************************** 
'			Unpack Data to Send   
'**************************************************************************************** 
						'routine to lookup character & put its value into  
						'the character register cycle through lookup for 
						'times = number of characters in message	 
					
Nighttime:					'"EVENING-AT-HEREFORD-RAIL--"(26 characters) 
	WhichLED = 0              		'Output0 (pin 7) Red LEDs	 
	for Index1 = 0 to 25			'Number of Characters 
		lookup Index1,(1,20,1,130,2,130,195,0,66,129,0,4,1,67,1,36,227,67,131,0,67,66,2,68,0,0),Character
		gosub Morse 			'go to the character generation routine  
	next 					'loop back to get next character and load it 
	Counter = Counter + 1			'Increment counter 
	goto Start 				'return to start to wait for next input  
	
'****************************************************************************************	 

Daytime:					'"WELCOME-TO-HEREFORD-RAIL--"(26 characters) 
	Counter  = 0				'Reset Counter 
	WhichLED = 2              		'Output2 (pin 5) White LEDs 
	for Index1 = 0 to 25			'Number of Characters			 
		lookup Index1,(99,1,68,164,227,194,1,0,129,227,0,4,1,67,1,36,227,67,131,0,67,66,2,68,0,0),Character
		gosub Morse 			'go to the character generation routine  
	next 					'loop back to get next character and load it 
	goto Start 				'return to start to wait for next input  
		
	
'**************************************************************************************** 
'			Morse Code Generator 
'**************************************************************************************** 
	
Morse:
	let Elements = Character & %00000111'look at 3 LS digits and load into Elements register 
	if Elements = 0 then Word_Sp 		'         % means binary  
	
Bang_Key:
	for Index2 = 1 to Elements 		'loop through correct no. of times for number of elements 
		if Character >= 128 then Dah 	'test MS digit of ch. If it is 1 goto the Dah subroutine 
		goto Dit 			'if it is 0 goto the Dit sub routine  
ReEnter:
		let Character = Character * 2 	'do a left shift on all the bits in character. 
	next 					'loop back to get the next element 
	gosub Char_Sp 				'go to subroutine to put in inter-character space 
	return 					'return to to get next character to send  
'**************************************************************************************** 
'			Dit - Dah Generator 
'**************************************************************************************** 

Dit:
	sound WhichLED,(Tone,Dit_Length) 	'sound tone for dit length  
	sound WhichLED,(Quiet,Dit_Length) 	'silence for dit length 
	goto  ReEnter 				'return to look at next element of character.  
	
Dah:
	sound WhichLED,(Tone,Dah_Length) 	'sound tone for dah length  
	sound WhichLED,(Quiet,Dit_Length) 	'silence for dit length 
	goto  ReEnter 				'return to look at next element of character.  
	
Char_Sp:
	sound WhichLED,(Quiet,Dah_Length) 	'send silence  after character completely sent 
	return 					'return to get next character  
	
Word_Sp:
	sound WhichLED,(Quiet,Wrd_Length) 	'send silence for break between words 
	return 					'return to get next character. 
	
'**************************************************************************************** 
'	Test for Voltage and Daylight 
'**************************************************************************************** 
Test:
	readadc10 Battery, Voltage		'Read Battery Voltage 
	if Voltage < LowBatt then LowVoltage  	'Is Battery discharged 
	readadc10 LLevel, Light			'Read light level		 
	if Counter > NightCount	then ChckLight 	'Test for Night Timeout 
	return
'****************************************************************************************	 
ChckLight:					'Check for Day 
	if Light < DayPlus then Wait4Morning	'Is it Day 
	return					'Yes - Return to Start 
'**************************************************************************************** 
LowVoltage:					'Battery Low - Time to charge 
	gosub TimeDelay				'Sleep for 30 seconds 
	goto Test				'Test again 
'**************************************************************************************** 
TimeDelay:					'Low Power sleep mode 
	low 0					'Turn off leds 
	low 1					'Turn off leds 
	for Loop = 0 to 12			'Do 13 Times 
		nap 7				'Sleep for 2.3 Seconds 
	next Loop				'Sleep for 30 secs 2.3 * 13 = 29.9Sec 
	return					'Return From Delay 
'**************************************************************************************** 
Wait4Morning:					'Ran for Timeout period. Sleep until morning 
	gosub TimeDelay				'Sleep for 30 seconds 
	readadc10 LLevel, Light 		'Read light level 
	if Light < DayPlus then Wait4Morning	'Is it Day 
	Counter = 0				'Reset Counter 
	return					'Return to Start 
'****************************************************************************************