Train in the Garden.Bas
'************************************************************************************ 
'Originally written by Dave Bodnar 13 April 2004 "http://davebodnar.com" 
'Modified to suit my situation September/October 2004 
'Speeds up and slows motor. Slows and or stops on input 7 - Reverses on input 6 
'Version 1.0 - First run on Picaxe 18X 
'Version 1.2 - Added Stop on 2nd detection of input 7 high  
'Using 564 of 2048 bytes - Removed LCDmessages as causing PWM problems 
'************************************************************************************ 
'Outputs 
symbol	SLCD		=	0		'output 0 - Serial data to LCD module 
symbol	HBridgeD1	=	1		'output 1 - H-Bridge Fwd dir pin 7 
symbol 	HBridgeD2	=	2		'output 2 - H-Bridge Rev dir pin 8  
symbol 	pulse		=	3		'output 3 - H-Bridge pin pwm pin 9 
symbol	Horn		=	4		'output 4 - Horn trigger on pin 10 
symbol	RevLt		=	5		'output 5 - Reverse Lights on pin 11 
symbol 	FwdLt		=	6		'output 6 - Forward Lights on pin 12 
symbol 	CabLt		=	7		'output 7 - Cabin   Lights on pin 13 
'************************************************************************************ 
'Inputs		 
symbol	AC		=	pin0		'input pin for ADC 0 - Acceleration 
symbol	ST		=	pin1		'input pin for ADC 1 - Station  Wait 
symbol	TS		=	pin2		'input pin for ADC 2 - Top Speed 
symbol	OutMag		=	pin6		'input pin for Outside magnet 
symbol	CtrMag		=	pin7		'input pin for Centre magnet 
'************************************************************************************ 
'Constants 
symbol	period		=	124		'constant for PWM period 
symbol	lowend		=	300		'low speed value 
symbol	dstp		=	6		'step value for slowdown loop 
symbol	astp		=	4		'step value for speedup loop 
'************************************************************************************ 
'Registers	 
symbol	fwd_rev		=	b0		'Forward = 0 Reverse = 1  
symbol	mess_no		=	b1		'LCD message number variable 
symbol 	stoptime	=	b2		'pot value for station pause time 
symbol 	stationstop	=	b3		'pot value /4 station pause time 
symbol	accloop		=	w3		'variable for speedup/slowdown loop 
symbol 	top		=	w4		'top speed value (0 to 1023) 
symbol	temp		=	b10		'temporary variable 
symbol	accpot		=	b11		'how long to pause (acc/dec delay) 

'************************************************************************************ 
START:						'Start main program here. 
	pause 1000				'time for LCD to initilize. 
'	serout SLCD, N2400,(254,1)		'clear display on LCD 
'	serout SLCD, N2400,(254,192,"Initializing  ")'initialize message on LCD 
	low HBridgeD1:low HBridgeD2		'initialize H bridge direction 
	fwd_rev=0				'start direction flag 
	low FwdLt:low RevLt:low CabLt		'lights off 
'	gosub SETMESSAGES			'save messages to LCD 
	pause 10				'wait 10mS to update display 
'	mess_no=6:gosub LCDDATA			'request station message on LCD 
	high FwdLt				'turn on forward headlight 
	high CabLt				'Turn on cabin lights 
 	gosub BEEP				'trigger the horn 
	high HBridgeD1:low HBridgeD2		'start out Fwd H bridge direction 
'	mess_no=2:gosub LCDDATA			'request forward message on LCD 

'************************************************************************************ 
'			Main loop begins here 
'************************************************************************************ 
SPEEDUP:					'accelerate motor to full speed 
	gosub READPOTS:				'read setting from potentiometers 
	setint %00000000,%00000000		'disable interrupt until decellerating 
'	mess_no=3:gosub LCDDATA			'request "Accelerating" message on LCD 
	for accloop=lowend to top step astp	'accelerate loop start 
	   pwmout pulse, period, accloop	'send pulses 
	   pause accpot				'pause for acceleration delay 
	next accloop				'loop 
	low CabLt				'Turn off cabin lights 
'	mess_no=1:gosub LCDDATA			'request "Full Speed" message on LCD 
	pwmout pulse, period, top		'send full speed pulses 
'************************************************************************************ 
MAINTAIN_SPEED:					'keep steady speed routine 
	if CtrMag = 1 then SLOWDOWN		'if we see a magnet then exit loop 
	goto MAINTAIN_SPEED:			'loop  
'************************************************************************************ 
SLOWDOWN:
'	mess_no=5:gosub LCDDATA			'request "Slowing" message on LCD 
	setint %01000000,%01000000		'int for input6 (Outer Magnet) hi 
	high CabLt				'turn on cabin lights 
	for accloop=top to lowend step -dstp 	'decelerate loop start 
	   pwmout pulse, period, accloop	'send pwm pulses output 3 
	   pause accpot				'pause for deceleration delay 
	next accloop				'loop 
'	mess_no=7:gosub LCDDATA			'request "Stopped" message on LCD 
'************************************************************************************ 
STATIONWAIT:					'wait at station until time out 
	pwmout pulse, period, 0	 		'stop pulses  
	low HBridgeD1:low HBridgeD2		'stop motor  
	low FwdLt :low RevLt			'headlights off 
'	mess_no=6:gosub LCDDATA			'request "Station Wait" message on LCD 
	for temp= stationstop to 0 step -1 	'loop for station delay 
'	   serout SLCD,N2400,(254,206,#b10," ")  '2nd row 14th chr, countdown to 0  
	   pause 1000				'pause 1 second 
	next temp				'loop 
'************************************************************************************ 
WHICHWAY:
	if fwd_rev =1 then GOREVERSE		'which way?	1=Reverse 0=Forward	 
GOFORWARD:
	high HBridgeD1:low HBridgeD2		'forward 
	high FwdLt				'turn on forward headlight 
'	mess_no=2				'"Forward" message 
	goto GETREADY:				'jump over reverse 
GOREVERSE:
	high HBridgeD2:low HBridgeD1		'reverse 
	high RevLt				'turn on reverse headlight 
'	mess_no=4				'"Reverse" message  
GETREADY:
	gosub LCDDATA				'request Fwd/Rev message on LCD 
	pause 1000				'pause 1 second 
	gosub BEEP				'trigger the horn 
	goto SPEEDUP:				'start over again! 
'************************************************************************************ 
'			Subroutines 
'************************************************************************************ 
INTERRUPT:					'jumps here if pin6 goes high 
	if CtrMag = 1 then STOPNOW		'check to see if pin7 trigered IRQ 
	if fwd_rev = 0 then REV			'if FWD need to go Reverse 
	fwd_rev = 0				'change flag to Forward 
	goto INT_ON				'jump over Reverse 
REV:
	fwd_rev = 1				'change flag to Reverse 
	goto INT_ON				'jump over stop 
STOPNOW:
	accloop = lowend			'loop counter to lowend, stop now. 
INT_ON:
	pause 100				'pause for 100mS so dont trigger again 
	setint %01000000,%01000000		'enable int on input6 (Outer Magnet) 
return						'back to when magnet detected 
'************************************************************************************ 
BEEP:						'routine to operate a relay or opto 
	high Horn				'trigger the horn 
	pause 250				'pause for 250 mS 
	low Horn				'turn off 
	pause 1000				'pause for 1 second 
return						'back 
'************************************************************************************ 
READPOTS:					'start of read pot subroutine 
	readadc AC,accpot			'get accelerate / decelerate pot 
	readadc ST,stoptime			'get pot reading for stop time 
	stationstop=stoptime/10			'0 to 255/10 = 0 to 25 seconds 
	readadc10 TS,top			'get top speed pot value  
return						'return to place where gosub was called 
'************************************************************************************ 
FLASHLTS:					'takes 1000mS to execute 
	high FwdLt				'turn on Forward headlight 
	pause 400				'wait 400 mS 
	low FwdLt				'turn off Forward headlight 
	pause 600				'wait 600 mS 
return						'back 
'************************************************************************************ 
LCDDATA:
	serout SLCD,N2400,(mess_no)		'display the saved message on LCD 
return
'************************************************************************************ 
SETMESSAGES:					'flash lights to give appropriate delay 
	serout SLCD, N2400,(253,1,"Full Speed      "):gosub FLASHLTS 'Upper Mess 1 
	serout SLCD, N2400,(253,2,"Forward         "):gosub FLASHLTS 'Lower Mess 2 
	serout SLCD, N2400,(253,3,"Accelerating    "):gosub FLASHLTS 'Upper Mess 3 
	serout SLCD, N2400,(253,4,"Reverse         "):gosub FLASHLTS 'Lower Mess 4 
	serout SLCD, N2400,(253,5,"Slowing         "):gosub FLASHLTS 'Upper Mess 5 
	serout SLCD, N2400,(253,6,"Station Wait    "):gosub FLASHLTS 'Lower Mess 6 
	serout SLCD, N2400,(253,7,"Stopped         "):gosub FLASHLTS 'Upper Mess 7 
return
'************************************************************************************