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

  • Revisions


    [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