davidbuckley.net
home  >  Bambino  >  Programs 1 to 16  |  Programs 17 to 21  |  Programs 22 - 28 14 January 2012

Bambino Programming 22 - 28 by David Buckley

Developer Programming instructions


[page top]

'Bambino-22
Sertxd("B22",cr)		'report program number @4800

#PicAxe 20M2
#no_data
'PICAXE            IC   Memory   ext  I/O   Outputs  Inputs  ADC  Memory                        Starts  Polled  Resonator
' £   Type        pins  bytes    slot pins                        Vars. RAM Spad Data     Table*        Int.    def. opt. 
'2.28 PICAXE-20M2  20    2k           18    1-16     1-17     4    28   512      256      512   8       Yes      4   -32

'PICAXE-20M2 circuit board with LEDs off takes 1mA
'PICAXE-20M2 circuit board with LEDs off and servos connected takes 10mA


'Bambino-01	'Test eyeLEDs, whiskerLEDs and speaker
'Bambino-02	'Test InfraRed input
'Bambino-02a	'Test Eye light values
'Bambino-02b	'Test Whisker light values
'Bambino-03	'Play the inbuilt tunes using keys 1 to 4 and beep on 5
'Bambino-04	'Set servos to mid position	
'Bambino-05	'Calibrate servo mid positions and put values in EEPROM.
'Bambino-06	'Introduce _iStand:- initialise with feet in mid position
'Bambino-07	'Set rollR
'Bambino-08	'Set rollL
'Bambino-09	'Check rollR, rollL
'Bambino-10	'Introduction of _Stand
'Bambino-11	'Investigate effect of rollspeed;	watch roll for all three speeds
'Bambino-12	'Investigate effect of rollspeed;	watch Roll and Stand for all three speeds
'Bambino-13	'Check paceFL paceFR;	Investigate effect of pacespeed
'Bambino-14	'Check Fd
'Bambino-15	'Test Rt, Lt
'Bambino-15a	'Test T2L Turn to Light, T2D Turn to Dark
'Bambino-16	'Test Bk
'Bambino-17	'Creaton of sections ACTIONS, BEHAVIOURS, ACTS;
            	'Introduction of ACT parameter 'Ado'
'Bambino-17a 'Demo routine            	
'Bambino-18	'Walk Fd with obstacle avoidance using eyes from 02a
'Bambino-18a	'Walk Fd with drop-off avoidance using whiskers values from 02b
'Bambino-18b	'rewritten with autocalibration of down whiskers and reading of whiskers as subroutines
'Bambino-19	'If IR command then do it otherwise walk and avoid
'Bambino-20	'rewrite to incorporate rollC and paceC in EEPROM 254,255
'Bambino-21	'rewrite to clearer code
'Bambino-22 	'remember a sequence of key presses          
            	
'-----------------------------------------------------------------            	
'modified
'--------

'New
'---
'be able to record some moves and replay them using Key [1]
'Press [|] to start recording
'Press [POWER] or [1] to end recording
'Press [1] to play recording
'RockAdo is moved to key [2]	it can be included in remembered moves.
'symbol nokey		=255
'=================================================================
'TVR010 PicAxe IR-controller
'---------------------------
'Before use, the transmitter must be programmed with the ‘Sony’ transmit code.
'1. Insert 2 AAA size batteries, preferably alkaline.
'2. Press ‘S’ and ‘B’ at the same time. S is in the centre of the arrows. 
'	The top left red LED should light.
'3. Press ‘0’. The LED should flash.
'4. Press ‘1’. The LED should flash.
'5. Press ‘3’. The LED should go out.
'6. Press the red power button (top right).
'-------------------------------------------
'IRin cmnds PicAxe controller
'DO NOT PRESS OTHER KEYS 
'ie [A] [B] [C] [D] [E] [F] [G] 
'They change the Mode and [B] has to be pressed to change back.
'[square] [triangle [()] [L] [X] [backwards F]  have no effect

Symbol KEY_POWER  = 21		'Sleep

Symbol KEY_UP     = 16		'Step Forward
Symbol KEY_DOWN   = 17		'Step Backward
Symbol KEY_RIGHT  = 18		'Turn Right
Symbol KEY_LEFT   = 19		'Turn Left

Symbol KEY_BAR    = 96
Symbol KEY_TENT   = 54
Symbol KEY_VERT_CROSS = 37
Symbol KEY_VCROSS = 37		'synonym for easier coding
Symbol KEY_DIAG_CROSS = 20
Symbol KEY_XCROSS = 20		'synonym for easier coding
symbol IRkey1     =  0
symbol IRkey2     =  1
symbol IRkey3     =  2
symbol IRkey4     =  3
symbol IRkey5     =  4
symbol IRkey6     =  5
symbol IRkey7     =  6
symbol IRkey8     =  7
symbol IRkey9     =  8
Symbol KEY_MINUS  = 98
Symbol KEY_0      =  9		'Quit command mode
Symbol KEY_PLUS   = 11
'=================================================================
symbol servopace    =c.0	'left connector
symbol servoroll    =c.4	'right connector
symbol VoiceLed_    =c.5      'low =>LED on 
symbol eyeLedL_     =c.2      'low =>LED on 
symbol eyeLedR_     =b.1      'low =>LED on
symbol whiskerLedL_ =c.3    'low =>whisker LED on
symbol whiskerLedR_ =b.3    'low =>whisker LED on
symbol eyeR         =c.7		  	
symbol eyeL         =c.1		  	
symbol iIRin        =c.6
symbol oIRout       =b.2

'symbol general 	=b0
symbol flags	=w1
symbol B_flags     =b3
'symbol f_doIRcmnds  =bit29
symbol f_play	  =bit28	
symbol f_record	  =bit29
symbol f_direction  =bit30	'1=forwards, 0=backwards    
symbol f_defaultB   =bit31	'defaultBehaviour 1=use default
symbol servosAt	=w2
symbol  rollat 	 =b4
symbol  paceat 	 =b5
symbol ServosTo	=w3
symbol  rollTo	 =b6	   
symbol  paceTo	 =b7
symbol Smoveby	=w4
symbol  rollby	 =b8
symbol  paceby     =b9
symbol Scentre	=w5
symbol  rollC	 =b10
symbol  paceC      =b11
symbol Sspeed     =w6
symbol  rollspeed  =b12  '4 is too fast, 0 won't move
symbol  pacespeed  =b13  '6 is about max for servos to keep up
symbol counters	=w7
symbol  spulse 	 =b14
symbol  iA 		 =b15
symbol temp       =w8
symbol  tempL      =b16
'symbol tempH      =b17

	
symbol sframe   =22	'time between servo pulses
symbol Ado			=b18	'parameter for ACTs
symbol obstacle =b19  '%11 bitmap of obstacles  %LeftRight
symbol lightL   =b20  'light level Left
symbol lightR   =b21  'light level Right
symbol IRcmnd   =b22  'cmnd from IRremote
symbol nokey    =255

'symbol cmnd		=b23  'Action to be done

'=================================================================
initialise:
	rollby    =15	'+ve right 
	paceby    =20	'+ve Left  foot forward
	rollspeed =1  	'4 is too fast, 0 won't move
	pacespeed =2   	'6 is about max for servos to keep up  
	rollC	    =150	'Default, 100 is roll to the left
	paceC	    =150	'Default, 100 is left foot back
	read 254,temp	'set in prog5
	if temp>130 and temp<170 then	'so servo is always between 100,200
	  rollC =temp
	 endif 
	read 255,temp	'set in prog5
	if temp>130 and temp<170 then	'so servo is always between 100,200
	  paceC =temp
	 endif 
	sertxd("rollC=",#rollC," paceC=",#paceC,cr)
	low eyeLedR_	'make output LED on
	low eyeLedL_	'make output LED on
	gosub _iStand
	f_defaultB =1	'defaultBehaviour On
	f_record =0
	bptr =32
	poke bptr,0		'no recording

start:
sertxd("S")
	Ado =4				'for RockAdo
	irin [50,Walkabout],iIRin,IRcmnd	'irin with timeout, no IR =>Walkabout
	gosub beep50                  'so we know IR received
	goto IRacty
'=================================================================
'Activities
'----------
IRacty:
	sertxd("IR")
DoIRcmnd:	
	sertxd(#IRcmnd)
	sertxd("f_play",#f_play,"f_rec",#f_record)
	sertxd("@",#bptr,"=",#IRcmnd)		
	select IRcmnd
	  case KEY_POWER
	  	if f_record=1 then
	  		f_record =0
		   	@bptr =0	      	'end marker
		  else 
	  		gosub rest
			gosub EyesON
			goto DoIRcmnd		'have already got IRcmnd in rest:
		  endif
	  case KEY_UP
		if f_record=1 then
			  @bptrinc =IRcmnd
		  endif
	  	gosub Fd
	  case KEY_DOWN
		if f_record=1 then
			@bptrinc =IRcmnd
		  endif
	  	gosub Bk
	  case KEY_RIGHT
		if f_record=1 then
			@bptrinc =IRcmnd
		  endif
	  	gosub Rt
	  case KEY_LEFT
  		if f_record=1 then
	  		@bptrinc =IRcmnd
  		  endif
	  	gosub Lt
	  case IRkey1
	  	f_play =1			'play
	  	bptr =32 			'set to start
	  	sertxd("bptr",#bptr)	 
	  case IRkey2
		if f_record=1 then
			@bptrinc =IRcmnd
		  endif
	  	gosub RockAdo
	  case KEY_0
		goto Start			'QUIT
	  case KEY_BAR	
	  	f_record =1
	  	f_play =0	
	  	bptr =32 			'set to start
	 end select

	if f_play=1 then
		f_record =0 
 		IRcmnd =@bptrinc		'read remembered command
		if IRcmnd=0 then		'0=end
			f_play =0
			IRcmnd =nokey	'no move
		  endif 
		goto	DoIRcmnd				
	  endif
	
GetIR:
	if f_record=1 then
  		low VoiceLed_		'turn on mouth while waiting
	  else  
  		high VoiceLed_		'turn off mouth while waiting
	  endif		
	irin iIRin,IRcmnd 		'Get IRcmnd
	gosub beep50          		'so we know IR received
	goto DoIRcmnd			'Do code


'-----------------------------------------	
Walkabout:
sertxd("W")
	obstacle =0
	gosub EyesOFF
EwhiskerR:
	readadc c.7,lightR
	low eyeLedR_			'eyeR on
	readadc c.7,tempL
	high  eyeLedR_			'eyeR off
	if lightR>tempL then		'why this happens I don't know
		tempL =lightR				
	  endif	
	tempL =tempL -lightR
	if tempL<2 then EwhiskerL	'ignore
	obstacle =obstacle or 1 
	
EwhiskerL:
	readadc c.1,lightL
	low eyeLedL_			'eyeL on
	readadc c.1,tempL
	high  eyeLedL_			'eyeL off
	if lightL>tempL then		'why this happens I don't know
		tempL =lightL				
	  endif	
	tempL =tempL -lightL
	if tempL<5 then Walk		'ignore
	obstacle =obstacle or %10 

Walk:	
	gosub B_fast
	b0 =obstacle 			'to use bits
	if bit0=0 then
		low eyeLedR_
	  endif 
	if bit1=0 then
		low eyeLedL_
	  endif 
	on obstacle gosub Fd,Lt,Rt,Bk 
	irin [50,Walkabout],iIRin,IRcmnd	'irin with timeout, no IR =>Walkabout
	goto start                    'QUIT if IRin
'=================================================================
'Behaviours
'----------
B_fast:
	rollspeed =3
	pacespeed =6
	return
	
B_turn:	
	rollspeed =1	'slow so foot doesn't bounce
	pacespeed =5 
	return	
'=================================================================
'Program Acts
'------------

RockAdo:
	if f_defaultB=1 then gosub B_fast
	for iA=1 to Ado  
 		gosub _rollR
		gosub _rollL
	  next iA 
	gosub Stand 
	return
	
FdAdo:
	for iA=1 to Ado 
		gosub Fd
	  next iA 
	return
	
BkAdo:
	for iA=1 to Ado 
		gosub Bk
	  next iA 
	return

Rest:
	gosub _rollL
	gosub _iStand
	pwmout eyeLedR_,100,400 'active low so high Dutycycle for dim
	pwmout eyeLedL_,100,400 'active low so high Dutycycle for dim
_RestIRwait:
	high VoiceLed_
	irin iIRin,IRcmnd			'irin with no timeout
	gosub beep50            		'so we know IR received
	if IRcmnd=KEY_POWER then _RestIRwait	'wait until different IRcmnd
	pwmout eyeLedR_,off	
	pwmout eyeLedL_,off
	return
	
'=================================================================
'Actions
'-------

Fd:
sertxd ("Fd")
	f_direction =1
	if f_defaultB=1 then gosub B_fast
	if paceat<paceC then _FdL 'else _FdR
_FdR:
'sertxd ("_FdR")
	gosub _rollL
	gosub _RF
	gosub Stand
	return
_FdL:
'sertxd ("_FdL")
	gosub _rollR
	gosub _LF
	gosub Stand
	return
'-----------------------------------------
Bk:
sertxd ("Bk")
	f_direction =0
	if f_defaultB=1 then gosub B_fast
	if paceat<paceC then _BkR 'else _BkL
_BkL:
	gosub _rollR
	gosub _RF
	gosub Stand
	return
_BkR:
	gosub _rollL
	gosub _LF
	gosub Stand
	return
'-----------------------------------------
Rt:
sertxd ("Rt")
	if paceat<paceC and f_direction=1 then gosub Fd	'need left foot forward
	if paceat<paceC and f_direction=0 then gosub Bk	'need left foot forward
	if f_defaultB=1 then gosub beep150
	if f_defaultB=1 then gosub B_turn
	gosub _RF
	return
'-----------------------------------------
Lt:
sertxd ("Lt")
	if paceat>paceC and f_direction=1 then gosub Fd	'need right foot forward
	if paceat&lgt;paceC and f_direction=0 then gosub Bk	'need right foot forward
	if f_defaultB=1 then gosub beep150
	if f_defaultB=1 then gosub B_turn
	gosub _LF
	return
'=================================================================
_RF:
'sertxd ("_RF")
	paceto =paceC -paceby
	for spulse=paceat to paceto step -pacespeed
		paceat =spulse
		pulsout servoroll,rollat	'pulse servo hold in position
		pulsout servopace,paceat	'pulse servo
		pause sframe
	  next spulse
	return 
_LF:
'sertxd ("_LF")
	paceto =paceC +paceby
	for spulse=paceat to paceto step pacespeed
		paceat =spulse
		pulsout servoroll,rollat	'pulse servo hold in position
		pulsout servopace,paceat	'pulse servo
		pause sframe
	  next spulse
	return 
'-----------------------------------------
Stand:	'stand with both feet flat
'sertxd (" Sd")
	if rollat<rollC then _StandR 'else _StandL
_StandL:
'sertxd ("_SL")
	for spulse=rollat to rollC step -rollspeed
		rollat =spulse
		pulsout servoroll,rollat	'pulse servo
		pulsout servopace,paceat	'pulse servo hold in position
		pause sframe
	  next spulse
	return 
_StandR:
'sertxd ("_SR")
	for spulse=rollat to rollC step rollspeed
		rollat =spulse
		pulsout servoroll,rollat	'pulse servo
		pulsout servopace,paceat	'pulse servo hold in position
		pause sframe
	  next spulse
	return 
'-----------------------------------------
_rollL:
'sertxd ("_rL")
	rollto =rollC -rollby
	for spulse=rollat to rollto step -rollspeed
		rollat =spulse
		pulsout servoroll,rollat	'pulse servo
		pulsout servopace,paceat	'pulse servo hold in position
		pause sframe
	  next spulse
	return 
	 
_rollR:
'sertxd ("_rR")
	rollto =rollC +rollby
	for Spulse=rollat to rollto step rollspeed
		rollat =spulse
		pulsout servoroll,rollat	'pulse servo
		pulsout servopace,paceat	'pulse servo hold in position
		pause sframe
	  next spulse
	return 
'-----------------------------------------
_iStand:
'initialise with feet in mid position
	for spulse=0 to 10
		pulsout servopace,paceC		'pulse servo paceC
		pulsout servoroll,rollC		'pulse servo rollC
		pause 70			'pause 70ms - do it slowly
	  next spulse
	rollat =rollC
	paceat =paceC 
	return 
'-----------------------------------------
beep50:
	sound VoiceLed_,(50,10)	'this leaves mouthLED ON
	high VoiceLed_			'turn off mouth
	return

beep150:
	sound VoiceLed_,(150,10)	'this leaves mouthLED ON
	high VoiceLed_			'turn off mouth
	return

EyesOFF:
	high eyeLedR_
	high eyeLedL_
	return
	
EyesON:
	low eyeLedR_
	low eyeLedL_
	return
'=================================================================

[page top]

'Bambino-23
Sertxd("B23",cr)		'report program number @4800

#PicAxe 20M2
#no_data
'PICAXE            IC   Memory   ext  I/O   Outputs  Inputs  ADC  Memory                        Starts  Polled  Resonator
' £   Type        pins  bytes    slot pins                        Vars. RAM Spad Data     Table*        Int.    def. opt. 
'2.28 PICAXE-20M2  20    2k           18    1-16     1-17     4    28   512      256      512   8       Yes      4   -32

'PICAXE-20M2 circuit board with LEDs off takes 1mA
'PICAXE-20M2 circuit board with LEDs off and servos connected takes 10mA


'Bambino-01	'Test eyeLEDs, whiskerLEDs and speaker
'Bambino-02	'Test InfraRed input
'Bambino-02a'Test Eye light values
'Bambino-02b'Test Whisker light values
'Bambino-03	'Play the inbuilt tunes using keys 1 to 4 and beep on 5
'Bambino-04	'Set servos to mid position	
'Bambino-05	'Calibrate servo mid positions and put values in EEPROM.
'Bambino-06	'Introduce _iStand:- initialise with feet in mid position
'Bambino-07	'Set rollR
'Bambino-08	'Set rollL
'Bambino-09	'Check rollR, rollL
'Bambino-10	'Introduction of _Stand
'Bambino-11	'Investigate effect of rollspeed;	watch roll for all three speeds
'Bambino-12	'Investigate effect of rollspeed;	watch Roll and Stand for all three speeds
'Bambino-13	'Check paceFL paceFR;	Investigate effect of pacespeed
'Bambino-14	'Check Fd
'Bambino-15	'Test Rt, Lt
'Bambino-15a'Test T2L Turn to Light, T2D Turn to Dark
'Bambino-16	'Test Bk
'Bambino-17	'Creaton of sections ACTIONS, BEHAVIOURS, ACTS;
            	'Introduction of ACT parameter 'Ado'
'Bambino-17a'Demo routine            	
'Bambino-18	'Walk Fd with obstacle avoidance using eyes from 02a
'Bambino-18a	'Walk Fd with drop-off avoidance using whiskers values from 02b
'Bambino-18b	'rewritten with autocalibration of down whiskers and reading of whiskers as subroutines
'Bambino-19	'If IR command then do it otherwise walk and avoid
'Bambino-20	'rewrite to incorporate rollC and paceC in EEPROM 254,255
'Bambino-21	'rewrite to clearer code
'Bambino-22 'remember a sequence of keys presses          
'Bambino-23 'remember up to 8 sequences of key presses in RAM         
            	
'-----------------------------------------------------------------            	
'modified
'--------

'New
'---
'symbol nokey - deleted
'nokey:		'wait until no IR received
'IRgetAct_cmnd:	'get Act key1 - key8
'DoIRcmnd:;	case KEY_POWER	- rewritten ->DoIRacty, DoCmnd
'[KEY_BAR] enters learn mode
'[KEY_BAR] has to be followed by a number key 1-8 
'	= the Act to be remembered
'up to 8 Acts can be learned
'learned Acts can call coded Acts
'a learned Act which chains itself repeats forever, eg #1 = Fd,1
'Acts can chain to other Acts, eg Fd,Bk,2   - chain to Act2
'[KEY_POWER] stops the playing Act.
'[KEY_TENT] selects coded Acts = subroutines,
'[KEY_TENT] has to be followed by a number key 1-8 
'	 [key1]=>RockAdo
'coded Acts play until the end.
'=================================================================
'TVR010 PicAxe IR-controller
'---------------------------
'Before use, the transmitter must be programmed with the ‘Sony’ transmit code.
'1. Insert 2 AAA size batteries, preferably alkaline.
'2. Press ‘S’ and ‘B’ at the same time. S is in the centre of the arrows. 
'	The top left red LED should light.
'3. Press ‘0’. The LED should flash.
'4. Press ‘1’. The LED should flash.
'5. Press ‘3’. The LED should go out.
'6. Press the red power button (top right).
'-------------------------------------------
'IRin cmnds PicAxe controller
'DO NOT PRESS OTHER KEYS 
'ie [A] [B] [C] [D] [E] [F] [G] 
'They change the Mode and [B] has to be pressed to change back.
'[square] [triangle [()] [L] [X] [backwards F]  have no effect

Symbol KEY_POWER  = 21		'Sleep

Symbol KEY_UP     = 16		'Step Forward
Symbol KEY_DOWN   = 17		'Step Backward
Symbol KEY_RIGHT  = 18		'Turn Right
Symbol KEY_LEFT   = 19		'Turn Left

Symbol KEY_BAR    = 96		'learn an Act
Symbol KEY_TENT   = 54		'
Symbol KEY_VERT_CROSS = 37
Symbol KEY_VCROSS = 37		'use synonym easier coding
Symbol KEY_DIAG_CROSS = 20
Symbol KEY_XCROSS = 20		'use synonym easier coding
symbol IRkey1     =  0
symbol IRkey2     =  1
symbol IRkey3     =  2
symbol IRkey4     =  3
symbol IRkey5     =  4
symbol IRkey6     =  5
symbol IRkey7     =  6
symbol IRkey8     =  7
symbol IRkey9     =  8
Symbol KEY_MINUS  = 98
Symbol KEY_0      =  9		'QUIT command mode
Symbol KEY_PLUS   = 11
'=================================================================
symbol servopace    =c.0	'left connector
symbol servoroll    =c.4	'right connector
symbol VoiceLed_    =c.5      'low =>LED on 
symbol eyeLedL_     =c.2      'low =>LED on 
symbol eyeLedR_     =b.1      'low =>LED on
symbol whiskerLedL_ =c.3    'low =>whisker LED on
symbol whiskerLedR_ =b.3    'low =>whisker LED on
symbol eyeR         =c.7		  	
symbol eyeL         =c.1		  	
symbol iIRin        =c.6
symbol oIRout       =b.2

'symbol general 	=b0
symbol flags	=w1
symbol B_flags     =b3
'symbol f_doIRcmnds  =bit29
symbol f_play	  =bit28	
symbol f_record	  =bit29
symbol f_direction  =bit30	'1=forwards, 0=backwards    
symbol f_defaultB   =bit31	'defaultBehaviour 1=use default
symbol servosAt	=w2
symbol  rollat 	 =b4
symbol  paceat 	 =b5
symbol ServosTo	=w3
symbol  rollTo	 =b6	   
symbol  paceTo	 =b7
symbol Smoveby	=w4
symbol  rollby	 =b8
symbol  paceby     =b9
symbol Scentre	=w5
symbol  rollC	 =b10
symbol  paceC      =b11
symbol Sspeed     =w6
symbol  rollspeed  =b12  '4 is too fast, 0 won't move
symbol  pacespeed  =b13  '6 is about max for servos to keep up
symbol counters	=w7
symbol  spulse 	 =b14
symbol  iA 		 =b15
symbol temp       =w8
symbol  tempL      =b16
'symbol tempH      =b17

symbol sframe     =22	'time between servo pulses

symbol Ado		=b18	'parameter for ACTs
symbol obstacle   =b19  '%11 bitmap of obstacles  %LeftRight
symbol lightL     =b20  'light level Left
symbol lightR     =b21  'light level Right
symbol cmnd	      =b22  'cmnd from IRremote
symbol Act        =b23
symbol Aend		=b24	'end of record slot

symbol act1	=32
symbol act2	=32 *2
symbol act3	=32 *3 
symbol act4	=32 *4
symbol act5	=32 *5
symbol act6	=32 *6
symbol act7	=32 *7
symbol act8	=32 *8

for Act=act1 to act8
	poke Act,255	'set stop markers	
  next Act	

'=================================================================
initialise:
	rollby    =15	'+ve right 
	paceby    =20	'+ve Left  foot forward
	rollspeed =1  	'4 is too fast, 0 won't move
	pacespeed =2   	'6 is about max for servos to keep up  
	rollC	    =150	'Default, 100 is roll to the left
	paceC	    =150	'Default, 100 is left foot back
	read 254,temp	'set in prog5
	if temp>130 and temp<170 then	'so servo is always between 100,200
	  rollC =temp
	 endif 
	read 255,temp	'set in prog5
	if temp>130 and temp<170 then	'so servo is always between 100,200
	  paceC =temp
	 endif 
	sertxd("rollC=",#rollC," paceC=",#paceC,cr)
	low eyeLedR_		'make output LED on
	low eyeLedL_		'make output LED on
	gosub _iStand
	f_defaultB =1		'defaultBehaviour On
	f_record =0
	bptr =32
	poke bptr,0		'no recording

start:
	sertxd("S")
	Ado =4				'for RockAdo
	irin [50,Walkabout],iIRin,cmnd	'irin with timeout, no IR =>Walkabout
	gosub beep50            	'so we know IR received
	goto DoCmnd
'=================================================================
'Activities
'----------
IRacty:
sertxd("IR")
	irin iIRin,cmnd	 	'Get cmnd
	gosub beep50            'so we know IR received
DoCmnd:	
sertxd(cr,#cmnd," @",#bptr)
	sertxd(" f_p",#f_play," f_r",#f_record,",")
		
	select cmnd
	  case KEY_POWER
	  	if f_record=0 and f_play=0 then
	  		gosub rest
			gosub EyesON
			goto DoCmnd	'have already got IRcmnd in rest:
		   else
		      f_play =0
		      if f_record=1 then
		      	f_record =0
    	 			poke bptr,255	     'end marker
    	 		  endif	
    	 		gosub dump  
		 endif 
	  case KEY_UP
	  	gosub Fd
	  case KEY_DOWN
	  	gosub Bk
	  case KEY_RIGHT
	  	gosub Rt
	  case KEY_LEFT
	  	gosub Lt
	  case KEY_0
		goto Start			'QUIT

	  case <IRkey9			'Act keya
	  	if f_record<>1 then
	  		f_play=1			'play
	  		bptr =32 *cmnd +32	'set to start
	  		sertxd(" play@",#bptr,cr)	 
		  endif

	  case KEY_BAR	
	  	f_play =0	
	  	f_record =1
		gosub IRgetAct_cmnd
		bptr =32 *cmnd +32
		Aend =bptr +31
		gosub nokey
	  	sertxd("rec@",#bptr,cr)
	  	goto IRacty	 		'get cmnds
	  	
	  case KEY_TENT			'coded acts
	  	gosub IRgetAct_cmnd
		cmnd =cmnd +128		'set topbit for coded Acts
		sertxd(" Act",#cmnd,cr)
		goto DoCmnd
			 
	  case >127
	  	sertxd("case >127",cr)	 
	    	Act =cmnd -128
	  	on Act gosub RockAdo	'add others
	  	
	  end select


	if f_record=1 then
		if bptr<Aend then
			@bptrinc =cmnd
		 else				'end of slot
		 	gosub beep150
			cmnd =KEY_POWER	
			goto DoCmnd
		 endif				
	   endif

	if f_play=1 then
		irin [50,_playon],iIRin,cmnd
		goto Start		'if IR received =>break		
_playon:		
	 	cmnd =@bptrinc
		if cmnd<>255 then	DoCmnd'255=end
		f_play =0
	  endif
		
	goto IRacty			'get IR

'-----------------------------------------	
Walkabout:
sertxd("W")
	obstacle =0
	gosub EyesOFF
EwhiskerR:
	readadc c.7,lightR
	low eyeLedR_			'eyeR on
	readadc c.7,tempL
	high  eyeLedR_			'eyeR off
	if lightR>tempL then		'why this happens I don't know
	  tempL =lightR				
	 endif	
	tempL =tempL -lightR
	if tempL<2 then EwhiskerL	'ignore
	obstacle =obstacle or 1 
	
EwhiskerL:
	readadc c.1,lightL
	low eyeLedL_			'eyeL on
	readadc c.1,tempL
	high  eyeLedL_			'eyeL off
	if lightL>tempL then		'why this happens I don't know
	  tempL =lightL				
	 endif	
	tempL =tempL -lightL
	if tempL<5 then Walk		'ignore
	obstacle =obstacle or %10 

Walk:	
	gosub B_fast
	b0 =obstacle 			'to use bits
	if bit0=0 then
	  low eyeLedR_
	 endif 
	if bit1=0 then
	  low eyeLedL_
	 endif 
	on obstacle gosub Fd,Lt,Rt,Bk 
	irin [50,Walkabout],iIRin,cmnd	'irin with timeout, no IR =>Walkabout
	goto start                    	'QUIT if IRin
'=================================================================
'Behaviours
'----------
B_fast:
	rollspeed =3
	pacespeed =6
	return
	
B_turn:	
	rollspeed =1	'slow so foot doesn't bounce
	pacespeed =5 
	return	
'=================================================================
'Acts
'----

RockAdo:	'#128
	if f_defaultB=1 then gosub B_fast
	for iA=1 to Ado  
 	  gosub _rollR
	  gosub _rollL
	 next iA 
	gosub Stand 
	return
	
FdAdo:
	for iA=1 to Ado 
	  gosub Fd
	 next iA 
	return
	
BkAdo:
	for iA=1 to Ado 
	  gosub Bk
	 next iA 
	return

Rest:
	gosub _rollL
	gosub _iStand
	pwmout eyeLedR_,100,400 'active low so high Dutycycle for dim
	pwmout eyeLedL_,100,400 'active low so high Dutycycle for dim
_RestIRwait:
	high VoiceLed_
	irin iIRin,cmnd				'irin with no timeout
	gosub beep50            		'so we know IR received
	if cmnd=KEY_POWER then _RestIRwait	'wait until different IRcmnd
	pwmout eyeLedR_,off	
	pwmout eyeLedL_,off
	return
	
'=================================================================
'Actions
'-------

Fd:
sertxd ("Fd")
	f_direction =1
	if f_defaultB=1 then gosub B_fast
	if paceat<paceC then _FdL 'else _FdL
_FdR:
'sertxd ("_FdR")
	gosub _rollL
	gosub _RF
	gosub Stand
	return
_FdL:
'sertxd ("_FdL")
	gosub _rollR
	gosub _LF
	gosub Stand
	return
'-----------------------------------------
Bk:
sertxd ("Bk")
	f_direction =0
	if f_defaultB=1 then gosub B_fast
	if paceat<paceC then _BkR 'else _BkL
_BkL:
	gosub _rollR
	gosub _RF
	gosub Stand
	return
_BkR:
	gosub _rollL
	gosub _LF
	gosub Stand
	return
'-----------------------------------------
Rt:
sertxd ("Rt")
	if paceat<paceC and f_direction=1 then gosub Fd	'need left foot forward
	if paceat<paceC and f_direction=0 then gosub Bk	'need left foot forward
	if f_defaultB=1 then gosub beep150
	if f_defaultB=1 then gosub B_turn
	gosub _RF
	return
'-----------------------------------------
Lt:
sertxd ("Lt")
	if paceat>paceC and f_direction=1 then gosub Fd	'need right foot forward
	if paceat>paceC and f_direction=0 then gosub Bk	'need right foot forward
	if f_defaultB=1 then gosub beep150
	if f_defaultB=1 then gosub B_turn
	gosub _LF
	return
'=================================================================
_RF:
'sertxd ("_RF")
	paceto =paceC -paceby
	for spulse=paceat to paceto step -pacespeed
	  paceat =spulse
	  pulsout servoroll,rollat	'pulse servo hold in position
	  pulsout servopace,paceat	'pulse servo
	  pause sframe
	 next spulse
	return 
_LF:
'sertxd ("_LF")
	paceto =paceC +paceby
	for spulse=paceat to paceto step pacespeed
	  paceat =spulse
	  pulsout servoroll,rollat	'pulse servo hold in position
	  pulsout servopace,paceat	'pulse servo
	  pause sframe
	 next spulse
	return 
'-----------------------------------------
Stand:	'stand with both feet flat
'sertxd (" Sd")
	if rollat<rollC then _StandR 'else _StandL
_StandL:
'sertxd ("_SL")
	for spulse=rollat to rollC step -rollspeed
	  rollat =spulse
	  pulsout servoroll,rollat	'pulse servo
	  pulsout servopace,paceat	'pulse servo hold in position
	  pause sframe
	 next spulse
	return 
_StandR:
'sertxd ("_SR")
	for spulse=rollat to rollC step rollspeed
	  rollat =spulse
	  pulsout servoroll,rollat	'pulse servo
	  pulsout servopace,paceat	'pulse servo hold in position
	  pause sframe
	 next spulse
	return 
'-----------------------------------------
_rollL:
'sertxd ("_rL")
	rollto =rollC -rollby
	for spulse=rollat to rollto step -rollspeed
	  rollat =spulse
	  pulsout servoroll,rollat	'pulse servo
	  pulsout servopace,paceat	'pulse servo hold in position
	  pause sframe
	 next spulse
	return 
	 
_rollR:
'sertxd ("_rR")
	rollto =rollC +rollby
	for Spulse=rollat to rollto step rollspeed
	  rollat =spulse
	  pulsout servoroll,rollat	'pulse servo
	  pulsout servopace,paceat	'pulse servo hold in position
	  pause sframe
	 next spulse
	return 
'-----------------------------------------
_iStand:
'initialise with feet in mid position
	for spulse=0 to 10
	  pulsout servopace,paceC	'pulse servo paceC
	  pulsout servoroll,rollC	'pulse servo rollC
	  pause 70			'pause 70ms - do it slowly
	 next spulse
	rollat =rollC
	paceat =paceC 
	return 
'-----------------------------------------
dump:
	for bptr=32 to 40
		sertxd (cr,#bptr,"=",#@bptr)
		next bptr
	sertxd (cr)
	return
	
badkey:
	high eyeLedR_
	pause 100
	low eyeLedR_
	high eyeLedL_
	pause 100
	low eyeLedL_
	return

beep50:
	sound VoiceLed_,(50,10)
	return

beep150:
	sound VoiceLed_,(150,10)
	return

EyesOFF:
	high eyeLedR_
	high eyeLedL_
	return
	
EyesON:
	low eyeLedR_
	low eyeLedL_
	return
	
IRgetAct_cmnd:	  	
	irin iIRin,cmnd		'key1 - key8 => 0-7
	if cmnd<8 then _IRgetActEnd
	gosub badkey
	goto IRgetAct_cmnd	'repeat until valid act		
_IRgetActEnd:
	gosub beep50	
	return 
	
nokey:
	irin [50,_nokeyend],iIRin,cmnd'irin timeout =>return
	goto nokey
_nokeyend:
	return	
	
'=================================================================

[page top]

'Bambino-24
Sertxd("B24",cr)		'report program number @4800

#PicAxe 20M2
#no_data
'PICAXE            IC   Memory   ext  I/O   Outputs  Inputs  ADC  Memory                        Starts  Polled  Resonator
' £   Type        pins  bytes    slot pins                        Vars. RAM Spad Data     Table*        Int.    def. opt. 
'2.28 PICAXE-20M2  20    2k           18    1-16     1-17     4    28   512      256      512   8       Yes      4   -32

'PICAXE-20M2 circuit board with LEDs off takes 1mA
'PICAXE-20M2 circuit board with LEDs off and servos connected takes 10mA


'Bambino-01	'Test eyeLEDs, whiskerLEDs and speaker
'Bambino-02	'Test InfraRed input
'Bambino-02a'Test Eye light values
'Bambino-02b'Test Whisker light values
'Bambino-03	'Play the inbuilt tunes using keys 1 to 4 and beep on 5
'Bambino-04	'Set servos to mid position	
'Bambino-05	'Calibrate servo mid positions and put values in EEPROM.
'Bambino-06	'Introduce _iStand:- initialise with feet in mid position
'Bambino-07	'Set rollR
'Bambino-08	'Set rollL
'Bambino-09	'Check rollR, rollL
'Bambino-10	'Introduction of _Stand
'Bambino-11	'Investigate effect of rollspeed;	watch roll for all three speeds
'Bambino-12	'Investigate effect of rollspeed;	watch Roll and Stand for all three speeds
'Bambino-13	'Check paceFL paceFR;	Investigate effect of pacespeed
'Bambino-14	'Check Fd
'Bambino-15	'Test Rt, Lt
'Bambino-15a'Test T2L Turn to Light, T2D Turn to Dark
'Bambino-16	'Test Bk
'Bambino-17	'Creaton of sections ACTIONS, BEHAVIOURS, ACTS;
            	'Introduction of ACT parameter 'Ado'
'Bambino-17a'Demo routine            	
'Bambino-18	'Walk Fd with obstacle avoidance using eyes from 02a
'Bambino-18a	'Walk Fd with drop-off avoidance using whiskers values from 02b
'Bambino-18b	'rewritten with autocalibration of down whiskers and reading of whiskers as subroutines
'Bambino-19	'If IR command then do it otherwise walk and avoid
'Bambino-20	'rewrite to incorporate rollC and paceC in EEPROM 254,255
'Bambino-21	'rewrite to clearer code
'Bambino-22 'remember a sequence of keys presses          
'Bambino-23 'remember up to 8 sequence of keys presses in RAM          
'Bambino-24 'remember up to 8 sequence of key presses in EEPROM          
            	
'-----------------------------------------------------------------            	
'modified
'--------
'DoCmnd:
'	select cmnd		- eptr
'	case <IRkey9	- eptr
'	case KEY_BAR	- eptr, Act0 now starts at EEPROM0, before it was at RAM32
'	case >127		- eptr, Act0 now starts at EEPROM0, before it was at RAM32,	
'New
'---
'case [KEY_XCROSS] sertxds EEPROM values as DATA x,x,x,x, to a PC
'symbol eptr

'=================================================================
'[KEY_BAR] enters learn mode
'[KEY_BAR] has to be followed by a number key 1-8 
'	= the Act to be remembered
'up to 8 Acts can be learned
'learned Acts can call coded Acts
'a learned Act which chains itself repeats forever, eg #1 = Fd,1
'Acts can chain to other Acts, eg Fd,Bk,2   - chain to Act2
'[KEY_POWER] stops the playing Act.
'[KEY_TENT] selects coded Acts = subroutines,
'[KEY_TENT] has to be followed by a number key 1-8 
'	 [key1]=>RockAdo
'coded Acts play until the end.
'
'[KEY_XCROSS]			'Dump EEPROM DATA to PC
'
'When recording an Act, 
'	after [IRkey1],[IRkey2],[IRkey3],[IRkey4],[IRkey5],[IRkey6],[IRkey7],[IRkey8]
'	is used to chain another Act there is no point in recording more moves 
'	because they will never be replayed since control is transfered to the new Act,
'	just press [KEY_POWER] to end recording.
'NOTE do not record more than 30 moves for Act8 otherwise it will overwrite the servo calibration of RollC and PaceC
'=================================================================
'TVR010 PicAxe IR-controller
'---------------------------
'Before use, the transmitter must be programmed with the ‘Sony’ transmit code.
'1. Insert 2 AAA size batteries, preferably alkaline.
'2. Press ‘S’ and ‘B’ at the same time. S is in the centre of the arrows. 
'	The top left red LED should light.
'3. Press ‘0’. The LED should flash.
'4. Press ‘1’. The LED should flash.
'5. Press ‘3’. The LED should go out.
'6. Press the red power button (top right).
'-------------------------------------------
'IRin cmnds PicAxe controller
'DO NOT PRESS OTHER KEYS 
'ie [A] [B] [C] [D] [E] [F] [G] 
'They change the Mode and [B] has to be pressed to change back.
'[square] [triangle [()] [L] [X] [backwards F]  have no effect

Symbol KEY_POWER  = 21		'Sleep

Symbol KEY_UP     = 16		'Step Forward
Symbol KEY_DOWN   = 17		'Step Backward
Symbol KEY_RIGHT  = 18		'Turn Right
Symbol KEY_LEFT   = 19		'Turn Left

Symbol KEY_BAR    = 96		'learn an Act, next [key] selects a Act
Symbol KEY_TENT   = 54		'next [key] selects a Coded-Act
Symbol KEY_VERT_CROSS = 37	'use synonym for easier coding
Symbol KEY_VCROSS = 37
Symbol KEY_DIAG_CROSS = 20	'use synonym for easier coding
Symbol KEY_XCROSS = 20		'transfer EEPROM to PC for including in programs		'
					'Coded Acts		
symbol IRkey1     =  0		'		RockADo	
symbol IRkey2     =  1
symbol IRkey3     =  2
symbol IRkey4     =  3
symbol IRkey5     =  4
symbol IRkey6     =  5
symbol IRkey7     =  6
symbol IRkey8     =  7
symbol IRkey9     =  8
Symbol KEY_MINUS  = 98
Symbol KEY_0      =  9		'QUIT command mode
Symbol KEY_PLUS   = 11
'=================================================================
symbol servopace    =c.0	'left connector
symbol servoroll    =c.4	'right connector
symbol VoiceLed_    =c.5        'low =>LED on 
symbol eyeLedL_     =c.2        'low =>LED on 
symbol eyeLedR_     =b.1        'low =>LED on
symbol whiskerLedL_ =c.3        'low =>whisker LED on
symbol whiskerLedR_ =b.3        'low =>whisker LED on
symbol eyeR         =c.7		  	
symbol eyeL         =c.1		  	
symbol iIRin        =c.6
symbol oIRout       =b.2

'symbol general 	=b0
symbol flags	  =w1
symbol B_flags    =b3
'symbol f_doIRcmnds  =bit29
symbol f_play	      =bit28	
symbol f_record	    =bit29
symbol f_direction  =bit30	'1=forwards, 0=backwards    
symbol f_defaultB   =bit31	'defaultBehaviour 1=use default
symbol servosAt	=w2
symbol  rollat 	  =b4
symbol  paceat 	  =b5
symbol ServosTo	=w3
symbol  rollTo	  =b6	   
symbol  paceTo	  =b7
symbol Smoveby	=w4
symbol  rollby	  =b8
symbol  paceby    =b9
symbol Scentre	=w5
symbol  rollC	    =b10
symbol  paceC     =b11
symbol Sspeed   =w6
symbol  rollspeed  =b12  '4 is too fast, 0 won't move
symbol  pacespeed  =b13  '6 is about max for servos to keep up
symbol counters	=w7
symbol  spulse 	  =b14
symbol  iA 		    =b15
symbol temp     =w8
symbol  tempLo     =b16
symbol tempHi      =b17

symbol sframe     =22	'time between servo pulses

symbol Ado		    =b18	'parameter for ACTs
symbol obstacle   =b19  '%11 bitmap of obstacles  %LeftRight
symbol lightL     =b20  'light level Left
symbol lightR     =b21  'light level Right
symbol objthresh  =70   'light/dark whisker threshold for obstacle 
symbol cmnd	      =b22  'cmnd from IRremote
symbol Act        =b23
symbol Aend		    =b24	'end of record slot
symbol eptr       =b25			'pointer to EEPROM

symbol act1	=32
symbol act2	=32 *2
symbol act3	=32 *3 
symbol act4	=32 *4
symbol act5	=32 *5
symbol act6	=32 *6
symbol act7	=32 *7
symbol act8	=32 *8

for Act=act1 to act8
	poke Act,255	'set stop markers	
  next Act	

'=================================================================
initialise:
	rollby    =15	'+ve right 
	paceby    =20	'+ve Left  foot forward
	rollspeed =1  	'4 is too fast, 0 won't move
	pacespeed =2   	'6 is about max for servos to keep up  
	rollC	    =150	'Default, 100 is roll to the left
	paceC	    =150	'Default, 100 is left foot back
	read 254,temp	'set in prog5
	if temp>130 and temp<170 then	'so servo is always between 100,200
	  rollC =temp
	 endif 
	read 255,temp	'set in prog5
	if temp>130 and temp<170 then	'so servo is always between 100,200
	  paceC =temp
	 endif 
	sertxd("rollC=",#rollC," paceC=",#paceC,cr)
	low eyeLedR_	'make output LED on
	low eyeLedL_	'make output LED on
	gosub _iStand
	f_defaultB =1	'defaultBehaviour On
	f_record =0

start:
sertxd("S")
	Ado =4				'for RockAdo
	irin [50,Walkabout],iIRin,cmnd'irin with timeout, no IR =>Walkabout
	gosub beep50                  'so we know IR received
	goto DoCmnd
'=================================================================
'Activities
'----------
IRacty:
	sertxd("IR")
	irin iIRin,cmnd	 	'Get cmnd
	gosub beep50            'so we know IR received
DoCmnd:	
	sertxd(cr,#cmnd," @",#eptr)
	sertxd(" f_p",#f_play," f_r",#f_record,",")
		
	select cmnd
	  case KEY_POWER
	  	if f_record=0 and f_play=0 then
	  		gosub rest
			gosub EyesON
			goto DoCmnd	'have already got IRcmnd in rest:
		   else
		      f_play =0
		      if f_record=1 then
		      	f_record =0
    	 			poke eptr,255	     'end marker
    	 		  endif	
    	 		'gosub dump  
		 endif 
	  case KEY_UP
	  	gosub Fd
	  case KEY_DOWN
	  	gosub Bk
	  case KEY_RIGHT
	  	gosub Rt
	  case KEY_LEFT
	  	gosub Lt
	  case KEY_0
		goto Start			'QUIT

	  case <IRkey9			'Act keys 1-8 => Acts 0-7
	  	if f_record<>1 then
	  		f_play=1			'play
	  		eptr =32 *cmnd		'set to start
	  		sertxd(" play@",#eptr,cr)	 
		  endif

	  case KEY_BAR	
	  	f_play =0	
	  	f_record =1
		gosub IRgetAct_cmnd
		eptr =32 *cmnd
		Aend =eptr +31
		gosub nokey
	  	sertxd("rec@",#eptr,cr)
	  	goto IRacty	 		'get cmnds
	  	
	  case KEY_TENT			'coded acts
	  	gosub IRgetAct_cmnd
		cmnd =cmnd +128		'set topbit for coded Acts
		sertxd(" Act",#cmnd,cr)
		goto DoCmnd
		
	  case KEY_XCROSS			'Dump DATA to PC	
		for Act=0 to 7
			sertxd(cr,lf,"'Act ",#Act,cr,lf,"DATA ")
			for eptr=0 to 30
				tempLo =Act *32 +eptr
				read tempLo,cmnd
				sertxd(#cmnd,",")
			  next eptr
			tempLo =Act *32 +31
			read tempLo,cmnd
			sertxd(#cmnd)
		  next Act
		sertxd(cr,lf)
		  	   
	  case >127
	  	sertxd("case >127",cr)	 
	    	Act =cmnd -128
	  	on Act gosub RockAdo	'add others
	  	
	  end select


	if f_record=1 then
		if eptr<Aend then
			write eptr,cmnd
			eptr =eptr +1
		 else				'end of slot
		 	gosub beep150
			cmnd =KEY_POWER	
			goto DoCmnd
		 endif	
	   endif

	if f_play=1 then
		irin [50,_playon],iIRin,cmnd
		goto Start			'if IR received =>break		
_playon:		
	 	read eptr,cmnd
 		eptr =eptr +1
		if cmnd<>255 then	DoCmnd	'255=end
		f_play =0
	  endif
		
	goto IRacty				'get IR


	
'-----------------------------------------	
Walkabout:
sertxd("W")
	obstacle =0
	gosub EyesOFF
EwhiskerR:
	readadc c.7,lightR
	low eyeLedR_			  	'eyeR on
	readadc c.7,tempLo
	high  eyeLedR_				'eyeR off
	if lightR>tempLo then		'why this happens I don't know
	  tempLo =lightR				
	 endif	
	tempLo =tempLo -lightR *256 /lightR	'scale
	if tempLo<objthresh then EwhiskerL	'ignore
	obstacle =obstacle or 1 
	
EwhiskerL:
	readadc c.1,lightL			'withLEDoff
	low eyeLedL_				'eyeL on
	readadc c.1,tempLo			'withLEDon
	high  eyeLedL_				'eyeL off
	if lightL>tempLo then		'why this happens I don't know
	  tempLo =lightL				
	 endif	
	tempLo =tempLo -lightL *256 /lightL	'scale
	
	if tempLo<objthresh then Walk	'ignore
	obstacle =obstacle or %10 

Walk:	
	gosub B_fast
	b0 =obstacle 				'to use bits
	if bit0=0 then
	  low eyeLedR_
	 endif 
	if bit1=0 then
	  low eyeLedL_
	 endif 
	on obstacle gosub Fd,Lt,Rt,Bk 
	irin [50,Walkabout],iIRin,cmnd	'irin with timeout, no IR =>Walkabout
	goto start                    'QUIT if IRin
'=================================================================
'Behaviours
'----------
B_fast:
	rollspeed =3
	pacespeed =6
	return
	
B_turn:	
	rollspeed =1	'slow so foot doesn't bounce
	pacespeed =5 
	return	
'=================================================================
'Acts
'----

RockAdo:	'#128
	if f_defaultB=1 then gosub B_fast
	for iA=1 to Ado  
 	  gosub _rollR
	  gosub _rollL
	 next iA 
	gosub Stand 
	return
	
FdAdo:
	for iA=1 to Ado 
	  gosub Fd
	 next iA 
	return
	
BkAdo:
	for iA=1 to Ado 
	  gosub Bk
	 next iA 
	return

Rest:
	gosub _rollL
	gosub _iStand
	pwmout eyeLedR_,100,400 'active low so high Dutycycle for dim
	pwmout eyeLedL_,100,400 'active low so high Dutycycle for dim
_RestIRwait:
	high VoiceLed_
	irin iIRin,cmnd		'irin with no timeout
	gosub beep50            'so we know IR received
	if cmnd=KEY_POWER then _RestIRwait	'wait until different IRcmnd
	pwmout eyeLedR_,off	
	pwmout eyeLedL_,off
	return
	
'=================================================================
'Actions
'-------

Fd:
sertxd ("Fd")
	f_direction =1
	if f_defaultB=1 then gosub B_fast
	if paceat<paceC then _FdL 'else _FdL
_FdR:
'sertxd ("_FdR")
	gosub _rollL
	gosub _RF
	gosub Stand
	return
_FdL:
'sertxd ("_FdL")
	gosub _rollR
	gosub _LF
	gosub Stand
	return
'-----------------------------------------
Bk:
sertxd ("Bk")
	f_direction =0
	if f_defaultB=1 then gosub B_fast
	if paceat<paceC then _BkR 'else _BkL
_BkL:
	gosub _rollR
	gosub _RF
	gosub Stand
	return
_BkR:
	gosub _rollL
	gosub _LF
	gosub Stand
	return
'-----------------------------------------
Rt:
sertxd ("Rt")
	if paceat<paceC and f_direction=1 then gosub Fd	'need left foot forward
	if paceat<paceC and f_direction=0 then gosub Bk	'need left foot forward
	if f_defaultB=1 then gosub beep150
	if f_defaultB=1 then gosub B_turn
	gosub _RF
	return
'-----------------------------------------
Lt:
sertxd ("Lt")
	if paceat>paceC and f_direction=1 then gosub Fd	'need right foot forward
	if paceat>paceC and f_direction=0 then gosub Bk	'need right foot forward
	if f_defaultB=1 then gosub beep150
	if f_defaultB=1 then gosub B_turn
	gosub _LF
	return
'=================================================================
_RF:
'sertxd ("_RF")
	paceto =paceC -paceby
	for spulse=paceat to paceto step -pacespeed
	  paceat =spulse
	  pulsout servoroll,rollat	'pulse servo hold in position
	  pulsout servopace,paceat	'pulse servo
	  pause sframe
	 next spulse
	return 
_LF:
'sertxd ("_LF")
	paceto =paceC +paceby
	for spulse=paceat to paceto step pacespeed
	  paceat =spulse
	  pulsout servoroll,rollat	'pulse servo hold in position
	  pulsout servopace,paceat	'pulse servo
	  pause sframe
	 next spulse
	return 
'-----------------------------------------
Stand:	'stand with both feet flat
'sertxd (" Sd")
	if rollat<rollC then _StandR 'else _StandL
_StandL:
'sertxd ("_SL")
	for spulse=rollat to rollC step -rollspeed
	  rollat =spulse
	  pulsout servoroll,rollat	'pulse servo
	  pulsout servopace,paceat	'pulse servo hold in position
	  pause sframe
	 next spulse
	return 
_StandR:
'sertxd ("_SR")
	for spulse=rollat to rollC step rollspeed
	  rollat =spulse
	  pulsout servoroll,rollat	'pulse servo
	  pulsout servopace,paceat	'pulse servo hold in position
	  pause sframe
	 next spulse
	return 
'-----------------------------------------
_rollL:
'sertxd ("_rL")
	rollto =rollC -rollby
	for spulse=rollat to rollto step -rollspeed
	  rollat =spulse
	  pulsout servoroll,rollat	'pulse servo
	  pulsout servopace,paceat	'pulse servo hold in position
	  pause sframe
	 next spulse
	return 
	 
_rollR:
'sertxd ("_rR")
	rollto =rollC +rollby
	for Spulse=rollat to rollto step rollspeed
	  rollat =spulse
	  pulsout servoroll,rollat	'pulse servo
	  pulsout servopace,paceat	'pulse servo hold in position
	  pause sframe
	 next spulse
	return 
'-----------------------------------------
_iStand:
'initialise with feet in mid position
	for spulse=0 to 10
	  pulsout servopace,paceC	'pulse servo paceC
	  pulsout servoroll,rollC	'pulse servo rollC
	  pause 70			'pause 70ms - do it slowly
	 next spulse
	rollat =rollC
	paceat =paceC 
	return 
'-----------------------------------------
badkey:
	high eyeLedR_
	pause 100
	low eyeLedR_
	high eyeLedL_
	pause 100
	low eyeLedL_
	return

beep50:
	sound VoiceLed_,(50,10)
	return

beep150:
	sound VoiceLed_,(150,10)
	return

EyesOFF:
	high eyeLedR_
	high eyeLedL_
	return
	
EyesON:
	low eyeLedR_
	low eyeLedL_
	return
	
IRgetAct_cmnd:	  	
	irin iIRin,cmnd			'key1 - key8 => 0-7
	if cmnd<8 then _IRgetActEnd
	gosub badkey
	goto IRgetAct_cmnd		'repeat until valid act		
_IRgetActEnd:
	gosub beep50	
	return 
	
nokey:
	irin [50,_nokeyend],iIRin,cmnd	'irin timeout =>return
	goto nokey
_nokeyend:
	return	
	
'=================================================================

[page top]

'Bambino-25
Sertxd("B25",cr)		'report program number @4800

#PicAxe 20M2
#no_data
'PICAXE            IC   Memory   ext  I/O   Outputs  Inputs  ADC  Memory                        Starts  Polled  Resonator
' £   Type        pins  bytes    slot pins                        Vars. RAM Spad Data     Table*        Int.    def. opt. 
'2.28 PICAXE-20M2  20    2k           18    1-16     1-17     4    28   512      256      512   8       Yes      4   -32

'PICAXE-20M2 circuit board with LEDs off takes 1mA
'PICAXE-20M2 circuit board with LEDs off and servos connected takes 10mA


'Bambino-01	'Test eyeLEDs, whiskerLEDs and speaker
'Bambino-02	'Test InfraRed input
'Bambino-02a'Test Eye light values
'Bambino-02b'Test Whisker light values
'Bambino-03	'Play the inbuilt tunes using keys 1 to 4 and beep on 5
'Bambino-04	'Set servos to mid position	
'Bambino-05	'Calibrate servo mid positions and put values in EEPROM.
'Bambino-06	'Introduce _iStand:- initialise with feet in mid position
'Bambino-07	'Set rollR
'Bambino-08	'Set rollL
'Bambino-09	'Check rollR, rollL
'Bambino-10	'Introduction of _Stand
'Bambino-11	'Investigate effect of rollspeed;	watch roll for all three speeds
'Bambino-12	'Investigate effect of rollspeed;	watch Roll and Stand for all three speeds
'Bambino-13	'Check paceFL paceFR;	Investigate effect of pacespeed
'Bambino-14	'Check Fd
'Bambino-15	'Test Rt, Lt
'Bambino-15a'Test T2L Turn to Light, T2D Turn to Dark
'Bambino-16	'Test Bk
'Bambino-17	'Creaton of sections ACTIONS, BEHAVIOURS, ACTS;
            	'Introduction of ACT parameter 'Ado'
'Bambino-17a'Demo routine            	
'Bambino-18	'Walk Fd with obstacle avoidance using eyes from 02a
'Bambino-18a	'Walk Fd with drop-off avoidance using whiskers values from 02b
'Bambino-18b	'rewritten with autocalibration of down whiskers and reading of whiskers as subroutines
'Bambino-19	'If IR command then do it otherwise walk and avoid
'Bambino-20	'rewrite to incorporate rollC and paceC in EEPROM 254,255
'Bambino-21	'rewrite to clearer code
'Bambino-22 'remember a sequence of keys presses          
'Bambino-23 'remember up to 8 sequence of keys presses in RAM          
'Bambino-24 'remember up to 8 sequence of keys presses in EEPROM          
'Bambino-25 'obstacle map made deeper and put in RAM for better obstacle avoidance
            	
'-----------------------------------------------------------------            	
'modified
'--------
'Walk: on obstacle gosub Fd,Lt,Rt,Bk  etc
'moved to Walkabout:
'EwhiskerR:
'EwhiskerL:

'New
'---
'Qwalk	'Query, walk
'symbol obstacleR =32	'RAM	obstacle memory
'symbol obstacleL =33	'RAM	obstacle memory
'symbol obs       =4	'increment  for obstacle
'=================================================================
'[KEY_BAR] enters learn mode
'[KEY_BAR] has to be followed by a number key 1-8 
'	= the Act to be remembered
'up to 8 Acts can be learned
'learned Acts can call coded Acts
'a learned Act which chains itself repeats forever, eg #1 = Fd,1
'Acts can chain to other Acts, eg Fd,Bk,2   - chain to Act2
'[KEY_POWER] stops the playing Act.
'[KEY_TENT] selects coded Acts = subroutines,
'[KEY_TENT] has to be followed by a number key 1-8 
'	 [key1]=>RockAdo
'coded Acts play until the end.
'
'[KEY_XCROSS]			'Dump EEPROM DATA to PC

'When recording an Act, 
'	after [IRkey1],[IRkey2],[IRkey3],[IRkey4],[IRkey5],[IRkey6],[IRkey7],[IRkey8]
'	is used to chain another Act there is no point in recording more moves 
'	because they will never be replayed since control is transfered to the new Act,
'	just press [KEY_POWER] to end recording.
'NOTE do not record more than 30 moves for Act8 otherwise it will overwrite the servo calibration of RollC and PaceC
'=================================================================
'TVR010 PicAxe IR-controller
'---------------------------
'Before use, the transmitter must be programmed with the ‘Sony’ transmit code.
'1. Insert 2 AAA size batteries, preferably alkaline.
'2. Press ‘S’ and ‘B’ at the same time. S is in the centre of the arrows. 
'	The top left red LED should light.
'3. Press ‘0’. The LED should flash.
'4. Press ‘1’. The LED should flash.
'5. Press ‘3’. The LED should go out.
'6. Press the red power button (top right).
'-------------------------------------------
'IRin cmnds PicAxe controller
'DO NOT PRESS OTHER KEYS 
'ie [A] [B] [C] [D] [E] [F] [G] 
'They change the Mode and [B] has to be pressed to change back.
'[square] [triangle [()] [L] [X] [backwards F]  have no effect

Symbol KEY_POWER  = 21		'Sleep

Symbol KEY_UP     = 16		'Step Forward
Symbol KEY_DOWN   = 17		'Step Backward
Symbol KEY_RIGHT  = 18		'Turn Right
Symbol KEY_LEFT   = 19		'Turn Left

Symbol KEY_BAR    = 96		'learn an Act, next [key] selects a Act
Symbol KEY_TENT   = 54		'next [key] selects a Coded-Act
Symbol KEY_VERT_CROSS = 37	'use synonym for easier coding
Symbol KEY_VCROSS = 37
Symbol KEY_DIAG_CROSS = 20	'use synonym for easier coding
Symbol KEY_XCROSS = 20		'transfer EEPROM to PC for including in programs		'
					'Coded Acts		
symbol IRkey1     =  0		'		RockADo	
symbol IRkey2     =  1
symbol IRkey3     =  2
symbol IRkey4     =  3
symbol IRkey5     =  4
symbol IRkey6     =  5
symbol IRkey7     =  6
symbol IRkey8     =  7
symbol IRkey9     =  8
Symbol KEY_MINUS  = 98
Symbol KEY_0      =  9		'QUIT command mode
Symbol KEY_PLUS   = 11
'=================================================================
symbol servopace    =c.0	'left connector
symbol servoroll    =c.4	'right connector
symbol VoiceLed_    =c.5        'low =>LED on 
symbol eyeLedL_     =c.2        'low =>LED on 
symbol eyeLedR_     =b.1        'low =>LED on
symbol whiskerLedL_ =c.3        'low =>whisker LED on
symbol whiskerLedR_ =b.3        'low =>whisker LED on
symbol eyeR         =c.7		  	
symbol eyeL         =c.1		  	
symbol iIRin        =c.6
symbol oIRout       =b.2

'symbol general 	=b0
symbol flags	  =w1
symbol B_flags    =b3
'symbol f_doIRcmnds  =bit29
symbol f_play	      =bit28	
symbol f_record	    =bit29
symbol f_direction  =bit30	'1=forwards, 0=backwards    
symbol f_defaultB   =bit31	'defaultBehaviour 1=use default
symbol servosAt	=w2
symbol  rollat 	  =b4
symbol  paceat 	  =b5
symbol ServosTo	=w3
symbol  rollTo	  =b6	   
symbol  paceTo	  =b7
symbol Smoveby	=w4
symbol  rollby	  =b8
symbol  paceby    =b9
symbol Scentre	=w5
symbol  rollC	  =b10
symbol  paceC     =b11
symbol Sspeed   =w6
symbol  rollspeed =b12  '4 is too fast, 0 won't move
symbol  pacespeed =b13  '6 is about max for servos to keep up
symbol counters	=w7
symbol  spulse 	  =b14
symbol  iA 	  =b15
symbol temp     =w8
symbol  tempLo    =b16
symbol tempHi     =b17

symbol sframe     =22	'time between servo pulses

symbol Ado	  =b18	'parameter for ACTs
symbol obsmap     =b19  '%11 bitmap of obstacles  %LeftRight
symbol lightL     =b20  'light level Left
symbol lightR     =b21  'light level Right
symbol objthresh  =70   'light/dark whisker threshold for obstacle 
symbol cmnd	  =b22  'cmnd from IRremote
symbol Act        =b23
symbol Aend	  =b24	'end of record slot
symbol eptr       =b25	'pointer to EEPROM
symbol EEholedetectR =252
symbol EEholedetectL =253
symbol EErollC       =254
symbol EEpaceC       =255

'EEPROM Acts
symbol act0	=0
symbol act1	=32 
symbol act2	=32 *2
symbol act3	=32 *3 
symbol act4	=32 *4
symbol act5	=32 *5
symbol act6	=32 *6
symbol act7	=32 *7
symbol act8	=32 *8

'for Act=act1 to act8
'	poke Act,255	'set stop markers	
'  next Act	


symbol obstaclesR =32	'RAM
symbol obstaclesL =33	'RAM
symbol obs        =6'8	'increment  for obstacle
'=================================================================
initialise:
	rollby    =15	'+ve right 
	paceby    =20	'+ve Left  foot forward
	rollspeed =1  	'4 is too fast, 0 won't move
	pacespeed =2   	'6 is about max for servos to keep up  
	rollC	    =150	'Default, 100 is roll to the left
	paceC	    =150	'Default, 100 is left foot back
	read EErollC,temp	'set in prog5
	if temp>130 and temp<170 then	'so servo is always between 100,200
	  rollC =temp
	 endif 
	read EEpaceC,temp	'set in prog5
	if temp>130 and temp<170 then	'so servo is always between 100,200
	  paceC =temp
	 endif 
	sertxd("rollC=",#rollC," paceC=",#paceC,cr)
	low eyeLedR_	'make output LED on
	low eyeLedL_	'make output LED on
	gosub _iStand
	f_defaultB =1	'defaultBehaviour On
	f_record =0

start:
sertxd("S")
	Ado =4				'for RockAdo
	irin [50,Walkabout],iIRin,cmnd'irin with timeout, no IR =>Walkabout
	gosub beep50                  'so we know IR received
	goto DoCmnd
'=================================================================
'Activities
'----------
IRacty:
	sertxd("IR")
	irin iIRin,cmnd	 	'Get cmnd
	gosub beep50            'so we know IR received
DoCmnd:	
	sertxd(cr,#cmnd," @",#eptr)
	sertxd(" f_p",#f_play," f_r",#f_record,",")
		
	select cmnd
	  case KEY_POWER
	  	if f_record=0 and f_play=0 then
	  		gosub rest
			gosub EyesON
			goto DoCmnd	'have already got IRcmnd in rest:
		   else
		      f_play =0
		      if f_record=1 then
		      	f_record =0
    	 			poke eptr,255	     'end marker
    	 		  endif	
 		 endif 
	  case KEY_UP
	  	gosub Fd
	  case KEY_DOWN
	  	gosub Bk
	  case KEY_RIGHT
	  	gosub Rt
	  case KEY_LEFT
	  	gosub Lt
	  case KEY_0
		goto Start			'QUIT and Wander

	  case <IRkey9			'Act keys 1-8 => Acts 0-7
	  	if f_record<>1 then
	  		f_play=1		'play
	  		eptr =32 *cmnd	'set to start
	  		sertxd(" play@",#eptr,cr)	 
		  endif

	  case KEY_BAR			'record
	  	f_play =0	
	  	f_record =1
		gosub IRgetAct_cmnd
		eptr =32 *cmnd
		Aend =eptr +31
		gosub nokey
	  	sertxd("rec@",#eptr,cr)
	  	goto IRacty	 		'get cmnds
	  	
	  case KEY_TENT			'coded acts
	  	gosub IRgetAct_cmnd
		cmnd =cmnd +128		'set topbit for coded Acts
		sertxd(" Act",#cmnd,cr)
		goto DoCmnd
		
	  case KEY_XCROSS			'Dump DATA to PC
		for Act=0 to 7
			sertxd(cr,lf,"'Act ",#Act,cr,lf,"DATA ")
			for eptr=0 to 30
				tempLo =Act *32 +eptr
				read tempLo,cmnd
				sertxd(#cmnd,",")
			  next eptr
			tempLo =Act *32 +31
			read tempLo,cmnd
			sertxd(#cmnd)
		  next Act
		sertxd(cr,lf)
		  	   
	  case >127				'do Coded Act subroutines
	  	sertxd("case >127",cr)	 
	    	Act =cmnd -128
	  	on Act gosub RockAdo	'add others
	  	
	  end select


'_record
	if f_record=1 then
		if eptr<Aend then
			write eptr,cmnd
			eptr =eptr +1
		 else				'end of slot
		 	gosub beep150
			cmnd =KEY_POWER	
			goto DoCmnd
		 endif	
	   endif

'_play:
	if f_play=1 then
		irin [50,_playon],iIRin,cmnd
		goto Start			'if IR received =>break		
_playon:		
	 	read eptr,cmnd
 		eptr =eptr +1
		if cmnd<>255 then	DoCmnd	'255=end
		f_play =0
	  endif
		
	goto IRacty				'get IR


	
'-----------------------------------------	
Walkabout:
sertxd("W")
	peek obstaclesR,tempLo	'read memory
	peek obstaclesL,tempHi	'read memory

	tempLo =tempLo min 1 -1 'decay memory
	tempHi =tempHi min 1 -1 'decay memory

  	if tempLo>0 then		'create short term memory map
  		obsmap =obsmap or %1
   	 endif
  	if tempHi>0 then
  		obsmap =obsmap or %10
   	 endif
	poke obstaclesR,tempLo	'save
	poke obstaclesL,tempHi	'save
	sertxd ("mem",#tempHi," ",#tempLo,cr)

	gosub B_fast
	'alter LEDs so we can tell what Bambino is doing
	b0 =obsmap 			'to use bits
	if bit0=0 then	
	  low eyeLedR_
	 endif 
	if bit1=0 then
	  low eyeLedL_
	 endif 
	'take avoiding action if necessary 
  	on obsmap gosub Fd,Lt,Rt,Bk 
	obsmap =0
	 
	gosub EyesOFF
EwhiskerR:
	readadc c.7,lightR
	low eyeLedR_			'eyeR on
	readadc c.7,tempLo
	high  eyeLedR_			'eyeR off
	if lightR>tempLo then		'why this happens I don't know
	  tempLo =lightR				
	 endif	
	tempLo =tempLo -lightR *256 /tempLo	'scale
	sertxd("eR",#tempLo)
	if tempLo<objthresh then EwhiskerL	'ignore
	'now do memory
	peek obstaclesR,tempLo
	tempLo =tempLo +obs max obs
	poke obstaclesR,tempLo		'update memory
	
EwhiskerL:
	readadc c.1,lightL		'withLEDoff
	low eyeLedL_			'eyeL on
	readadc c.1,tempHi		'withLEDon
	high  eyeLedL_			'eyeL off
	if lightL>tempHi then		'why this happens I don't know
	  tempHi =lightL				
	 endif	
	tempHi =tempHi -lightL *256 /tempHi		'scale
	sertxd("eL",#tempHi,cr)
	if tempHi<objthresh then Qwalk		'ignore
	'now do memory
	peek obstaclesL,tempHi
	tempHi =tempHi +obs max obs
	poke obstaclesL,tempHi	'update memory

Qwalk:	
	irin [50,Walkabout],iIRin,cmnd	'irin with timeout, no IR =>Walkabout
	goto start                    	'QUIT if IRin
'=================================================================
'Behaviours
'----------
B_fast:
	rollspeed =3
	pacespeed =6
	return
	
B_turn:	
	rollspeed =1	'slow so foot doesn't bounce
	pacespeed =5 
	return	
'=================================================================
'Acts
'----

RockAdo:	'#128
	if f_defaultB=1 then gosub B_fast
	for iA=1 to Ado  
 	  gosub _rollR
	  gosub _rollL
	 next iA 
	gosub Stand 
	return
	
FdAdo:
	for iA=1 to Ado 
	  gosub Fd
	 next iA 
	return
	
BkAdo:
	for iA=1 to Ado 
	  gosub Bk
	 next iA 
	return

Rest:
	gosub _rollL
	gosub _iStand
	pwmout eyeLedR_,100,400 'active low so high Dutycycle for dim
	pwmout eyeLedL_,100,400 'active low so high Dutycycle for dim
_RestIRwait:
	high VoiceLed_
	irin iIRin,cmnd				'irin with no timeout
	gosub beep50            		'so we know IR received
	if cmnd=KEY_POWER then _RestIRwait	'wait until different IRcmnd
	pwmout eyeLedR_,off	
	pwmout eyeLedL_,off
	return
	
'=================================================================
'Actions
'-------

Fd:
sertxd ("Fd")
	f_direction =1
	if f_defaultB=1 then gosub B_fast
	if paceat<paceC then _FdL 'else _FdL
_FdR:
'sertxd ("_FdR")
	gosub _rollL
	gosub _RF
	gosub Stand
	return
_FdL:
'sertxd ("_FdL")
	gosub _rollR
	gosub _LF
	gosub Stand
	return
'-----------------------------------------
Bk:
sertxd ("Bk")
	f_direction =0
	if f_defaultB=1 then gosub B_fast
	if paceat<paceC then _BkR 'else _BkL
_BkL:
	gosub _rollR
	gosub _RF
	gosub Stand
	return
_BkR:
	gosub _rollL
	gosub _LF
	gosub Stand
	return
'-----------------------------------------
Rt:
sertxd ("Rt")
	if paceat<paceC and f_direction=1 then gosub Fd	'need left foot forward
	if paceat<paceC and f_direction=0 then gosub Bk	'need left foot forward
	if f_defaultB=1 then gosub beep150
	if f_defaultB=1 then gosub B_turn
	gosub _RF
	return
'-----------------------------------------
Lt:
sertxd ("Lt")
	if paceat>paceC and f_direction=1 then gosub Fd	'need right foot forward
	if paceat>paceC and f_direction=0 then gosub Bk	'need right foot forward
	if f_defaultB=1 then gosub beep150
	if f_defaultB=1 then gosub B_turn
	gosub _LF
	return
'=================================================================
_RF:
'sertxd ("_RF")
	paceto =paceC -paceby
	for spulse=paceat to paceto step -pacespeed
	  paceat =spulse
	  pulsout servoroll,rollat	'pulse servo hold in position
	  pulsout servopace,paceat	'pulse servo
	  pause sframe
	 next spulse
	return 
_LF:
'sertxd ("_LF")
	paceto =paceC +paceby
	for spulse=paceat to paceto step pacespeed
	  paceat =spulse
	  pulsout servoroll,rollat	'pulse servo hold in position
	  pulsout servopace,paceat	'pulse servo
	  pause sframe
	 next spulse
	return 
'-----------------------------------------
Stand:	'stand with both feet flat
'sertxd (" Sd")
	if rollat<rollC then _StandR 'else _StandL
_StandL:
'sertxd ("_SL")
	for spulse=rollat to rollC step -rollspeed
	  rollat =spulse
	  pulsout servoroll,rollat	'pulse servo
	  pulsout servopace,paceat	'pulse servo hold in position
	  pause sframe
	 next spulse
	return 
_StandR:
'sertxd ("_SR")
	for spulse=rollat to rollC step rollspeed
	  rollat =spulse
	  pulsout servoroll,rollat	'pulse servo
	  pulsout servopace,paceat	'pulse servo hold in position
	  pause sframe
	 next spulse
	return 
'-----------------------------------------
_rollL:
'sertxd ("_rL")
	rollto =rollC -rollby
	for spulse=rollat to rollto step -rollspeed
	  rollat =spulse
	  pulsout servoroll,rollat	'pulse servo
	  pulsout servopace,paceat	'pulse servo hold in position
	  pause sframe
	 next spulse
	return 
	 
_rollR:
'sertxd ("_rR")
	rollto =rollC +rollby
	for Spulse=rollat to rollto step rollspeed
	  rollat =spulse
	  pulsout servoroll,rollat	'pulse servo
	  pulsout servopace,paceat	'pulse servo hold in position
	  pause sframe
	 next spulse
	return 
'-----------------------------------------
_iStand:
'initialise with feet in mid position
	for spulse=0 to 10
	  pulsout servopace,paceC	'pulse servo paceC
	  pulsout servoroll,rollC	'pulse servo rollC
	  pause 70			'pause 70ms - do it slowly
	 next spulse
	rollat =rollC
	paceat =paceC 
	return 
'-----------------------------------------
badkey:
	high eyeLedR_
	pause 100
	low eyeLedR_
	high eyeLedL_
	pause 100
	low eyeLedL_
	return

beep50:
	sound VoiceLed_,(50,10)
	return

beep150:
	sound VoiceLed_,(150,10)
	return

EyesOFF:
	high eyeLedR_
	high eyeLedL_
	return
	
EyesON:
	low eyeLedR_
	low eyeLedL_
	return
	
IRgetAct_cmnd:	  	
	irin iIRin,cmnd			'key1 - key8 => 0-7
	if cmnd<8 then _IRgetActEnd
	gosub badkey
	goto IRgetAct_cmnd		'repeat until valid act		
_IRgetActEnd:
	gosub beep50	
	return 
	
nokey:
	irin [50,_nokeyend],iIRin,cmnd	'irin timeout =>reurn
	goto nokey
_nokeyend:
	return	
	
'=================================================================

[page top]

'Bambino-26
Sertxd("B26",cr)		'report program number @4800

#PicAxe 20M2
#no_data
'1573 bytes used
'PICAXE            IC   Memory   ext  I/O   Outputs  Inputs  ADC  Memory                        Starts  Polled  Resonator
' £   Type        pins  bytes    slot pins                        Vars. RAM Spad Data     Table*        Int.    def. opt. 
'2.28 PICAXE-20M2  20    2k           18    1-16     1-17     4    28   512      256      512   8       Yes      4   -32

'PICAXE-20M2 circuit board with LEDs off takes 1mA
'PICAXE-20M2 circuit board with LEDs off and servos connected takes 10mA


'Bambino-01	 'Test eyeLEDs, whiskerLEDs and speaker
'Bambino-02	 'Test InfraRed input
'Bambino-02a 'Test Eye light values
'Bambino-02b 'Test Whisker light values
'Bambino-03	 'Play the inbuilt tunes using keys 1 to 4 and beep on 5
'Bambino-04	 'Set servos to mid position	
'Bambino-05	 'Calibrate servo mid positions and put values in EEPROM.
'Bambino-06	 'Introduce _iStand:- initialise with feet in mid position
'Bambino-07	 'Set rollR
'Bambino-08	 'Set rollL
'Bambino-09	 'Check rollR, rollL
'Bambino-10	 'Introduction of _Stand
'Bambino-11	 'Investigate effect of rollspeed;	watch roll for all three speeds
'Bambino-12	 'Investigate effect of rollspeed;	watch Roll and Stand for all three speeds
'Bambino-13	 'Check paceFL paceFR;	Investigate effect of pacespeed
'Bambino-14	 'Check Fd
'Bambino-15	 'Test Rt, Lt
'Bambino-15a 'Test T2L Turn to Light, T2D Turn to Dark
'Bambino-16	 'Test Bk
'Bambino-17	 'Creaton of sections ACTIONS, BEHAVIOURS, ACTS;
            	'Introduction of ACT parameter 'Ado'
'Bambino-17a 'Demo routine            	
'Bambino-18	 'Walk Fd with obstacle avoidance using eyes from 02a
'Bambino-18a 'Walk Fd with drop-off avoidance using whiskers values from 02b
'Bambino-18b 'rewritten with autocalibration of down whiskers and reading of whiskers as subroutines
'Bambino-19	 'If IR command then do it otherwise walk and avoid
'Bambino-20	 'rewrite to incorporate rollC and paceC in EEPROM 254,255
'Bambino-21	 'rewrite to clearer code
'Bambino-22  'remember a sequence of keys presses          
'Bambino-23  'remember up to 8 sequence of keys presses in RAM          
'Bambino-24  'remember up to 8 sequence of keys presses in EEPROM          
'Bambino-25  'obstacle map made deeper and put in RAM for better obstacle avoidance
'Bambino-26  'incorporate drop-off avoidance from 18b 
            	
'-----------------------------------------------------------------            	
'modified
'--------
'Walkabout:
'obs changed to mobs		'memory increment for obstacle
'QEwhiskerL:
'QEwhiskerR:
'
'New
'---
'tempHi_wL
'tempLo_wR
'mob        	'memory increment for obstacle
'mobs       	'memory max for obstacle
'mhole		'memory increment for hole
'mholes		'memory max  for hole
'QGwhiskerL:	Query Ground whisker Left
'QGwhiskerR:	Query Ground whisker Right
'whiskerL	renamed GwhiskerL		for Ground whisker Left
'whiskerR	renamed GwhiskerR		for Ground whisker Right
'=================================================================
'[KEY_BAR] enters learn mode
'[KEY_BAR] has to be followed by a number key 1-8 
'	= the Act to be remembered
'up to 8 Acts can be learned
'learned Acts can call coded Acts
'a learned Act which chains itself repeats forever, eg #1 = Fd,1
'Acts can chain to other Acts, eg Fd,Bk,2   - chain to Act2
'[KEY_POWER] stops the playing Act.
'[KEY_TENT] selects coded Acts = subroutines,
'[KEY_TENT] has to be followed by a number key 1-8 
'	 [key1]=>RockAdo
'coded Acts play until the end.
'
'[KEY_XCROSS]			'Dump EEPROM DATA to PC

'When recording an Act, 
'	after [IRkey1],[IRkey2],[IRkey3],[IRkey4],[IRkey5],[IRkey6],[IRkey7],[IRkey8]
'	is used to chain another Act there is no point in recording more moves 
'	because they will never be replayed since control is transfered to the new Act,
'	just press [KEY_POWER] to end recording.
'NOTE do not record more than 30 moves for Act8 otherwise it will overwrite the servo calibration of RollC and PaceC
'=================================================================
'TVR010 PicAxe IR-controller
'---------------------------
'Before use, the transmitter must be programmed with the ‘Sony’ transmit code.
'1. Insert 2 AAA size batteries, preferably alkaline.
'2. Press ‘S’ and ‘B’ at the same time. S is in the centre of the arrows. 
'	The top left red LED should light.
'3. Press ‘0’. The LED should flash.
'4. Press ‘1’. The LED should flash.
'5. Press ‘3’. The LED should go out.
'6. Press the red power button (top right).
'-------------------------------------------
'IRin cmnds PicAxe controller
'DO NOT PRESS OTHER KEYS 
'ie [A] [B] [C] [D] [E] [F] [G] 
'They change the Mode and [B] has to be pressed to change back.
'[square] [triangle [()] [L] [X] [backwards F]  have no effect

Symbol KEY_POWER  = 21		'Sleep

Symbol KEY_UP     = 16		'Step Forward
Symbol KEY_DOWN   = 17		'Step Backward
Symbol KEY_RIGHT  = 18		'Turn Right
Symbol KEY_LEFT   = 19		'Turn Left

Symbol KEY_BAR    = 96		'learn an Act, next [key] selects a Act
Symbol KEY_TENT   = 54		'next [key] selects a Coded-Act
Symbol KEY_VERT_CROSS = 37	'use synonym for easier coding
Symbol KEY_VCROSS = 37
Symbol KEY_DIAG_CROSS = 20	'use synonym for easier coding
Symbol KEY_XCROSS = 20		'transfer EEPROM to PC for including in programs		'
					'Coded Acts		
symbol IRkey1     =  0		'		RockADo	
symbol IRkey2     =  1
symbol IRkey3     =  2
symbol IRkey4     =  3
symbol IRkey5     =  4
symbol IRkey6     =  5
symbol IRkey7     =  6
symbol IRkey8     =  7
symbol IRkey9     =  8
Symbol KEY_MINUS  = 98
Symbol KEY_0      =  9		'QUIT command mode
Symbol KEY_PLUS   = 11
'=================================================================
symbol servopace    =c.0	'left connector
symbol servoroll    =c.4	'right connector
symbol VoiceLed_    =c.5    	'low =>LED on 
symbol eyeLedL_     =c.2    	'low =>LED on 
symbol eyeLedR_     =b.1    	'low =>LED on
symbol eyeR         =c.7		  	
symbol eyeL         =c.1
symbol GwhiskerLedL_=c.3    	'low =>whisker LED on
symbol GwhiskerLedR_=b.3    	'low =>whisker LED on
symbol GwhiskerL    =b.6        'adc whisker Down Left		  	
symbol GwhiskerR    =b.0        'adc whisker Down Right		  	
symbol iIRin        =c.6
symbol oIRout       =b.2

symbol general 	  =b0
symbol temp0	  =b0
symbol flags	=w1
symbol B_flags      =b3
'symbol f_doIRcmnds  =bit29
symbol f_play	    =bit28	
symbol f_record	    =bit29
symbol f_direction    =bit30	'1=forwards, 0=backwards    
symbol f_defaultB     =bit31	'defaultBehaviour 1=use default
symbol servosAt	=w2
symbol  rollat 	  =b4
symbol  paceat 	  =b5
symbol ServosTo	=w3
symbol  rollTo	  =b6	   
symbol  paceTo	  =b7
symbol Smoveby	=w4
symbol  rollby	  =b8
symbol  paceby      =b9
symbol Scentre	=w5
symbol  rollC	  =b10
symbol  paceC       =b11
symbol Sspeed     =w6
symbol  rollspeed   =b12  '4 is too fast, 0 won't move
symbol  pacespeed   =b13  '6 is about max for servos to keep up
symbol counters	=w7
symbol  spulse 	  =b14
symbol  iA 		  =b15
symbol  i 		  =b15	'calibrateholewhiskers:	
symbol tempw       =w8
symbol  tempLo      =b16
symbol  tempLo_wR   =b16	'whisker Right
symbol  tempLo_wRg  =b16	'whisker Right Ground
symbol  tempHi      =b17
symbol  tempHi_wL   =b17	'whisker Left
symbol  tempHi_wLg  =b17	'whisker Left Ground 

symbol sframe     =22	'time between servo pulses

symbol Ado		    =b18	'parameter for ACTs
symbol obsmap     =b19  '%11 bitmap of obstacles  %LeftRight
symbol lightL     =b20  'light level Left
symbol lightR     =b21  'light level Right
symbol objthresh  =70   'light/dark whisker threshold for obstacle 
symbol cmnd	  =b22  'cmnd from IRremote
symbol Act        =b23
symbol Aend	   =b24	'end of record slot
symbol eptr       =b25	'pointer to EEPROM

'depending on the sensors obsdetectL and obsdetectR may need to be different
symbol obsdetectL	=120	'scaled light level difference for obstacle
symbol obsdetectR	=120	'scaled light level difference for obstacle

'if set in Program#18a then those values will be used, otherwise these values
'depending on the sensors holedetectL and holedetectR may need to be different
'default if not set in prog #18a, values so Bambino can see table edges
symbol holedetectL=120	'scaled light level difference for holes
symbol holedetectR=120	'scaled light level difference for holes

symbol EEholedetectR =252
symbol EEholedetectL =253
symbol EErollC       =254
symbol EEpaceC       =255

'EEPROM Acts
symbol act0	=0
symbol act1	=32 
symbol act2	=32 *2
symbol act3	=32 *3 
symbol act4	=32 *4
symbol act5	=32 *5
symbol act6	=32 *6
symbol act7	=32 *7
symbol act8	=32 *8

'for Act=act1 to act8
'	poke Act,255	'set stop markers	
'  next Act	


symbol obstaclesR =32	'RAM
symbol obstaclesL =33	'RAM
symbol mob        =6'8	'memory increment  for obstacle
symbol mobs       =8	'memory increment  for obstacle
symbol mhole	=4	'memory increment  for hole
symbol mholes	=8	'memory max  for hole
'=================================================================
initialise:
	rollby    =15	'+ve right 
	paceby    =20	'+ve Left  foot forward
	rollspeed =1  	'4 is too fast, 0 won't move
	pacespeed =2   	'6 is about max for servos to keep up  
	rollC	    =150	'Default, 100 is roll to the left
	paceC	    =150	'Default, 100 is left foot back
	'get values from EEPROM if set by program #5
	read EErollC,temp0
	if temp0>130 and temp0<170 then	'so servo is always between 100,200
	  rollC =temp0
	 endif 
	read EEpaceC,temp0
	if temp0>130 and temp0<170 then	'so servo is always between 100,200
	  paceC =temp0
	 endif 
	sertxd("rollC=",#rollC," paceC=",#paceC,cr)
	 
'	'get hole detect values from EEPROM if set by program #18a
'	read EEholedetectL,temp0		
'	if temp0=255 then
'	  write EEholedetectL,holedetectL
'	 endif 
'	read EEholedetectR,temp0
'	if temp0=255 then
'	  write EEholedetectR,holedetectR
'	 endif 
	gosub calibrateholewhiskers
	 
	low eyeLedR_	'make output LED on
	low eyeLedL_	'make output LED on
	gosub _iStand
	f_defaultB =1	'defaultBehaviour On
	f_record =0

start:
sertxd("S")
	Ado =4				'for RockAdo
	irin [50,Walkabout],iIRin,cmnd'irin with timeout, no IR =>Walkabout
	gosub beep50                  'so we know IR received
	goto DoCmnd
'=================================================================
'Activities
'----------
IRacty:
	sertxd("IR")
	irin iIRin,cmnd	 	'Get cmnd
	gosub beep50            'so we know IR received
DoCmnd:	
	sertxd(cr,#cmnd," @",#eptr)
	sertxd(" f_p",#f_play," f_r",#f_record,",")
		
	select cmnd
	  case KEY_POWER
	  	if f_record=0 and f_play=0 then
	  		gosub rest
			goto DoCmnd	'have already got IRcmnd in rest:
		   else
		      f_play =0
		      if f_record=1 then
		      	f_record =0
    	 			poke eptr,255	     'end marker
    	 		  endif	
 		 endif 
	  case KEY_UP
	  	gosub Fd
	  case KEY_DOWN
	  	gosub Bk
	  case KEY_RIGHT
	  	gosub Rt
	  case KEY_LEFT
	  	gosub Lt
	  case KEY_0
		goto Start			'QUIT and Wander

	  case <IRkey9			'Act keys 1-8 => Acts 0-7
	  	if f_record<>1 then
	  		f_play=1		'play
	  		eptr =32 *cmnd	'set to start
	  		sertxd(" play@",#eptr,cr)	 
		  endif

	  case KEY_BAR			'record
	  	f_play =0	
	  	f_record =1
		gosub IRgetAct_cmnd
		eptr =32 *cmnd
		Aend =eptr +31
		gosub nokey
	  	sertxd("rec@",#eptr,cr)
	  	goto IRacty	 		'get cmnds
	  	
	  case KEY_TENT			'coded acts
	  	gosub IRgetAct_cmnd
		cmnd =cmnd +128		'set topbit for coded Acts
		sertxd(" Act",#cmnd,cr)
		goto DoCmnd
		
	  case KEY_XCROSS			'Dump DATA to PC
		for Act=0 to 7
			sertxd(cr,lf,"'Act ",#Act,cr,lf,"DATA ")
			for eptr=0 to 30
				tempLo =Act *32 +eptr
				read tempLo,cmnd
				sertxd(#cmnd,",")
			  next eptr
			tempLo =Act *32 +31
			read tempLo,cmnd
			sertxd(#cmnd)
		  next Act
		sertxd(cr,lf)
		  	   
	  case >127				'do Coded Act subroutines
	  	sertxd("case >127",cr)	 
	    	Act =cmnd -128
	  	on Act gosub RockAdo	'add others
	  	
	  end select


'_record
	if f_record=1 then
		if eptr<Aend then
			write eptr,cmnd
			eptr =eptr +1
		 else				'end of slot
		 	gosub beep150
			cmnd =KEY_POWER	
			goto DoCmnd
		 endif	
	   endif

'_play:
	if f_play=1 then
		irin [50,_playon],iIRin,cmnd
		goto Start			'if IR received =>break		
_playon:		
	 	read eptr,cmnd
 		eptr =eptr +1
		if cmnd<>255 then	DoCmnd	'255=end
		f_play =0
	  endif
		
	goto IRacty				'get IR


	
'-----------------------------------------	
Walkabout:
sertxd(cr,"W")
	peek obstaclesR,tempLo	'read memory
	peek obstaclesL,tempHi	'read memory
	tempLo =tempLo min 1 -1 'decay memory
	tempHi =tempHi min 1 -1 'decay memory
	poke obstaclesR,tempLo	'save
	poke obstaclesL,tempHi	'save
	sertxd ("mem",#tempHi," ",#tempLo," ")

	obsmap =0			
  	if tempLo>0 then		'create short term memory map
  		obsmap =obsmap or %1
   	  endif
  	if tempHi>0 then
  		obsmap =obsmap or %10
   	  endif

	gosub B_fast
	'alter LEDs so we can tell what Bambino is doing
	b0 =obsmap 			'to use bits
	if bit0=0 then	
'		low eyeLedR_
	pwmout eyeLedR_,110,400 'active low so high Dutycycle for dim
	  endif 
	if bit1=0 then
'		low eyeLedL_
	pwmout eyeLedL_,110,400 'active low so high Dutycycle for dim
	  endif 

	'take avoiding action if necessary 
  	on obsmap gosub Fd,Lt,Rt,Bk 
	'otherwise fall through and test whiskers
	 
	pwmout eyeLedR_,off	
	pwmout eyeLedL_,off
'	gosub EyesOFF

	gosub QEwhiskerL
	gosub QEwhiskerR
	gosub QGwhiskerL
	gosub QGwhiskerR
	
Qwalk:	
	irin [50,Walkabout],iIRin,cmnd	'irin with timeout, no IR =>Walkabout
	goto start                    	'QUIT if IRin
'=================================================================
'Behaviours
'----------
B_fast:
	rollspeed =3
	pacespeed =6
	return
	
B_turn:	
	rollspeed =1	'slow so foot doesn't bounce
	pacespeed =5 
	return	
'=================================================================
'Acts
'----

RockAdo:	'#128
	if f_defaultB=1 then gosub B_fast
	for iA=1 to Ado  
 	  gosub _rollR
	  gosub _rollL
	 next iA 
	gosub Stand 
	return
	
FdAdo:
	for iA=1 to Ado 
	  gosub Fd
	 next iA 
	return
	
BkAdo:
	for iA=1 to Ado 
	  gosub Bk
	 next iA 
	return

Rest:
	gosub _rollL
	gosub _iStand
	pwmout eyeLedR_,100,400 'active low so high Dutycycle for dim
	pwmout eyeLedL_,100,400 'active low so high Dutycycle for dim
_RestIRwait:
	high VoiceLed_
	irin iIRin,cmnd				'irin with no timeout
	gosub beep50            		'so we know IR received
	if cmnd=KEY_POWER then _RestIRwait	'wait until different IRcmnd
	pwmout eyeLedR_,off	
	pwmout eyeLedL_,off
	gosub EyesOFF
	return
	
'=================================================================
'Actions
'-------

Fd:
sertxd ("Fd")
	f_direction =1
	if f_defaultB=1 then gosub B_fast
	if paceat<paceC then _FdL 'else _FdL
_FdR:
'sertxd ("_FdR")
	gosub _rollL
	gosub _RF
	gosub Stand
	return
_FdL:
'sertxd ("_FdL")
	gosub _rollR
	gosub _LF
	gosub Stand
	return
'-----------------------------------------
Bk:
sertxd ("Bk")
	f_direction =0
	if f_defaultB=1 then gosub B_fast
	if paceat<paceC then _BkR 'else _BkL
_BkL:
	gosub _rollR
	gosub _RF
	gosub Stand
	return
_BkR:
	gosub _rollL
	gosub _LF
	gosub Stand
	return
'-----------------------------------------
Rt:
sertxd ("Rt")
	if paceat<paceC and f_direction=1 then gosub Fd	'need left foot forward
	if paceat<paceC and f_direction=0 then gosub Bk	'need left foot forward
	if f_defaultB=1 then gosub beep150
	if f_defaultB=1 then gosub B_turn
	gosub _RF
	return
'-----------------------------------------
Lt:
sertxd ("Lt")
	if paceat>paceC and f_direction=1 then gosub Fd	'need right foot forward
	if paceat>paceC and f_direction=0 then gosub Bk	'need right foot forward
	if f_defaultB=1 then gosub beep150
	if f_defaultB=1 then gosub B_turn
	gosub _LF
	return
'=================================================================
_RF:
'sertxd ("_RF")
	paceto =paceC -paceby
	for spulse=paceat to paceto step -pacespeed
	  paceat =spulse
	  pulsout servoroll,rollat	'pulse servo hold in position
	  pulsout servopace,paceat	'pulse servo
	  pause sframe
	 next spulse
	return 
_LF:
'sertxd ("_LF")
	paceto =paceC +paceby
	for spulse=paceat to paceto step pacespeed
	  paceat =spulse
	  pulsout servoroll,rollat	'pulse servo hold in position
	  pulsout servopace,paceat	'pulse servo
	  pause sframe
	 next spulse
	return 
'-----------------------------------------
Stand:	'stand with both feet flat
'sertxd (" Sd")
	if rollat<rollC then _StandR 'else _StandL
_StandL:
'sertxd ("_SL")
	for spulse=rollat to rollC step -rollspeed
	  rollat =spulse
	  pulsout servoroll,rollat	'pulse servo
	  pulsout servopace,paceat	'pulse servo hold in position
	  pause sframe
	 next spulse
	return 
_StandR:
'sertxd ("_SR")
	for spulse=rollat to rollC step rollspeed
	  rollat =spulse
	  pulsout servoroll,rollat	'pulse servo
	  pulsout servopace,paceat	'pulse servo hold in position
	  pause sframe
	 next spulse
	return 
'-----------------------------------------
_rollL:
'sertxd ("_rL")
	rollto =rollC -rollby
	for spulse=rollat to rollto step -rollspeed
	  rollat =spulse
	  pulsout servoroll,rollat	'pulse servo
	  pulsout servopace,paceat	'pulse servo hold in position
	  pause sframe
	 next spulse
	return 
	 
_rollR:
'sertxd ("_rR")
	rollto =rollC +rollby
	for Spulse=rollat to rollto step rollspeed
	  rollat =spulse
	  pulsout servoroll,rollat	'pulse servo
	  pulsout servopace,paceat	'pulse servo hold in position
	  pause sframe
	 next spulse
	return 
'-----------------------------------------
_iStand:
'initialise with feet in mid position
	for spulse=0 to 10
	  pulsout servopace,paceC	'pulse servo paceC
	  pulsout servoroll,rollC	'pulse servo rollC
	  pause 70			'pause 70ms - do it slowly
	 next spulse
	rollat =rollC
	paceat =paceC 
	return 
'-----------------------------------------
'Sense
'-----
calibrateholewhiskers:
'take averages of 8 readings per whisker
	w8 =0	'clear tempHi,tempLo
	low GwhiskerLedL_			'eyeL on
	for i=0 to 7
'		low whiskerLedL_		'eyeL on
		readadc GwhiskerL,temp0
'		high whiskerLedL_		'eyeL off		
		sertxd("L",#temp0)
		temp0 =temp0 /8
		tempHi_wLg =tempHi_wLg +temp0
		sertxd(" ",#tempHi_wLg,cr)
	  next i	
	high GwhiskerLedL_			'eyeL off
	low GwhiskerLedR_			'eyeL on
	for i=0 to 7
'		low whiskerLedR_		'eyeL on
		readadc GwhiskerR,temp0
'		high whiskerLedR_		'eyeL off
		sertxd("R",#temp0)
		temp0 =temp0 /8
		tempLo_wRg =tempLo_wRg +temp0
		sertxd(" ",#tempLo_wRg,cr)
	  next i	
	high GwhiskerLedR_			'eyeL off
'set threshold at 60%
	tempHi_wLg =tempHi_wLg *3 /5
	tempLo_wRg =tempLo_wRg *3 /5
  sertxd("holethresh L",#tempHi_wLg," R",#tempLo_wRg,cr)
	write EEholedetectL,tempHi_wLg
	write EEholedetectR,tempLo_wRg
	return 

QEwhiskerL:
	low eyeLedL_			'LeyeLED on
	readadc c.1,tempHi_wL		'withLEDon
	high  eyeLedL_			'LeyeLED off
	readadc c.1,lightL		'ambient light
	if lightL>tempHi_wL then	'why this happens I don't know
		lightL =tempHi_wL
	  endif	
	tempHi_wL =tempHi_wL -lightL *256 /tempHi_wL	'scale
  sertxd(cr,"eL",#tempHi_wL)
	if tempHi_wL>objthresh then	'obstacle so update obstacles memory
		peek obstaclesL,temp0
		temp0 =temp0 +mob max mobs
		poke obstaclesL,temp0
	  endif	
	return 

QEwhiskerR:
	low eyeLedR_			'ReyeLED on
	readadc c.7,tempLo_wR		'withLEDon
	high  eyeLedR_			'ReyeLED off
	readadc c.7,lightR		'ambient light
	if lightR>tempLo_wR then	'why this happens I don't know
		lightR =tempLo_wR
	  endif	
	tempLo_wR =tempLo_wR -lightR *256 /tempLo_wR	'scale
  sertxd(" eR",#tempLo_wR)
	if tempLo_wR>objthresh then	'obstacle so update obstacles memory
		peek obstaclesR,temp0
		temp0 =temp0 +mob max mobs
		poke obstaclesR,temp0
	  endif
	return 

QGwhiskerL:
	low GwhiskerLedL_		'LwLED on
	readadc GwhiskerL,tempHi_wLg	'withLEDon
	high GwhiskerLedL_		'LwLED off
	readadc GwhiskerL,lightL	'ambient light
	if lightL>tempHi_wLg then	'why this happens I don't know
		 lightL =tempHi_wLg	
	  endif	
	read EEholedetectL,temp0
	if tempHi_wLg<temp0 then 	'a hole, no ground detected so update obstacles memory
		peek obstaclesL,temp0
		temp0 =temp0 +mhole max mholes
		poke obstaclesL,temp0
	  endif
sertxd(cr,"wL",#tempHi_wLg)  
	return 

QGwhiskerR:
	low GwhiskerLedR_		'RwLED on
	readadc GwhiskerR,tempLo_wRg	'withLEDon
	high  GwhiskerLedR_		'RwLED off
	readadc GwhiskerR,lightR	'ambient light
	if lightR>tempLo_wRg then	'why this happens I don't know
		 lightL =tempLo_wRg	
	  endif	
	read EEholedetectR,temp0
	if tempLo_wRg<temp0 then 	'a hole, no ground detected so update obstacles memory
		peek obstaclesR,temp0
		temp0 =temp0 +mhole max mholes
		poke obstaclesR,temp0
	  endif
  sertxd(" wR",#tempLo_wRg)
	return 
'-----------------------------------------
badkey:
	high eyeLedR_
	pause 100
	low eyeLedR_
	high eyeLedL_
	pause 100
	low eyeLedL_
	return

beep50:
	sound VoiceLed_,(50,10)
	return

beep150:
	sound VoiceLed_,(150,10)
	return

EyesOFF:
	high eyeLedR_
	high eyeLedL_
	return
	
EyesON:
	low eyeLedR_
	low eyeLedL_
	return
	
IRgetAct_cmnd:	  	
	irin iIRin,cmnd		'key1 - key8 => 0-7
	if cmnd<8 then _IRgetActEnd
	gosub badkey
	goto IRgetAct_cmnd	'repeat until valid act		
_IRgetActEnd:
	gosub beep50	
	return 
	
nokey:
	irin [50,_nokeyend],iIRin,cmnd'irin timeout =>return
	goto nokey
_nokeyend:
	return	
	
'=================================================================

[page top]

'Bambino-27
Sertxd("B27",cr)		'report program number @4800

#PicAxe 20M2
#no_data
'1599 bytes used
'PICAXE            IC   Memory   ext  I/O   Outputs  Inputs  ADC  Memory                        Starts  Polled  Resonator
' £   Type        pins  bytes    slot pins                        Vars. RAM Spad Data     Table*        Int.    def. opt. 
'2.28 PICAXE-20M2  20    2k           18    1-16     1-17     4    28   512      256      512   8       Yes      4   -32

'PICAXE-20M2 circuit board with LEDs off takes 1mA
'PICAXE-20M2 circuit board with LEDs off and servos connected takes 10mA


'Bambino-01	 'Test eyeLEDs, whiskerLEDs and speaker
'Bambino-02	 'Test InfraRed input
'Bambino-02a     'Test Eye light values
'Bambino-02b     'Test Whisker light values
'Bambino-03	 'Play the inbuilt tunes using keys 1 to 4 and beep on 5
'Bambino-04	 'Set servos to mid position	
'Bambino-05	 'Calibrate servo mid positions and put values in EEPROM.
'Bambino-06	 'Introduce _iStand:- initialise with feet in mid position
'Bambino-07	 'Set rollR
'Bambino-08	 'Set rollL
'Bambino-09	 'Check rollR, rollL
'Bambino-10	 'Introduction of _Stand
'Bambino-11	 'Investigate effect of rollspeed;	watch roll for all three speeds
'Bambino-12	 'Investigate effect of rollspeed;	watch Roll and Stand for all three speeds
'Bambino-13	 'Check paceFL paceFR;	Investigate effect of pacespeed
'Bambino-14	 'Check Fd
'Bambino-15	 'Test Rt, Lt
'Bambino-15a     'Test T2L Turn to Light, T2D Turn to Dark
'Bambino-16	 'Test Bk
'Bambino-17	 'Creaton of sections ACTIONS, BEHAVIOURS, ACTS;
            	'Introduction of ACT parameter 'Ado'
'Bambino-17a    'Demo routine            	
'Bambino-18	 'Walk Fd with obstacle avoidance using eyes from 02a
'Bambino-18a     'Walk Fd with drop-off avoidance using whiskers values from 02b
'Bambino-18b     'rewritten with autocalibration of down whiskers and reading of whiskers as subroutines
'Bambino-19	 'If IR command then do it otherwise walk and avoid
'Bambino-20	 'rewrite to incorporate rollC and paceC in EEPROM 254,255
'Bambino-21	 'rewrite to clearer code
'Bambino-22  'remember a sequence of keys presses          
'Bambino-23  'remember up to 8 sequence of keys presses in RAM          
'Bambino-24  'remember up to 8 sequence of keys presses in EEPROM          
'Bambino-25  'obstacle map made deeper and put in RAM for better obstacle avoidance
'Bambino-26  'incorporate drop-off avoidance from 18b
'Bambino-27  'map increment  on hole split into mholeB & mholeT to enable backup & Turn 	
			'otherwise Bambino turns and falls sideways off an edge.
'-----------------------------------------------------------------            	
'modified
'--------
'QGwhiskerL:
'QGwhiskerR:
'
'New
'---
'mholeT		'memory increment for hole turn
'mholeB		'memory increment for hole back
'=================================================================
'[KEY_BAR] enters learn mode
'[KEY_BAR] has to be followed by a number key 1-8 
'	= the Act to be remembered
'up to 8 Acts can be learned
'learned Acts can call coded Acts
'a learned Act which chains itself repeats forever, eg #1 = Fd,1
'Acts can chain to other Acts, eg Fd,Bk,2   - chain to Act2
'[KEY_POWER] stops the playing Act.
'[KEY_TENT] selects coded Acts = subroutines,
'[KEY_TENT] has to be followed by a number key 1-8 
'	 [key1]=>RockAdo
'coded Acts play until the end.
'
'[KEY_XCROSS]			'Dump EEPROM DATA to PC

'When recording an Act, 
'	after [IRkey1],[IRkey2],[IRkey3],[IRkey4],[IRkey5],[IRkey6],[IRkey7],[IRkey8]
'	is used to chain another Act there is no point in recording more moves 
'	because they will never be replayed since control is transfered to the new Act,
'	just press [KEY_POWER] to end recording.
'NOTE do not record more than 30 moves for Act8 otherwise it will overwrite the servo calibration of RollC and PaceC
'=================================================================
'TVR010 PicAxe IR-controller
'---------------------------
'Before use, the transmitter must be programmed with the ‘Sony’ transmit code.
'1. Insert 2 AAA size batteries, preferably alkaline.
'2. Press ‘S’ and ‘B’ at the same time. S is in the centre of the arrows. 
'	The top left red LED should light.
'3. Press ‘0’. The LED should flash.
'4. Press ‘1’. The LED should flash.
'5. Press ‘3’. The LED should go out.
'6. Press the red power button (top right).
'-------------------------------------------
'IRin cmnds PicAxe controller
'DO NOT PRESS OTHER KEYS 
'ie [A] [B] [C] [D] [E] [F] [G] 
'They change the Mode and [B] has to be pressed to change back.
'[square] [triangle [()] [L] [X] [backwards F]  have no effect

Symbol KEY_POWER  = 21		'Sleep

Symbol KEY_UP     = 16		'Step Forward
Symbol KEY_DOWN   = 17		'Step Backward
Symbol KEY_RIGHT  = 18		'Turn Right
Symbol KEY_LEFT   = 19		'Turn Left

Symbol KEY_BAR    = 96		'learn an Act, next [key] selects a Act
Symbol KEY_TENT   = 54		'next [key] selects a Coded-Act
Symbol KEY_VERT_CROSS = 37	'use synonym for easier coding
Symbol KEY_VCROSS = 37
Symbol KEY_DIAG_CROSS = 20	'use synonym for easier coding
Symbol KEY_XCROSS = 20		'transfer EEPROM to PC for including in programs		'
					'Coded Acts		
symbol IRkey1     =  0		'	RockADo	
symbol IRkey2     =  1
symbol IRkey3     =  2
symbol IRkey4     =  3
symbol IRkey5     =  4
symbol IRkey6     =  5
symbol IRkey7     =  6
symbol IRkey8     =  7
symbol IRkey9     =  8
Symbol KEY_MINUS  = 98
Symbol KEY_0      =  9		'QUIT command mode
Symbol KEY_PLUS   = 11
'=================================================================
symbol servopace    =c.0	'left connector
symbol servoroll    =c.4	'right connector
symbol VoiceLed_    =c.5    	'low =>LED on 
symbol eyeLedL_     =c.2    	'low =>LED on 
symbol eyeLedR_     =b.1    	'low =>LED on
symbol eyeR         =c.7		  	
symbol eyeL         =c.1
symbol GwhiskerLedL_=c.3    	'low =>whisker LED on
symbol GwhiskerLedR_=b.3    	'low =>whisker LED on
symbol GwhiskerL    =b.6      'adc whisker Down Left		  	
symbol GwhiskerR    =b.0      'adc whisker Down Right		  	
symbol iIRin        =c.6
symbol oIRout       =b.2

symbol general 	   =b0
symbol temp0	   =b0
symbol flags	  =w1
symbol B_flags     =b3
'symbol f_doIRcmnds =bit29
symbol f_play	    =bit28	
symbol f_record	    =bit29
symbol f_direction  =bit30	'1=forwards, 0=backwards    
symbol f_defaultB   =bit31	'defaultBehaviour 1=use default
symbol servosAt	  =w2
symbol  rollat 	   =b4
symbol  paceat 	   =b5
symbol ServosTo	  =w3
symbol  rollTo	   =b6	   
symbol  paceTo	   =b7
symbol Smoveby	  =w4
symbol  rollby	   =b8
symbol  paceby     =b9
symbol Scentre	  =w5
symbol  rollC	   =b10
symbol  paceC       =b11
symbol Sspeed      =w6
symbol  rollspeed   =b12  '4 is too fast, 0 won't move
symbol  pacespeed   =b13  '6 is about max for servos to keep up
symbol counters	   =w7
symbol  spulse 	    =b14
symbol  iA 	    =b15
symbol  i 	    =b15	'calibrateholewhiskers:	
symbol tempw       =w8
symbol  tempLo      =b16
symbol  tempLo_wR   =b16	'whisker Right
symbol  tempLo_wRg  =b16	'whisker Right Ground
symbol  tempHi      =b17
symbol  tempHi_wL   =b17	'whisker Left
symbol  tempHi_wLg  =b17	'whisker Left Ground 

symbol sframe     =22	'time between servo pulses

symbol Ado		    =b18	'parameter for ACTs
symbol obsmap     =b19  '%11 bitmap of obstacles  %LeftRight
symbol lightL     =b20  'light level Left
symbol lightR     =b21  'light level Right
symbol objthresh  =70   'light/dark whisker threshold for obstacle 
symbol cmnd	  =b22  'cmnd from IRremote
symbol Act        =b23
symbol Aend		    =b24	'end of record slot
symbol eptr       =b25	'pointer to EEPROM

'depending on the sensors obsdetectL and obsdetectR may need to be different
symbol obsdetectL	=120	'scaled light level difference for obstacle
symbol obsdetectR	=120	'scaled light level difference for obstacle

'if set in Program#18a then those values will be used, otherwise these values
'depending on the sensors holedetectL and holedetectR may need to be different
'default if not set in prog #18a, values so Bambino can see table edges
symbol holedetectL=120	'scaled light level difference for holes
symbol holedetectR=120	'scaled light level difference for holes

symbol EEholedetectR =252
symbol EEholedetectL =253
symbol EErollC       =254
symbol EEpaceC       =255

'EEPROM Acts
symbol act0	=0
symbol act1	=32 
symbol act2	=32 *2
symbol act3	=32 *3 
symbol act4	=32 *4
symbol act5	=32 *5
symbol act6	=32 *6
symbol act7	=32 *7
symbol act8	=32 *8

'for Act=act1 to act8
'	poke Act,255	'set stop markers	
'  next Act	


symbol obstaclesR =32	'RAM
symbol obstaclesL =33	'RAM
symbol mob        =6'8	'memory increment  for obstacle
symbol mobs       =8	'memory increment  for obstacle
symbol mholeT	=4	'memory increment  for hole turn
symbol mholeB	=2	'memory increment  for hole back
symbol mholes	=8	'memory max  for hole
'=================================================================
initialise:
	rollby    =15	'+ve right 
	paceby    =20	'+ve Left  foot forward
	rollspeed =1  	'4 is too fast, 0 won't move
	pacespeed =2   	'6 is about max for servos to keep up  
	rollC	    =150	'Default, 100 is roll to the left
	paceC	    =150	'Default, 100 is left foot back
	'get values from EEPROM if set by program #5
	read EErollC,temp0
	if temp0>130 and temp0<170 then	'so servo is always between 100,200
	  rollC =temp0
	 endif 
	read EEpaceC,temp0
	if temp0>130 and temp0<170 then	'so servo is always between 100,200
	  paceC =temp0
	 endif 
	sertxd("rollC=",#rollC," paceC=",#paceC,cr)
	 
'	'get hole detect values from EEPROM if set by program #18a
'	read EEholedetectL,temp0		
'	if temp0=255 then
'	  write EEholedetectL,holedetectL
'	 endif 
'	read EEholedetectR,temp0
'	if temp0=255 then
'	  write EEholedetectR,holedetectR
'	 endif 
	gosub calibrateholewhiskers
	 
	low eyeLedR_	'make output LED on
	low eyeLedL_	'make output LED on
	gosub _iStand
	f_defaultB =1	'defaultBehaviour On
	f_record =0

start:
sertxd("S")
	Ado =4				'for RockAdo
	irin [50,Walkabout],iIRin,cmnd'irin with timeout, no IR =>Walkabout
	gosub beep50                  'so we know IR received
	goto DoCmnd
'=================================================================
'Activities
'----------
IRacty:
	sertxd("IR")
	irin iIRin,cmnd	 	'Get cmnd
	gosub beep50            'so we know IR received
DoCmnd:	
	sertxd(cr,#cmnd," @",#eptr)
	sertxd(" f_p",#f_play," f_r",#f_record,",")
		
	select cmnd
	  case KEY_POWER
	  	if f_record=0 and f_play=0 then
	  		gosub rest
			goto DoCmnd	'have already got IRcmnd in rest:
		   else
		      f_play =0
		      if f_record=1 then
		      	f_record =0
    	 			poke eptr,255	     'end marker
    	 		  endif	
 		 endif 
	  case KEY_UP
	  	gosub Fd
	  case KEY_DOWN
	  	gosub Bk
	  case KEY_RIGHT
	  	gosub Rt
	  case KEY_LEFT
	  	gosub Lt
	  case KEY_0
		goto Start			'QUIT and Wander

	  case <IRkey9			'Act keys 1-8 => Acts 0-7
	  	if f_record<>1 then
	  		f_play=1		'play
	  		eptr =32 *cmnd	'set to start
	  		sertxd(" play@",#eptr,cr)	 
		  endif

	  case KEY_BAR			'record
	  	f_play =0	
	  	f_record =1
		gosub IRgetAct_cmnd
		eptr =32 *cmnd
		Aend =eptr +31
		gosub nokey
	  	sertxd("rec@",#eptr,cr)
	  	goto IRacty	 		'get cmnds
	  	
	  case KEY_TENT			'coded acts
	  	gosub IRgetAct_cmnd
		cmnd =cmnd +128		'set topbit for coded Acts
		sertxd(" Act",#cmnd,cr)
		goto DoCmnd
		
	  case KEY_XCROSS			'Dump DATA to PC
		for Act=0 to 7
			sertxd(cr,lf,"'Act ",#Act,cr,lf,"DATA ")
			for eptr=0 to 30
				tempLo =Act *32 +eptr
				read tempLo,cmnd
				sertxd(#cmnd,",")
			  next eptr
			tempLo =Act *32 +31
			read tempLo,cmnd
			sertxd(#cmnd)
		  next Act
		sertxd(cr,lf)
		  	   
	  case >127				'do Coded Act subroutines
	  	sertxd("case >127",cr)	 
	    	Act =cmnd -128
	  	on Act gosub RockAdo	'add others
	  	
	  end select


'_record
	if f_record=1 then
		if eptr<Aend then
			write eptr,cmnd
			eptr =eptr +1
		 else				'end of slot
		 	gosub beep150
			cmnd =KEY_POWER	
			goto DoCmnd
		 endif	
	   endif

'_play:
	if f_play=1 then
		irin [50,_playon],iIRin,cmnd
		goto Start			'if IR received =>break		
_playon:		
	 	read eptr,cmnd
 		eptr =eptr +1
		if cmnd<>255 then	DoCmnd	'255=end
		f_play =0
	  endif
		
	goto IRacty				'get IR


	
'-----------------------------------------	
Walkabout:
sertxd(cr,"W")
	peek obstaclesR,tempLo	'read memory
	peek obstaclesL,tempHi	'read memory
	tempLo =tempLo min 1 -1 'decay memory
	tempHi =tempHi min 1 -1 'decay memory
	poke obstaclesR,tempLo	'save
	poke obstaclesL,tempHi	'save
	sertxd ("mem",#tempHi," ",#tempLo," ")

	obsmap =0			
  	if tempLo>0 then		'create short term memory map
  		obsmap =obsmap or %1
   	  endif
  	if tempHi>0 then
  		obsmap =obsmap or %10
   	  endif

	gosub B_fast
	'alter LEDs so we can tell what Bambino is doing
	b0 =obsmap 			'to use bits
	if bit0=0 then	
'		low eyeLedR_
	pwmout eyeLedR_,110,400 'active low so high Dutycycle for dim
	  endif 
	if bit1=0 then
'		low eyeLedL_
	pwmout eyeLedL_,110,400 'active low so high Dutycycle for dim
	  endif 

	'take avoiding action if necessary 
  	on obsmap gosub Fd,Lt,Rt,Bk 
	'otherwise fall through and test whiskers
	 
	pwmout eyeLedR_,off	
	pwmout eyeLedL_,off
'	gosub EyesOFF

	gosub QEwhiskerL
	gosub QEwhiskerR
	gosub QGwhiskerL
	gosub QGwhiskerR
	
Qwalk:	
	irin [50,Walkabout],iIRin,cmnd	'irin with timeout, no IR =>Walkabout
	goto start                    	'QUIT if IRin
'=================================================================
'Behaviours
'----------
B_fast:
	rollspeed =3
	pacespeed =6
	return
	
B_turn:	
	rollspeed =1	'slow so foot doesn't bounce
	pacespeed =5 
	return	
'=================================================================
'Acts
'----

RockAdo:	'#128
	if f_defaultB=1 then gosub B_fast
	for iA=1 to Ado  
 	  gosub _rollR
	  gosub _rollL
	 next iA 
	gosub Stand 
	return
	
FdAdo:
	for iA=1 to Ado 
	  gosub Fd
	 next iA 
	return
	
BkAdo:
	for iA=1 to Ado 
	  gosub Bk
	 next iA 
	return

Rest:
	gosub _rollL
	gosub _iStand
	pwmout eyeLedR_,100,400 'active low so high Dutycycle for dim
	pwmout eyeLedL_,100,400 'active low so high Dutycycle for dim
_RestIRwait:
	high VoiceLed_
	irin iIRin,cmnd				'irin with no timeout
	gosub beep50            		'so we know IR received
	if cmnd=KEY_POWER then _RestIRwait	'wait until different IRcmnd
	pwmout eyeLedR_,off	
	pwmout eyeLedL_,off
	gosub EyesOFF
	return
	
'=================================================================
'Actions
'-------

Fd:
sertxd ("Fd")
	f_direction =1
	if f_defaultB=1 then gosub B_fast
	if paceat<paceC then _FdL 'else _FdL
_FdR:
'sertxd ("_FdR")
	gosub _rollL
	gosub _RF
	gosub Stand
	return
_FdL:
'sertxd ("_FdL")
	gosub _rollR
	gosub _LF
	gosub Stand
	return
'-----------------------------------------
Bk:
sertxd ("Bk")
	f_direction =0
	if f_defaultB=1 then gosub B_fast
	if paceat<paceC then _BkR 'else _BkL
_BkL:
	gosub _rollR
	gosub _RF
	gosub Stand
	return
_BkR:
	gosub _rollL
	gosub _LF
	gosub Stand
	return
'-----------------------------------------
Rt:
sertxd ("Rt")
	if paceat<paceC and f_direction=1 then gosub Fd	'need left foot forward
	if paceat<paceC and f_direction=0 then gosub Bk	'need left foot forward
	if f_defaultB=1 then gosub beep150
	if f_defaultB=1 then gosub B_turn
	gosub _RF
	return
'-----------------------------------------
Lt:
sertxd ("Lt")
	if paceat>paceC and f_direction=1 then gosub Fd	'need right foot forward
	if paceat>paceC and f_direction=0 then gosub Bk	'need right foot forward
	if f_defaultB=1 then gosub beep150
	if f_defaultB=1 then gosub B_turn
	gosub _LF
	return
'=================================================================
_RF:
'sertxd ("_RF")
	paceto =paceC -paceby
	for spulse=paceat to paceto step -pacespeed
	  paceat =spulse
	  pulsout servoroll,rollat	'pulse servo hold in position
	  pulsout servopace,paceat	'pulse servo
	  pause sframe
	 next spulse
	return 
_LF:
'sertxd ("_LF")
	paceto =paceC +paceby
	for spulse=paceat to paceto step pacespeed
	  paceat =spulse
	  pulsout servoroll,rollat	'pulse servo hold in position
	  pulsout servopace,paceat	'pulse servo
	  pause sframe
	 next spulse
	return 
'-----------------------------------------
Stand:	'stand with both feet flat
'sertxd (" Sd")
	if rollat<rollC then _StandR 'else _StandL
_StandL:
'sertxd ("_SL")
	for spulse=rollat to rollC step -rollspeed
	  rollat =spulse
	  pulsout servoroll,rollat	'pulse servo
	  pulsout servopace,paceat	'pulse servo hold in position
	  pause sframe
	 next spulse
	return 
_StandR:
'sertxd ("_SR")
	for spulse=rollat to rollC step rollspeed
	  rollat =spulse
	  pulsout servoroll,rollat	'pulse servo
	  pulsout servopace,paceat	'pulse servo hold in position
	  pause sframe
	 next spulse
	return 
'-----------------------------------------
_rollL:
'sertxd ("_rL")
	rollto =rollC -rollby
	for spulse=rollat to rollto step -rollspeed
	  rollat =spulse
	  pulsout servoroll,rollat	'pulse servo
	  pulsout servopace,paceat	'pulse servo hold in position
	  pause sframe
	 next spulse
	return 
	 
_rollR:
'sertxd ("_rR")
	rollto =rollC +rollby
	for Spulse=rollat to rollto step rollspeed
	  rollat =spulse
	  pulsout servoroll,rollat	'pulse servo
	  pulsout servopace,paceat	'pulse servo hold in position
	  pause sframe
	 next spulse
	return 
'-----------------------------------------
_iStand:
'initialise with feet in mid position
	for spulse=0 to 10
	  pulsout servopace,paceC	'pulse servo paceC
	  pulsout servoroll,rollC	'pulse servo rollC
	  pause 70				'pause 70ms - do it slowly
	 next spulse
	rollat =rollC
	paceat =paceC 
	return 
'-----------------------------------------
'Sense
'-----
calibrateholewhiskers:
'take averages of 8 readings per whisker
	w8 =0	'clear tempHi,tempLo
	low GwhiskerLedL_			'eyeL on
	for i=0 to 7
'		low whiskerLedL_		'eyeL on
		readadc GwhiskerL,temp0
'		high whiskerLedL_		'eyeL off		
		sertxd("L",#temp0)
		temp0 =temp0 /8
		tempHi_wLg =tempHi_wLg +temp0
		sertxd(" ",#tempHi_wLg,cr)
	  next i	
	high GwhiskerLedL_			'eyeL off
	low GwhiskerLedR_			'eyeL on
	for i=0 to 7
'		low whiskerLedR_		'eyeL on
		readadc GwhiskerR,temp0
'		high whiskerLedR_		'eyeL off
		sertxd("R",#temp0)
		temp0 =temp0 /8
		tempLo_wRg =tempLo_wRg +temp0
		sertxd(" ",#tempLo_wRg,cr)
	  next i	
	high GwhiskerLedR_			'eyeL off
'set threshold at 60%
	tempHi_wLg =tempHi_wLg *3 /5
	tempLo_wRg =tempLo_wRg *3 /5
  sertxd("holethresh L",#tempHi_wLg," R",#tempLo_wRg,cr)
	write EEholedetectL,tempHi_wLg
	write EEholedetectR,tempLo_wRg
	return 

QEwhiskerL:
	low eyeLedL_			'LeyeLED on
	readadc c.1,tempHi_wL		'withLEDon
	high  eyeLedL_			'LeyeLED off
	readadc c.1,lightL		'ambient light
	if lightL>tempHi_wL then	'why this happens I don't know
		lightL =tempHi_wL
	  endif	
	tempHi_wL =tempHi_wL -lightL *256 /tempHi_wL	'scale
  sertxd(cr,"eL",#tempHi_wL)
	if tempHi_wL>objthresh then	'obstacle so update obstacles memory
		peek obstaclesL,temp0
		temp0 =temp0 +mob max mobs
		poke obstaclesL,temp0
	  endif	
	return 

QEwhiskerR:
	low eyeLedR_			'ReyeLED on
	readadc c.7,tempLo_wR		'withLEDon
	high  eyeLedR_			'ReyeLED off
	readadc c.7,lightR		'ambient light
	if lightR>tempLo_wR then	'why this happens I don't know
		lightR =tempLo_wR
	  endif	
	tempLo_wR =tempLo_wR -lightR *256 /tempLo_wR	'scale
  sertxd(" eR",#tempLo_wR)
	if tempLo_wR>objthresh then	'obstacle so update obstacles memory
		peek obstaclesR,temp0
		temp0 =temp0 +mob max mobs
		poke obstaclesR,temp0
	  endif
	return 

QGwhiskerL:
	low GwhiskerLedL_		'LwLED on
	readadc GwhiskerL,tempHi_wLg	'withLEDon
	high GwhiskerLedL_		'LwLED off
	readadc GwhiskerL,lightL	'ambient light
	if lightL>tempHi_wLg then	'why this happens I don't know
		 lightL =tempHi_wLg	
	  endif	
	read EEholedetectL,temp0
	if tempHi_wLg<temp0 then 	'a hole, no ground detected so update obstacles memory
		peek obstaclesL,temp0
		temp0 =temp0 +mholeB +mholeT max mholes
		poke obstaclesL,temp0
		peek obstaclesR,temp0
		temp0 =temp0 +mholeB max mholes	'so back and turn
		poke obstaclesR,temp0
	  endif
sertxd(cr,"wL",#tempHi_wLg)  
	return 

QGwhiskerR:
	low GwhiskerLedR_		'RwLED on
	readadc GwhiskerR,tempLo_wRg	'withLEDon
	high  GwhiskerLedR_		'RwLED off
	readadc GwhiskerR,lightR	'ambient light
	if lightR>tempLo_wRg then	'why this happens I don't know
		 lightL =tempLo_wRg	
	  endif	
	read EEholedetectR,temp0
	if tempLo_wRg<temp0 then 	'a hole, no ground detected so update obstacles memory
		peek obstaclesR,temp0
		temp0 =temp0 +mholeB +mholeT max mholes
		poke obstaclesR,temp0
		peek obstaclesL,temp0
		temp0 =temp0 +mholeB max mholes	'so back and turn
		poke obstaclesL,temp0
	  endif
  sertxd(" wR",#tempLo_wRg)
	return 
'-----------------------------------------
badkey:
	high eyeLedR_
	pause 100
	low eyeLedR_
	high eyeLedL_
	pause 100
	low eyeLedL_
	return

beep50:
	sound VoiceLed_,(50,10)
	return

beep150:
	sound VoiceLed_,(150,10)
	return

EyesOFF:
	high eyeLedR_
	high eyeLedL_
	return
	
EyesON:
	low eyeLedR_
	low eyeLedL_
	return
	
IRgetAct_cmnd:	  	
	irin iIRin,cmnd		'key1 - key8 => 0-7
	if cmnd<8 then _IRgetActEnd
	gosub badkey
	goto IRgetAct_cmnd	'repeat until valid act		
_IRgetActEnd:
	gosub beep50	
	return 
	
nokey:
	irin [50,_nokeyend],iIRin,cmnd'irin timeout =>return
	goto nokey
_nokeyend:
	return	
	
'=================================================================

[page top]

'Bambino-28
Sertxd("B28",cr)		'report program number @4800

#PicAxe 20M2
#no_data
'1781 bytes used
'PICAXE            IC   Memory   ext  I/O   Outputs  Inputs  ADC  Memory                        Starts  Polled  Resonator
' £   Type        pins  bytes    slot pins                        Vars. RAM Spad Data     Table*        Int.    def. opt. 
'2.28 PICAXE-20M2  20    2k           18    1-16     1-17     4    28   512      256      512   8       Yes      4   -32

'PICAXE-20M2 circuit board with LEDs off takes 1mA
'PICAXE-20M2 circuit board with LEDs off and servos connected takes 10mA


'Bambino-01  'Test eyeLEDs, whiskerLEDs and speaker
'Bambino-02  'Test InfraRed input
'Bambino-02a 'Test Eye light values
'Bambino-02b 'Test Whisker light values
'Bambino-03  'Play the inbuilt tunes using keys 1 to 4 and beep on 5
'Bambino-04  'Set servos to mid position	
'Bambino-05  'Calibrate servo mid positions and put values in EEPROM.
'Bambino-06  'Introduce _iStand:- initialise with feet in mid position
'Bambino-07  'Set rollR
'Bambino-08  'Set rollL
'Bambino-09  'Check rollR, rollL
'Bambino-10  'Introduction of _Stand
'Bambino-11  'Investigate effect of rollspeed;	watch roll for all three speeds
'Bambino-12  'Investigate effect of rollspeed;	watch Roll and Stand for all three speeds
'Bambino-13  'Check paceFL paceFR;	Investigate effect of pacespeed
'Bambino-14  'Check Fd
'Bambino-15  'Test Rt, Lt
'Bambino-15a 'Test T2L Turn to Light, T2D Turn to Dark
'Bambino-16  'Test Bk
'Bambino-17  'Creaton of sections ACTIONS, BEHAVIOURS, ACTS;
             'Introduction of ACT parameter 'Ado'
'Bambino-17a 'Demo routine            	
'Bambino-18  'Walk Fd with obstacle avoidance using eyes from 02a
'Bambino-18a 'Walk Fd with drop-off avoidance using whiskers values from 02b
'Bambino-18b 'rewritten with autocalibration of down whiskers and reading of whiskers as subroutines
'Bambino-19  'If IR command then do it otherwise walk and avoid
'Bambino-20  'rewrite to incorporate rollC and paceC in EEPROM 254,255
'Bambino-21  'rewrite to clearer code
'Bambino-22  'remember a sequence of keys presses          
'Bambino-23  'remember up to 8 sequence of keys presses in RAM          
'Bambino-24  'remember up to 8 sequence of keys presses in EEPROM          
'Bambino-25  'obstacle map made deeper and put in RAM for better obstacle avoidance
'Bambino-26  'incorporate drop-off avoidance from 18b
'Bambino-27  'map increment  on hole split into mholeB & mholeT to enable backup & Turn 	
			'otherwise Bambino turns and falls sideways off an edge.
'Bambino-28  'Adjustment of Servo centres rollC and paceC from handset
'-----------------------------------------------------------------            	
'modified
'--------
'IRacty:	moved to end of cmnd section
'nokey:	renamed waitnokey:
'badkey:	reordered to leave LEDs off
'gosub

'New
'---
'WalkaboutInit:	gosub calibrateholewhiskers moved from initialise:
'temp0_EE	  =b0
'adjustrollC:
'adjustpaceC:	
'_adjustC:
'_IRupdw:	

'=================================================================
'[KEY_UP]		(exit wander) direct contol	
'[KEY_DOWN]		(exit wander) direct contol	
'[KEY_RIGHT]	(exit wander) direct contol
'[KEY_LEFT]		(exit wander) direct contol	
'
'[KEY_BAR] enters learn mode
'[KEY_BAR] has to be followed by a number key 1-8 
'	= the Act to be remembered
'up to 8 Acts can be learned
'learned Acts can call coded Acts
'a learned Act which chains itself repeats forever, eg #1 = Fd,1
'Acts can chain to other Acts, eg Fd,Bk,2   - chain to Act2
'[KEY_POWER] stops the playing Act.
'
'[KEY_TENT] selects coded Acts = subroutines,
'[KEY_TENT] has to be followed by a number key 1-8 
'	 [key1]=>RockAdo
'coded Acts play until the end.
'
'[KEY_VCROSS] enters modify mode
'[KEY_VCROSS] has to be followed by [KEY_UP],[KEY_DOWN],[KEY_RIGHT],[KEY_LEFT] or [KEY_POWER] to quit
'[KEY_UP],[KEY_DOWN] select the Pace servo
'[KEY_RIGHT],[KEY_LEFT] select the Roll servo
'[KEY_MINUS] adjusts the centre position one way
'[KEY_PLUS] adjusts the centre position the other way
'
'[KEY_XCROSS]		'Dump EEPROM DATA to PC, format to past into programs
'
'When recording an Act, 
'	after [IRkey1],[IRkey2],[IRkey3],[IRkey4],[IRkey5],[IRkey6],[IRkey7],[IRkey8]
'	is used to chain another Act there is no point in recording more moves 
'	because they will never be replayed since control is transfered to the new Act,
'	just press [KEY_POWER] to end recording.
'NOTE do not record more than 30 moves for Act8 otherwise it will overwrite the servo calibration of RollC and PaceC
'=================================================================
'TVR010 PicAxe IR-controller
'---------------------------
'Before use, the transmitter must be programmed with the ‘Sony’ transmit code.
'1. Insert 2 AAA size batteries, preferably alkaline.
'2. Press ‘S’ and ‘B’ at the same time. S is in the centre of the arrows. 
'	The top left red LED should light.
'3. Press ‘0’. The LED should flash.
'4. Press ‘1’. The LED should flash.
'5. Press ‘3’. The LED should go out.
'6. Press the red power button (top right).
'-------------------------------------------
'IRin cmnds PicAxe controller
'DO NOT PRESS OTHER KEYS 
'ie [A] [B] [C] [D] [E] [F] [G] 
'They change the Mode and [B] has to be pressed to change back.
'[square] [triangle [()] [L] [X] [backwards F]  have no effect

Symbol KEY_POWER  = 21		'Sleep

Symbol KEY_UP     = 16		'Step Forward
Symbol KEY_DOWN   = 17		'Step Backward
Symbol KEY_RIGHT  = 18		'Turn Right
Symbol KEY_LEFT   = 19		'Turn Left

Symbol KEY_BAR    = 96		'learn an Act, next [key] selects a Act
Symbol KEY_TENT   = 54		'next [key] selects a Coded-Act
Symbol KEY_VERT_CROSS = 37	'use synonym for easier coding
Symbol KEY_VCROSS = 37		'add mode - modify mode
Symbol KEY_DIAG_CROSS = 20	'use synonym for easier coding
Symbol KEY_XCROSS = 20		'transfer EEPROM to PC for including in programs		'
					'Coded Acts		
symbol IRkey1     =  0		'	RockADo	
symbol IRkey2     =  1
symbol IRkey3     =  2
symbol IRkey4     =  3
symbol IRkey5     =  4
symbol IRkey6     =  5
symbol IRkey7     =  6
symbol IRkey8     =  7
symbol IRkey9     =  8
Symbol KEY_MINUS  = 98
Symbol KEY_0      =  9		'QUIT command mode
Symbol KEY_PLUS   = 11
'=================================================================
symbol servopace    =c.0	'left connector
symbol servoroll    =c.4	'right connector
symbol VoiceLed_    =c.5    	'low =>LED on 
symbol eyeLedL_     =c.2    	'low =>LED on 
symbol eyeLedR_     =b.1    	'low =>LED on
symbol eyeR         =c.7		  	
symbol eyeL         =c.1
symbol GwhiskerLedL_=c.3    	'low =>whisker LED on
symbol GwhiskerLedR_=b.3    	'low =>whisker LED on
symbol GwhiskerL    =b.6      'adc whisker Down Left		  	
symbol GwhiskerR    =b.0      'adc whisker Down Right		  	
symbol iIRin        =c.6
symbol oIRout       =b.2

symbol general 	    =b0
symbol temp0	    =b0
symbol temp0_EE	    =b0	
symbol flags	   =w1
symbol B_flags      =b3
'symbol f_doIRcmnds  =bit29
symbol f_play	     =bit28	
symbol f_record	     =bit29
symbol f_direction   =bit30	'1=forwards, 0=backwards    
symbol f_defaultB    =bit31	'defaultBehaviour 1=use default
symbol servosAt	   =w2
symbol  rollat 	    =b4
symbol  paceat 	    =b5
symbol ServosTo	   =w3
symbol  rollTo	    =b6	   
symbol  paceTo	    =b7
symbol Smoveby	   =w4
symbol  rollby	    =b8
symbol  paceby      =b9
symbol Scentre	   =w5
symbol  rollC	    =b10
symbol  paceC       =b11
symbol Sspeed      =w6
symbol  rollspeed   =b12  '4 is too fast, 0 won't move
symbol  pacespeed   =b13  '6 is about max for servos to keep up
symbol counters	   =w7
symbol  spulse 	    =b14
symbol  iA 	    =b15
symbol  i   	    =b15	'calibrateholewhiskers:	
symbol tempw       =w8
symbol  tempLo      =b16
symbol  tempLo_wR   =b16	'whisker Right
symbol  tempLo_wRg  =b16	'whisker Right Ground
symbol  tempHi      =b17
symbol  tempHi_wL   =b17	'whisker Left
symbol  tempHi_wLg  =b17	'whisker Left Ground 

symbol sframe     =22	'time between servo pulses

symbol Ado		    =b18	'parameter for ACTs
symbol obsmap     =b19  '%11 bitmap of obstacles  %LeftRight
symbol lightL     =b20  'light level Left
symbol lightR     =b21  'light level Right
symbol objthresh  =70   'light/dark whisker threshold for obstacle 
symbol cmnd	  =b22  'cmnd from IRremote
symbol Act        =b23
symbol Aend	  =b24	'end of record slot
symbol eptr       =b25	'pointer to EEPROM

'depending on the sensors obsdetectL and obsdetectR may need to be different
symbol obsdetectL	=120	'scaled light level difference for obstacle
symbol obsdetectR	=120	'scaled light level difference for obstacle

'if set in Program#18a then those values will be used, otherwise these values
'depending on the sensors holedetectL and holedetectR may need to be different
'default if not set in prog #18a, values so Bambino can see table edges
symbol holedetectL=120	'scaled light level difference for holes
symbol holedetectR=120	'scaled light level difference for holes

symbol EEholedetectR =252
symbol EEholedetectL =253
symbol EErollC       =254
symbol EEpaceC       =255

'EEPROM Acts
symbol act0	=0
symbol act1	=32 
symbol act2	=32 *2
symbol act3	=32 *3 
symbol act4	=32 *4
symbol act5	=32 *5
symbol act6	=32 *6
symbol act7	=32 *7
symbol act8	=32 *8

'for Act=act1 to act8
'	poke Act,255	'set stop markers	
'  next Act	


symbol obstaclesR =32	'RAM
symbol obstaclesL =33	'RAM
symbol mob        =6'8	'memory increment  for obstacle
symbol mobs       =8	'memory increment  for obstacle
symbol mholeT	=4	'memory increment  for hole turn
symbol mholeB	=2	'memory increment  for hole back
symbol mholes	=8	'memory max  for hole
'=================================================================
initialise:
	rollby    =15	'+ve right 
	paceby    =20	'+ve Left  foot forward
	rollspeed =1  	'4 is too fast, 0 won't move
	pacespeed =2   	'6 is about max for servos to keep up  
	rollC	    =150	'Default, 100 is roll to the left
	paceC	    =150	'Default, 100 is left foot back
	'get values from EEPROM if set by program #5
	read EErollC,temp0
	if temp0>130 and temp0<170 then	'so servo is always between 100,200
	  rollC =temp0
	 endif 
	read EEpaceC,temp0
	if temp0>130 and temp0<170 then	'so servo is always between 100,200
	  paceC =temp0
	 endif 
	sertxd("rollC=",#rollC," paceC=",#paceC,cr)
	 
	low eyeLedR_	'make output LED on
	low eyeLedL_	'make output LED on
	gosub _iStand
	f_defaultB =1	'defaultBehaviour On
	f_record =0

start:
sertxd("S")
	Ado =4				'for RockAdo
	irin [50,WalkaboutInit],iIRin,cmnd'irin with timeout, no IR =>WalkaboutInit
	gosub beep50                  'so we know IR received
	goto DoCmnd
'=================================================================
'Activities
'----------
'rest 	- from [KEY_POWER]
'Wander	- from [KEY_0]
'direct IRcmnds

DoCmnd:	
	sertxd(cr,#cmnd," @",#eptr)
	sertxd(" f_p",#f_play," f_r",#f_record,",")
		
	select cmnd
	  case KEY_POWER
	  	if f_record=0 and f_play=0 then
	  		gosub rest
			goto DoCmnd	'have already got IRcmnd in rest:
		   else
		      f_play =0
		      if f_record=1 then
		      	f_record =0
    	 			poke eptr,255	     'end marker
    	 		  endif	
 		 endif 
	  case KEY_UP
	  	gosub Fd
	  case KEY_DOWN
	  	gosub Bk
	  case KEY_RIGHT
	  	gosub Rt
	  case KEY_LEFT
	  	gosub Lt
	  case KEY_0
		goto Start			'QUIT and Wander

'key Acts
	  case <IRkey9			'Act keys 1-8 => Acts 0-7
	  	if f_record<>1 then
	  		f_play=1		'play
	  		eptr =32 *cmnd	'set to start
	  		sertxd(" play@",#eptr,cr)	 
		  endif

	  case KEY_BAR			'record
	  	f_play =0	
	  	f_record =1
		gosub IRgetAct_cmnd	'wait for key 1 - 8 only
		eptr =32 *cmnd
		Aend =eptr +31
		gosub waitnokey
	  	sertxd("rec@",#eptr,cr)
	  	goto IRcmnd	 		'get cmnds
	  	
'coded Acts	  	
	  case KEY_TENT			'coded acts
	  	gosub IRgetAct_cmnd	'wait for key 1 - 8 only
		cmnd =cmnd +128		'set topbit for coded Acts, ie cmnd>127
		sertxd(" Act",#cmnd,cr)
		goto DoCmnd
		
	  case KEY_XCROSS			'Dump DATA to PC
		for Act=0 to 7
			sertxd(cr,lf,"'Act ",#Act,cr,lf,"DATA ")
			for eptr=0 to 30
				tempLo =Act *32 +eptr
				read tempLo,cmnd
				sertxd(#cmnd,",")
			  next eptr
			tempLo =Act *32 +31
			read tempLo,cmnd
			sertxd(#cmnd)
		  next Act
		sertxd(cr,lf)
		  	   
	  case >127				'do Coded Act subroutines
	  	sertxd("case >127",cr)	 
	    	Act =cmnd -128
	  	on Act gosub RockAdo	'add others
	  	
	  case KEY_VCROSS			'modify rollC, paceC
_case_VCROSS:
		irin iIRin,cmnd	 	'Get cmnd
		if cmnd>15 and cmnd<20 then	'16,17,18,19
			gosub beep50            'so we know valid IR received
		  else	
			gosub badkey
			goto _case_VCROSS
		  endif
		if cmnd=16 or cmnd=17 then
			gosub adjustpaceC
		  else		    		'18,19
		  	gosub adjustrollC
		  endif	
	  endselect


'_record
	if f_record=1 then
		if eptr<Aend then
			write eptr,cmnd
			eptr =eptr +1
		 else				'end of slot
		 	gosub beep150
			cmnd =KEY_POWER	'indicate end of slot by resting
			goto DoCmnd
		 endif	
	   endif

'_play:
	if f_play=1 then
		irin [50,_playon],iIRin,cmnd
		goto DoCmnd		'if IR received do cmnd		
_playon:		
	 	read eptr,cmnd
 		eptr =eptr +1
		if cmnd<>255 then	DoCmnd	'255=end
		f_play =0
	  endif
		
IRcmnd:				'get IRcmnd
	sertxd("IR")
	irin iIRin,cmnd	 	'Get cmnd
	gosub beep50            'so we know IR received
	
	goto DoCmnd


	
'-----------------------------------------
WalkaboutInit:
	gosub calibrateholewhiskers
	
Walkabout:
sertxd(cr,"W")
	peek obstaclesR,tempLo	'read memory
	peek obstaclesL,tempHi	'read memory
	tempLo =tempLo min 1 -1 'decay memory
	tempHi =tempHi min 1 -1 'decay memory
	poke obstaclesR,tempLo	'save
	poke obstaclesL,tempHi	'save
	sertxd ("mem",#tempHi," ",#tempLo," ")

	obsmap =0			
  	if tempLo>0 then		'create short term memory map
  		obsmap =obsmap or %1
   	  endif
  	if tempHi>0 then
  		obsmap =obsmap or %10
   	  endif

	gosub B_fast
	'alter LEDs so we can tell what Bambino is doing
	b0 =obsmap 			'to use bits
	if bit0=0 then	
'		low eyeLedR_
	pwmout eyeLedR_,110,400 'active low so high Dutycycle for dim
	  endif 
	if bit1=0 then
'		low eyeLedL_
	pwmout eyeLedL_,110,400 'active low so high Dutycycle for dim
	  endif 

	'take avoiding action if necessary 
  	on obsmap gosub Fd,Lt,Rt,Bk 
	'otherwise fall through and test whiskers
	 
	pwmout eyeLedR_,off	
	pwmout eyeLedL_,off
'	gosub EyesOFF

	gosub QEwhiskerL
	gosub QEwhiskerR
	gosub QGwhiskerL
	gosub QGwhiskerR
	
Qwalk:	
	irin [50,Walkabout],iIRin,cmnd	'irin with timeout, no IR =>Walkabout
	goto start                    	'QUIT if IRin
'=================================================================
'Behaviours
'----------
B_fast:
	rollspeed =3
	pacespeed =6
	return
	
B_turn:	
	rollspeed =1	'slow so foot doesn't bounce
	pacespeed =5 
	return	
'=================================================================
'Acts
'----

RockAdo:	'#128
	if f_defaultB=1 then gosub B_fast
	for iA=1 to Ado  
 	  gosub _rollR
	  gosub _rollL
	 next iA 
	gosub Stand 
	return
	
FdAdo:
	for iA=1 to Ado 
	  gosub Fd
	 next iA 
	return
	
BkAdo:
	for iA=1 to Ado 
	  gosub Bk
	 next iA 
	return

Rest:
	gosub _rollL
	gosub _iStand
	pwmout eyeLedR_,100,400 'active low so high Dutycycle for dim
	pwmout eyeLedL_,100,400 'active low so high Dutycycle for dim
_RestIRwait:
	high VoiceLed_		'LED off
	irin iIRin,cmnd		'irin with no timeout
	gosub beep50            'so we know IR received
	if cmnd=KEY_POWER then _RestIRwait	'wait until different IRcmnd
	pwmout eyeLedR_,off	
	pwmout eyeLedL_,off
	gosub EyesOFF
	return
	
'=================================================================
'Actions
'-------

Fd:
sertxd ("Fd")
	f_direction =1
	if f_defaultB=1 then gosub B_fast
	if paceat<paceC then _FdL 'else _FdL
_FdR:
'sertxd ("_FdR")
	gosub _rollL
	gosub _RF
	gosub Stand
	return
_FdL:
'sertxd ("_FdL")
	gosub _rollR
	gosub _LF
	gosub Stand
	return
'-----------------------------------------
Bk:
sertxd ("Bk")
	f_direction =0
	if f_defaultB=1 then gosub B_fast
	if paceat<paceC then _BkR 'else _BkL
_BkL:
	gosub _rollR
	gosub _RF
	gosub Stand
	return
_BkR:
	gosub _rollL
	gosub _LF
	gosub Stand
	return
'-----------------------------------------
Rt:
sertxd ("Rt")
	if paceat<paceC and f_direction=1 then gosub Fd	'need left foot forward
	if paceat<paceC and f_direction=0 then gosub Bk	'need left foot forward
	if f_defaultB=1 then gosub beep150
	if f_defaultB=1 then gosub B_turn
	gosub _RF
	return
'-----------------------------------------
Lt:
sertxd ("Lt")
	if paceat>paceC and f_direction=1 then gosub Fd	'need right foot forward
	if paceat>paceC and f_direction=0 then gosub Bk	'need right foot forward
	if f_defaultB=1 then gosub beep150
	if f_defaultB=1 then gosub B_turn
	gosub _LF
	return
'=================================================================
_RF:
'sertxd ("_RF")
	paceto =paceC -paceby
	for spulse=paceat to paceto step -pacespeed
	  paceat =spulse
	  pulsout servoroll,rollat	'pulse servo hold in position
	  pulsout servopace,paceat	'pulse servo
	  pause sframe
	 next spulse
	return 
_LF:
'sertxd ("_LF")
	paceto =paceC +paceby
	for spulse=paceat to paceto step pacespeed
	  paceat =spulse
	  pulsout servoroll,rollat	'pulse servo hold in position
	  pulsout servopace,paceat	'pulse servo
	  pause sframe
	 next spulse
	return 
'-----------------------------------------
Stand:	'stand with both feet flat
'sertxd (" Sd")
	if rollat<rollC then _StandR 'else _StandL
_StandL:
'sertxd ("_SL")
	for spulse=rollat to rollC step -rollspeed
	  rollat =spulse
	  pulsout servoroll,rollat	'pulse servo
	  pulsout servopace,paceat	'pulse servo hold in position
	  pause sframe
	 next spulse
	return 
_StandR:
'sertxd ("_SR")
	for spulse=rollat to rollC step rollspeed
	  rollat =spulse
	  pulsout servoroll,rollat	'pulse servo
	  pulsout servopace,paceat	'pulse servo hold in position
	  pause sframe
	 next spulse
	return 
'-----------------------------------------
_rollL:
'sertxd ("_rL")
	rollto =rollC -rollby
	for spulse=rollat to rollto step -rollspeed
	  rollat =spulse
	  pulsout servoroll,rollat	'pulse servo
	  pulsout servopace,paceat	'pulse servo hold in position
	  pause sframe
	 next spulse
	return 
	 
_rollR:
'sertxd ("_rR")
	rollto =rollC +rollby
	for Spulse=rollat to rollto step rollspeed
	  rollat =spulse
	  pulsout servoroll,rollat	'pulse servo
	  pulsout servopace,paceat	'pulse servo hold in position
	  pause sframe
	 next spulse
	return 
'-----------------------------------------
_iStand:
'initialise with feet in mid position
	for spulse=0 to 10
	  pulsout servopace,paceC	'pulse servo paceC
	  pulsout servoroll,rollC	'pulse servo rollC
	  pause 70				'pause 70ms - do it slowly
	 next spulse
	rollat =rollC
	paceat =paceC 
	return 
'-----------------------------------------
'Sense
'-----
calibrateholewhiskers:
'take averages of 8 readings per whisker
	w8 =0	'clear tempHi,tempLo
	low GwhiskerLedL_				'eyeL on
	for i=0 to 7
'		low whiskerLedL_			'eyeL on
		readadc GwhiskerL,temp0
'		high whiskerLedL_			'eyeL off		
		sertxd("L",#temp0)
		temp0 =temp0 /8
		tempHi_wLg =tempHi_wLg +temp0
		sertxd(" ",#tempHi_wLg,cr)
	  next i	
	high GwhiskerLedL_			'eyeL off
	low GwhiskerLedR_				'eyeL on
	for i=0 to 7
'		low whiskerLedR_			'eyeL on
		readadc GwhiskerR,temp0
'		high whiskerLedR_			'eyeL off
		sertxd("R",#temp0)
		temp0 =temp0 /8
		tempLo_wRg =tempLo_wRg +temp0
		sertxd(" ",#tempLo_wRg,cr)
	  next i	
	high GwhiskerLedR_			'eyeL off
'set threshold at 60%
	tempHi_wLg =tempHi_wLg *3 /5
	tempLo_wRg =tempLo_wRg *3 /5
  sertxd("holethresh L",#tempHi_wLg," R",#tempLo_wRg,cr)
	write EEholedetectL,tempHi_wLg
	write EEholedetectR,tempLo_wRg
	return 

QEwhiskerL:
	low eyeLedL_			'LeyeLED on
	readadc c.1,tempHi_wL		'withLEDon
	high  eyeLedL_			'LeyeLED off
	readadc c.1,lightL		'ambient light
	if lightL>tempHi_wL then	'why this happens I don't know
		lightL =tempHi_wL
	  endif	
	tempHi_wL =tempHi_wL -lightL *256 /tempHi_wL	'scale
  sertxd(cr,"eL",#tempHi_wL)
	if tempHi_wL>objthresh then	'obstacle so update obstacles memory
		peek obstaclesL,temp0
		temp0 =temp0 +mob max mobs
		poke obstaclesL,temp0
	  endif	
	return 

QEwhiskerR:
	low eyeLedR_			'ReyeLED on
	readadc c.7,tempLo_wR		'withLEDon
	high  eyeLedR_			'ReyeLED off
	readadc c.7,lightR		'ambient light
	if lightR>tempLo_wR then	'why this happens I don't know
		lightR =tempLo_wR
	  endif	
	tempLo_wR =tempLo_wR -lightR *256 /tempLo_wR	'scale
  sertxd(" eR",#tempLo_wR)
	if tempLo_wR>objthresh then	'obstacle so update obstacles memory
		peek obstaclesR,temp0
		temp0 =temp0 +mob max mobs
		poke obstaclesR,temp0
	  endif
	return 

QGwhiskerL:
	low GwhiskerLedL_			'LwLED on
	readadc GwhiskerL,tempHi_wLg	'withLEDon
	high GwhiskerLedL_		'LwLED off
	readadc GwhiskerL,lightL	'ambient light
	if lightL>tempHi_wLg then	'why this happens I don't know
		 lightL =tempHi_wLg	
	  endif	
	read EEholedetectL,temp0
	if tempHi_wLg<temp0 then 	'a hole, no ground detected so update obstacles memory
		peek obstaclesL,temp0
		temp0 =temp0 +mholeB +mholeT max mholes
		poke obstaclesL,temp0
		peek obstaclesR,temp0
		temp0 =temp0 +mholeB max mholes	'so back and turn
		poke obstaclesR,temp0
	  endif
sertxd(cr,"wL",#tempHi_wLg)  
	return 

QGwhiskerR:
	low GwhiskerLedR_			'RwLED on
	readadc GwhiskerR,tempLo_wRg	'withLEDon
	high  GwhiskerLedR_		'RwLED off
	readadc GwhiskerR,lightR		'ambient light
	if lightR>tempLo_wRg then	'why this happens I don't know
		 lightL =tempLo_wRg	
	  endif	
	read EEholedetectR,temp0
	if tempLo_wRg<temp0 then 	'a hole, no ground detected so update obstacles memory
		peek obstaclesR,temp0
		temp0 =temp0 +mholeB +mholeT max mholes
		poke obstaclesR,temp0
		peek obstaclesL,temp0
		temp0 =temp0 +mholeB max mholes	'so back and turn
		poke obstaclesL,temp0
	  endif
  sertxd(" wR",#tempLo_wRg)
	return 
'-----------------------------------------
badkey:
	low eyeLedR_
	pause 100
	high eyeLedR_
	low eyeLedL_
	pause 100
	high eyeLedL_
	return

beep50:
	sound VoiceLed_,(50,10)
	return

beep150:
	sound VoiceLed_,(150,10)
	return

EyesOFF:
	high eyeLedR_
	high eyeLedL_
	return
	
EyesON:
	low eyeLedR_
	low eyeLedL_
	return
	
IRgetAct_cmnd:	  	
	irin iIRin,cmnd		'key1 - key8 => 0-7
	if cmnd<8 then _IRgetActEnd
	gosub badkey
	goto IRgetAct_cmnd	'repeat until valid act		
_IRgetActEnd:
	gosub beep50	
	return 
	
waitnokey:
	irin [50,_nokeyend],iIRin,cmnd'irin timeout =>return
	goto waitnokey
_nokeyend:
	return	
	
adjustrollC:
	temp0_EE =EErollC
	low GwhiskerLedR_			'LED on, Right servo is Roll 
	goto _adjustC
adjustpaceC:	
	temp0_EE =EEpaceC
	low GwhiskerLedL_			'LED on, Left servo is Pace
_adjustC:
	tempw =Smoveby			'save Smoveby
	Smoveby =0
_IRupdw:	
	if cmnd = KEY_POWER then	'finished
		write EErollC,rollC
		write EEpaceC,paceC
		Smoveby =tempw		'restore moveby
		high  GwhiskerLedL_	
		high  GwhiskerLedR_	
		return
	  endif	
	if temp0_EE=EErollC then	'do rollC
		select cmnd
			case KEY_MINUS
				rollC =rollC -1
			case KEY_PLUS
				rollC =rollC +1
			else
				gosub badkey	
	  	  endselect	
	  else				'do paceC
		select cmnd
			case KEY_MINUS
			  	paceC =paceC -1	
			case KEY_PLUS
			  	paceC =paceC +1	
			else
				gosub badkey	
	  	  endselect	
	  endif
	gosub _iStand	
	irin iIRin,cmnd		
	gosub beep50
	goto _IRupdw
'=================================================================

[page top]
Revisions