yeah i don’t mind sharing the code –
it’s not very advanced compared to the pheonix v2 code - in fact, its very basic! But I am learning from the ground up and learning fast.
I am using a mrs-01 frame with atom pro, BB2 and ssc-32 with an srf08 ultrasonic sensor.
a link to an earlier video is:
youtube.com/watch?v=qqskMQo2hxc
since then i have added in multiple gaits, and a selection of turning or attacking upon close proximity to an object.
Anyway, it is a work in progress but here it is:
[code];CONFIGURATION
SDA Con P6 ;set up the Serial DAta pin for using the I2C bus
SCL Con P7 ;Set up the Serial Clock Line for using the I2C bus
SRF08 Con 0xE0 ;Set up the address of the sensor on the I2C bus
SSCpinout con P11 ;set up the serial out to pin 11
SSCpinin con P10 ;set up the serial in to pin 11
SSCbaud con i38400 ;set up the baud rate for communication between the SSC and the BB2
DAT con P12 ;set up the pin used for DATa with the ps2 controller communications
CMD con P13 ;set up the pin used for CoMmanD with the ps2 controller
SEL con P14 ;set up the pin used for SELect (signal goes low during transmission)
CLK con P15 ;Set up the pin used for the Clock - to keep in sync
ButtonDown con 0 ;used for when the user input was the on-board buttons
ButtonUp con 1 ;used for when the user input was the on-board buttons
CmdReg Con 0 ;Sonar Command register
LightReg Con 1 ;Sonar Light sensor register
RangeReg Con 2 ;Sonar 1st Range register
binarycount var byte ;Variable named binarycount - used for user input
seqnum var byte ;Variable named seqnum - copys the contents of binary input into here (selecting gaits)
Sequence var byte ;Variable named Seqence - used to store the sequence number required
Prevseq var byte ;Variable named Prevseq - used to compare current and last sequence
Speed var byte ;Variable named Speed - used to control the speed of the sequence
liftleg var byte
moveflag var bit ;Variable named moveflag - used to flag movement
Light var byte ’ Light sensor
Range var word ’ 16 bit variable for Range
PrevRange var word
turn var byte
attack var byte
prevattack var byte
Display var word
Prange10 var word
Prange9 var word
Prange8 var word
Prange7 var word
Prange6 var word
Prange5 var word
Prange4 var word
Prange3 var word
Prange2 var word
Prange1 var word
Prange var word
AvRange var word
prevattack = 0
attack = 0
Display = 0
;-----------------------------
index var byte ;Variable named index - used in a for - next loop to display ps2 readings in terminal
ps2 var byte(19) ;An array of bytes called ps2 (19 of them) - used to store information from the ps2
mode var byte ;Variable named mode - stores the mode of the ps2 controller
Small_Motor var byte ;Variable called Small_Motor - used for the vibration of the controller
Large_Motor var byte ;Variable called Small_Motor - used for the vibration of the controller
LastButton var Byte(2) ;Array of 2 bytes named LastButton - used to compare current and last ps2 button
LastButton(0) = 255 ;Set value to 255
LastButton(1) = 255 ;Set value to 255
bitA var bit ;Variable bit named bitA - used to store bit0 of binary count
bitB var bit ;Variable bit named bitB - used to store bit1 of binary count
bitC var bit ;Variable bit named bitC - used to store bit2 of binary count
ButtonA var bit ;Variable bit named ButtonA - used to store state of buttonA
ButtonB var bit ;Variable bit named ButtonB - used to store state of buttonB
ButtonC var bit ;Variable bit named ButtonC - used to store state of buttonC
PrevButA var bit ;Variable bit named PrevButA - used to store state of PrevButA
PrevButB var bit ;Variable bit named PrevButB - used to store state of PrevButB
PrevButC var bit ;Variable bit named PrevButC - used to store state of PrevButC
temp var word ;Large Variable named temp - used
bitA = 0 ;Set bitA to zero
bitB = 0 ;Set bitB to zero
bitC = 0 ;Set bitC to zero
ButtonA = 0 ;Set buttonA to zero
ButtonB = 0 ;Set buttonB to zero
ButtonC = 0 ;Set buttonC to zero
binarycount = 0 ;Set binarycount to zero
seqnum = 0 ;Set seqnum to zero
Prevseq = 0 ;Set Prevseq to zero
Sequence = 0 ;Set Sequence to zero
moveflag = 1 ;Set moveflag to one
turn = 0
attack = 0
;leftleg = 0
main
gosub ps2initialise
gosub change
Serout S_OUT, i9600, " before wakeup "]
gosub wakeup
Serout S_OUT, i9600, " after wakeup "]
loop
gosub ps2reading
gosub sensorreading
gosub AverageRange
gosub check
;;;;;;;;;;;;;;;;;;;;Check for user input;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;; Binary counter ;;;;;;;;;;;;;;;;;;;;;
IF (ps2(2).bit6 = 0) and LastButton(1).bit6 THEN ;Cross Button test
binarycount = binarycount + 1
sound P9,[100\500]
low P9
ENDIF
IF (ps2(2).bit5 = 0) and LastButton(1).bit5 THEN ;Circle Button test
binarycount = binarycount - 1
sound P9,[100\1000]
low P9
ENDIF
IF (ps2(2).bit7 = 0) and LastButton(1).bit7 THEN ;Square Button test
binarycount = 0
sound P9,[100\1500]
low P9
ENDIF
LastButton(0) = ps2(1)
LastButton(1) = ps2(2)
if (ButtonA = ButtonDown) AND (PrevButA = ButtonUp) then
binarycount = binarycount + 1
sound P9, [10\3000]
low P9
endif
if (ButtonB = ButtonDown) AND (PrevButB = ButtonUp) then
binarycount = binarycount - 1
sound P9, [10\1000]
low P9
endif
if (ButtonC = ButtonDown) AND (PrevButC = ButtonUp) then
binarycount = 0
sound P9, [10\2000]
low P9
endif
;;;;;;;;;;;;;;;Make the LEDs represent the number;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;; in the binary counter ;;;;;;;;;;;;;;;;;;;;;;;;;;
bitA = binarycount.BIT0
bitB = binarycount.BIT1
bitC = binarycount.BIT2
;------------------read the binary counter and act------------------
;----------------- upon the number required ------------------------
if (bitA = 1) AND (bitB = 0) AND (bitC = 0) then
; sound P9, [100\1000]
binarycount = 1
endif
if (bitA = 0) AND (bitB = 1) AND (bitC = 0) then
; sound P9, [100\2000]
binarycount = 2
endif
if (bitA = 1) AND (bitB = 1) AND (bitC = 0) then
; sound P9, [100\3000]
binarycount = 3
endif
if (bitA = 0) AND (bitB = 0) AND (bitC = 1) then
; sound P9, [100\4000]
binarycount = 4
endif
if (bitA = 1) AND (bitB = 0) AND (bitC = 1) then
; sound P9, [100\5000]
binarycount = 5
endif
if (bitA = 0) AND (bitB = 1) AND (bitC = 1) then
; sound P9, [100\6000]
binarycount = 6
endif
if (bitA = 1) AND (bitB = 1) AND (bitC = 1) then
; sound P9, [100\7000]
binarycount = 7
endif
if (bitA = 0) AND (bitB = 0) AND (bitC = 0) then
; sound P9, [100\500]
binarycount = 0
endif
;------------------^^ makes sure the counter resets ---------------
;------------------ and can only be between 0 - 7 ----------------
;------------------ don’t need more than 8 variants --------------
seqnum = binarycount
if(binarycount <=6) AND (binarycount<>0) then
moveflag = 1
if(binarycount=0) then
moveflag = 0
; gosub all1500
; liftflag = 1
endif
If(binarycount=7) then
serout SSCpinout, SSCbaud, “PL0”, 13]
moveflag = 0
serout SSCpinout, SSCbaud,"#0 p1500"]
serout SSCpinout, SSCbaud,"#1 p1500"]
serout SSCpinout, SSCbaud,"#2 p1500"]
serout SSCpinout, SSCbaud,"#4 p1500"]
serout SSCpinout, SSCbaud,"#5 p1500"]
serout SSCpinout, SSCbaud,"#6 p1500"]
serout SSCpinout, SSCbaud,"#8 p1500"]
serout SSCpinout, SSCbaud,"#9 p1500"]
serout SSCpinout, SSCbaud,"#10 p1500"]
serout SSCpinout, SSCbaud,"#16 p1500"]
serout SSCpinout, SSCbaud,"#17 p1500"]
serout SSCpinout, SSCbaud,"#18 p1500"]
serout SSCpinout, SSCbaud,"#20 p1500"]
serout SSCpinout, SSCbaud,"#21 p1500"]
serout SSCpinout, SSCbaud,"#22 p1500"]
serout SSCpinout, SSCbaud,"#24 p1500"]
serout SSCpinout, SSCbaud,"#25 p1500"]
serout SSCpinout, SSCbaud,"#26 p1500"]
serout SSCpinout, SSCbaud,"T800",13]
endif
serout s_out,i9600,"binarycount is ",DEC binarycount, 13]
;-------------- if in correct mode then goto walking sub -----------------
if (moveflag = 1) and (seqnum <> Prevseq) then
gosub walking
endif
; PrevButA = ButtonA
; PrevButB = ButtonB
; PrevButC = ButtonC
goto loop
;----------------------- Choose which gait to use -------------------
;----------------------- depending on user input --------------------
walking:
if (seqnum = 1) then
; leftleg = 1
Sequence = 4
Speed = 100
turn = 1
attack = 0
endif
if (seqnum = 2) then
; leftleg = 0
Sequence = 5
Speed = 100
turn = 1
attack = 0
endif
if (seqnum = 3) then
; leftleg = 1
Sequence = 6
Speed = 100
turn = 1
attack = 0
endif
if (seqnum = 4) then
; leftleg = 1
Sequence = 4
Speed = 100
turn = 0
attack = 1
endif
if (seqnum = 5) then
; leftleg = 0
Sequence = 5
Speed = 100
turn = 0
attack = 1
endif
if (seqnum = 6) then
; leftleg = 1
Sequence = 6
Speed = 100
turn = 0
attack = 1
endif
PrevSeq = seqnum
serout SSCpinout,SSCbaud,"PL0 SQ",dec Sequence," SM", dec Speed," IX0 PA0", 13]
; serout s_out,i9600,“should move leg…”,13]
return
;-----------------Initialise the ps2 controller---------------------
;-----------------set up communications and mode--------------------
ps2initialise:
high CLK
low SEL
shiftout CMD,CLK,FASTLSBPRE,$1\8,$43\8,$0\8,$1\8,$0\8] ;CONFIG_MODE_ENTER
high SEL
pause 1
low SEL
shiftout CMD,CLK,FASTLSBPRE,$01\8,$44\8,$00\8,$01\8,$03\8,$00\8,$00\8,$00\8,$00\8] ;SET_MODE_AND_LOCK
high SEL
pause 100
low SEL
shiftout CMD,CLK,FASTLSBPRE,$01\8,$4F\8,$00\8,$FF\8,$FF\8,$03\8,$00\8,$00\8,$00\8] ;SET_DS2_NATIVE_MODE
high SEL
pause 1
low SEL
shiftout CMD,CLK,FASTLSBPRE,$01\8,$4D\8,$00\8,$00\8,$01\8,$FF\8,$FF\8,$FF\8,$FF\8] ;VIBRATION_ENABLE
high SEL
pause 1
low SEL
shiftout CMD,CLK,FASTLSBPRE,$01\8,$43\8,$00\8,$00\8,$5A\8,$5A\8,$5A\8,$5A\8,$5A\8] ;CONFIG_MODE_EXIT_DS2_NATIVE
high SEL
pause 1
low SEL
shiftout CMD,CLK,FASTLSBPRE,$01\8,$43\8,$00\8,$00\8,$00\8,$00\8,$00\8,$00\8,$00\8] ;CONFIG_MODE_EXIT
high SEL
pause 1
return
;-----------PS2 Mode----------
ps2reading:
low SEL
;--------------- ask the ps2 controller what “mode” it is in
shiftout CMD,CLK,FASTLSBPRE,$1\8]
;--------------- reading “mode” from PS2 controller
;--------------- 73(hex) is Digital button mode (dualshock1)
;--------------- 79(hex) is Analog button mode (dualshock2)
shiftin DAT,CLK,FASTLSBPOST,[mode\8]
high SEL
pause 1
;-----------PS2 Data----------
low SEL
;-------------------- asking for data from ps2 controller -------------------
shiftout CMD,CLK,FASTLSBPRE,$1\8,$42\8]
;------------------------- reading data from controller ----------------------
;------------------- can’t use a “for-next” loop, it’s too slow to read PS2 data)
shiftin DAT,CLK,FASTLSBPOST,[ps2(0)\8,ps2(1)\8,ps2(2)\8,ps2(3)\8,ps2(4)\8,ps2(5)\8,ps2(6)\8,ps2(7)\8,ps2(8)\8, |
ps2(9)\8,ps2(10)\8,ps2(11)\8,ps2(12)\8,ps2(13)\8,ps2(14)\8,ps2(15)\8,ps2(16)\8,ps2(17)\8,ps2(18)\8]
high SEL
pause 1
;-----------PS2 Vibration motors----------
Small_Motor = 1 - Temp(1).bit5 ; Numeric right arrow button (Small Motor on/off)
Large_Motor = Temp(8) ; Analog left arrow button (Large Motor speed)
low SEL
shiftout CMD,CLK,FASTLSBPRE,$1\8,$42\8,$0\8,Small_Motor\8,Large_Motor\8]
high SEL
;----------------------In the Basic Micro Studio Terminal--------------
;----------------------Show the ps2 controller mode (A/D)--------------
;----------------------And Display the bytes coming in ----------------
serout S_OUT,i57600,[13, hex2 mode\2]
for index = 1 to 18
;serout S_OUT,i57600," ", dec3 temp(index)\3]
next
return
;----------------------Play on Start up ----------------------------
wakeup:
pause 500
sound p9, [100\1000,100\2000,100\3000]
low p9
serout SSCpinout,SSCbaud,“PL0 SQ0 SM100 IX0 PA0 ONCE”, 13]
gosub CheckMotion
serout SSCpinout,SSCbaud,“PL0 SQ1 SM100 IX0 PA0 ONCE”, 13]
gosub CheckMotion
return
;----------------------Check to see if a sequence is being played --------------------------
CheckMotion:
SequenceNumber var byte
SequenceFromStep var byte
SequenceToStep var byte
SequenceRemainingTime var byte
;Wait for Servo Contrioller Player to complete sequence
SequenceWait:
serout SSCpinout, SSCbaud, “QPL0”, 13]
serin SSCpinin, SSCbaud, [SequenceNumber, SequenceFromStep, SequenceToStep, SequenceRemainingTime]
IF (SequenceNumber<>255 | SequenceFromStep<>0 | SequenceToStep<>0 | SequenceRemainingTime<>0) THEN
GOTO SequenceWait ;Continue waiting
ENDIF
return
change:
Serout S_OUT, i9600, "start change "]
i2cout SDA, SCL, SRF08, [CmdReg, 0xA0]
Serout S_OUT, i9600, " hhhh "] ; Serout S_OUT, i9600, “after 1”] ’ Use terminal window
i2cout SDA, SCL,SRF08, [CmdReg, 0xAA]
i2cout SDA, SCL,SRF08, [CmdReg, 0xA5]
i2cout SDA, SCL,SRF08, [SRF08]
Serout S_OUT, i9600, " finish change "]
; Serout S_OUT, i9600, "change address "] ’ Use terminal window
return
;---------------- Act upon the readings from the sensor -----------------
check:
;---------------- if the turn flag is set then turn the robot right ------------
if (AvRange < 20) AND (Range <> PrevRange) AND (attack = 0) AND (turn = 1)then
serout SSCpinout, SSCbaud,"PL0 SQ3 SM200 IX0 PA0 ONCE", 13]
gosub CheckMotion
serout SSCpinout, SSCbaud,"PL0 SQ3 SM200 IX0 PA0 ONCE", 13]
gosub CheckMotion
serout SSCpinout, SSCbaud,"PL0 SQ3 SM200 IX0 PA0 ONCE", 13]
gosub CheckMotion
serout SSCpinout, SSCbaud,"PL0 SQ3 SM200 IX0 PA0 ONCE", 13]
gosub CheckMotion
serout SSCpinout, SSCbaud,"PL0 SQ3 SM200 IX0 PA0 ONCE", 13]
gosub CheckMotion
serout SSCpinout, SSCbaud,"PL0 SQ3 SM200 IX0 PA0 ONCE", 13]
gosub CheckMotion
serout SSCpinout, SSCbaud,"PL0 SQ3 SM200 IX0 PA0 ONCE", 13]
Serout S_OUT, i9600, "turn"] ' Use terminal window
endif
if (AvRange < 20) AND (Range <> PrevRange) AND (attack = 1)AND (turn = 0)then
attack = 2
serout SSCpinout, SSCbaud,“PL0 SQ2 SM100 IX6 PA0 ONCE”, 13]
Serout S_OUT, i9600, “attack”] ’ Use terminal window
; serout cSCCout, cSCCbaud,"#1 p1250",13]
endif
prevattack = attack
PrevRange = Range
return
;----------------------filter out erratic sensor readings-----------------
;----------------------by taking an average of the last 13 readings-------
AverageRange:
Prange10 = Prange9
Prange9 = Prange8
Prange8 = Prange7
Prange7 = Prange6
Prange6 = Prange5
Prange5 = Prange4
Prange4 = Prange3
Prange3 = Prange2
Prange2 = Prange1
Prange1 = Prange
Prange = PrevRange
PrevRange = Range
AvRange = (Prange10 + Prange9 + Prange8 + Prange7 + Prange6 + Prange5 + Prange4 + Prange3 + Prange2 + Prange1 + Prange + PrevRange + Range) / 13
return
sensorreading:
Serout S_OUT, i9600, “start sensor”]
i2cout SDA, SCL, SRF08, [CmdReg,81] ; third param is the I2c device address
Serout S_OUT, i9600, " ranging "] ; Serout S_OUT, i9600, " gsdyaghhs "] ’ Use terminal window
pause 66
i2cout SDA, SCL, SRF08, [RangeReg] ; Do a write to the I2c Saying we want this variable
; Serout S_OUT, i9600, “after 2”] ’ Use terminal window
i2cin SDA, SCL,SRF08, [Range.HighByte, Range.LowByte]
; Serout S_OUT, i9600, “after 3”] ’ Use terminal window
i2cout SDA, SCL, SRF08, [Lightreg] ; Do a write to the I2c Saying we want this variable
; Serout S_OUT, i9600, “after 2”] ’ Use terminal window
i2cin SDA, SCL,SRF08, [Light]
; Serout S_OUT, i9600, “after 3”] ’ Use terminal window
Display = Display + 1
if (Display = 30) then
Serout S_OUT, i9600, "Light1 = ", dec Light, ", Range = ", DEC Range, " cm, AvRange = ", dec AvRange] ’ Use terminal window
; Serout S_OUT, i9600, “after 4”] ’ Use terminal window
Display = 0
endif
return[/code]
There are a lot of serouts i used to follow the flow of the program - they are for troubleshooting and just ignore them,
also there are a few parts from my older program where i used the buttons on the BB2 to select the gait rather than the ps2 controller so ignore that too!
as i said its a work in progress so be nice 
it needs tidying up but ill get round to that!