Need help programing i need a compass and sonar to work together
Indy_007
Posts: 7
I have the basic stamp and i have a compass and sonar hooked up they will run seperatly but not together. I am trying to run them both with rules but i am having trouble writing them, the best i can figure is it needs to run off sonar for a little while then when the wall ends it will use the compass heading, any help and suggestions???
thanks
thanks
Comments
For programming help, can you please attach what code you have started so far and what is or is not working with it? You can use the attachment manager to upload your sample code so we can review it. It helps to have all or most the information before offering suggestions.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Respectfully,
Joshua Donelson
www.parallax.com
I am thinking that I need to set the rules to use the sonar for a couple of loops then when it is going straight get the compass heading, then if the distance gets extremely large it will go and use the compass heading. The reason i want to do this is when just using the compass if it is not straight it will vear off course.
here are the sonar rules
·· Rule1: '· Go a bit left
··· IF (sonarDistance > (wallOffset + someTolerance)) THEN
··········· PULSOUT RightServo, RightZeroSpeed - speed
··········· PULSOUT LeftServo,· LeftZeroSpeed· + turnspeed
··········· ruleFired = True
········ ENDIF
·· Rule2: '· Go a bit right
··· IF (sonarDistance < (wallOffset - someTolerance)) THEN
··········· PULSOUT RightServo, RightZeroSpeed - turnspeed
··········· PULSOUT LeftServo,· LeftZeroSpeed· + speed
··········· ruleFired = True
········ ENDIF
·· Rule3: '· Go forward
··· IF (sonarDistance = ((wallOffset - someTolerance) OR (wallOffset + someTolerance))· THEN
··········· PULSOUT RightServo, RightZeroSpeed· - speed
··········· PULSOUT LeftServo,· LeftZeroSpeed·· + speed
··········· ruleFired = True
········ ENDIF
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- Stephen
' {$STAMP BS2}
' {$PBASIC 2.5}
'******************************************************************************
'Joshua Endicott
'Mechanical Engineering Technology Student
'WVU Institute of Technology
'******************************************************************************
' A HMC6352 compass module and sonar PING are used to steer a straight path
' and follow the a Wall
'
'.............................................................................
' Circuit Diagram
'..............................................................................
'
' BS2 | +5v
' | |
' |
' | | |
' pin 0|
| I/O |
' | | Sonar |
' | | |
' |
' | |
' | ---
' | -
' |
' | +5v
' | |
' |
' | | |
' pin 9|
| Data |
' | | HMC6352 |
' | | |
' pin 8|
| Clock |
' | | |
' |
' | |
' | ---
' | -
' |
' pin 13|
' | |
' pin 12|
____|____
' | | +5vdc | |
' | ____|____ | | Right |
' | +5vdc | | ---| Servo |
' | | | Left | | |
' | ---| Servo | |_________|
' | | | |
' | |_________| ---
' | | -
' | ---
' | -
'______________|
'
'..............................................................................
'******************************************************************************
' System Constants
'******************************************************************************
wallOffset CON 2000
someTolerance CON 100
' System Constants
'******************************************************************************
' Used by the Compass module
HMC6352_READ CON $43
HMC6352_WRITE CON $42
GET_HEADING CON $41
sck CON 1
sio CON 0
'...Program Constants
True CON 1
False CON 0
'
' Number Ranges
'.....................................
' range 0 --> 32766 positive
' +0 --> + 32766
'.....................................
' range 65535 --> 32767 negative
' -1 --> -32767
'.....................................
MaxNum CON 65535
halfMaxNum CON 32767
'...Motor Constants
'
RightZeroSpeed CON 750
LeftZeroSpeed CON 750
speed CON 200
turnspeed CON 50
'...Allowable drift degrees *10
delta CON 50
'******************************************************************************
' I/O Pin Assignments
'******************************************************************************
PING PIN 10 ' Sonar
SDA PIN 9 ' Compass Data pin
SCL PIN 8 ' COmpas clock pin
RightServo PIN 13
LeftServo PIN 12 '
'******************************************************************************
' Variables
'******************************************************************************
Theta VAR Word ' Commanded heading
Heading VAR Word ' Actual Heading
h1 VAR Word ' Past Headings for
h2 VAR Word ' data smoothing
h3 VAR Word
h4 VAR Word
diff VAR Word ' Heading - Theta
absDiff VAR Word ' ABS(Heading - Theta)
dir VAR Bit ' Left/Right direction flag
ruleFired VAR Word ' Rule Flag
I2C_DATA VAR Byte ' Compass
I2C_LSB VAR Bit ' Compass
sonarDistance VAR Word
oldSonar VAR Word
'******************************************************************************
' Main Control Loop
'******************************************************************************
DO
'
' get Sensors
'
GOSUB getSonar
'
' Check Rules Only one will fire per loop
'
ruleFired = False
Rule1: ' Go a bit left
IF ((sonarDistance > (wallOffset + someTolerance) AND (sonarDistance < 3000))) THEN
PULSOUT RightServo, RightZeroSpeed - speed
PULSOUT LeftServo, LeftZeroSpeed + turnspeed
ruleFired = True
ENDIF
Rule2: ' Go a bit right
IF (sonarDistance < (wallOffset - someTolerance)) THEN
PULSOUT RightServo, RightZeroSpeed - turnspeed
PULSOUT LeftServo, LeftZeroSpeed + speed
ruleFired = True
ENDIF
Rule3: ' Go forward
IF (sonarDistance = ((wallOffset - someTolerance) OR (wallOffset + someTolerance)) AND (ruleFired = False)) THEN
PULSOUT RightServo, RightZeroSpeed - speed
PULSOUT LeftServo, LeftZeroSpeed + speed
GOSUB Compass_Get_Heading 'return Heading
h1 = Heading
Heading = (h1 + h2 +h3 + h4) /4 ' Average
h4 = h3 : h3 = h2 : h2 = h1 ' Shift
diff = Heading - Theta
absDiff = ABS(diff)
IF absDiff > 1800 THEN absDiff = 3600 - absdiff
IF (absDiff + Theta)//3600 = Heading THEN :dir = 0 :ELSE :dir =1 :ENDIF
DEBUG DEC heading, LF
ruleFired = True
ENDIF
Rule4:
IF ((sonardistance > 3000)) THEN
Rule0: ' Go a bit left based on Compass
IF (absDiff > delta) AND (dir =0) AND (ruleFired = False) THEN
PULSOUT RightServo, RightZeroSpeed - speed
PULSOUT LeftServo, LeftZeroSpeed + turnspeed
ruleFired = True
ENDIF
Rule5: ' Go forward based on Compass
IF (absDiff = delta ) AND (ruleFired = False) THEN
PULSOUT RightServo, RightZeroSpeed - speed
PULSOUT LeftServo, LeftZeroSpeed + speed
ruleFired =True
ENDIF
Rule6: ' Go a bit right based on Compass
IF (absDiff < delta) AND (dir =0) AND (ruleFired = False) THEN
PULSOUT RightServo, RightZeroSpeed - turnspeed
PULSOUT LeftServo, LeftZeroSpeed + speed
ruleFired =True
ENDIF
ENDIF
LOOP
'******************************************************************************
Compass_Get_Heading: ' Compass module subroutine return Heading
'
GOSUB I2C_Start
I2C_DATA = HMC6352_WRITE
GOSUB I2C_Write
I2C_DATA = GET_HEADING
GOSUB I2C_Write
GOSUB I2C_Stop
GOSUB I2C_Start
I2C_DATA = HMC6352_READ
GOSUB I2C_Write
PAUSE 6
GOSUB I2C_Read
Heading.HIGHBYTE = I2C_DATA
GOSUB I2C_ACK
GOSUB I2C_Read
Heading.LOWBYTE = I2C_DATA
GOSUB I2C_NACK
GOSUB I2C_Stop
RETURN
'..............................................................................
'
I2C_Start: ' Compass
'
LOW SDA
LOW SCL
RETURN
'..............................................................................
'
I2C_Stop: ' Compass
'
LOW SDA
INPUT SCL
INPUT SDA
RETURN
'..............................................................................
'
I2C_ACK: ' Compass
'
LOW SDA
INPUT SCL
LOW SCL
INPUT SDA
RETURN
'..............................................................................
'
I2C_NACK: ' Compass
'
INPUT SDA
INPUT SCL
LOW SCL
RETURN
'..............................................................................
'
I2C_Read: ' Compass
'
SHIFTIN SDA, SCL, MSBPRE, [noparse][[/noparse]I2C_DATA]
RETURN
'..............................................................................
'
I2C_Write: ' Compass
'
I2C_LSB = I2C_DATA.BIT0
I2C_DATA = I2C_DATA / 2
SHIFTOUT SDA, SCL, MSBFIRST, [noparse][[/noparse]I2C_DATA\7]
IF I2C_LSB THEN INPUT SDA ELSE LOW SDA
INPUT SCL
LOW SCL
INPUT SDA
INPUT SCL
LOW SCL
RETURN
'..............................................................................
'******************************************************************************
' getSonar return sonarDistnce
'******************************************************************************
getSonar:
PING = 10 ' make trigger 0-1-0
PULSOUT PING, 13 ' activate sensor
PULSIN PING, 1, sonarDistance ' measure echo pulse
'... Make sure a non zero reading is obtained
IF sonarDistance = 0 THEN sonarDistance = oldSonar
oldSonar = sonarDistance
DEBUG DEC sonarDistance, LF
RETURN
Try putting the code for rule 4 above rule 1 in the code.
Take out the "AND (sonarDistance < 3000)" in rule 1 and add "AND (ruleFired = False)" in the IF THEN for rules 1 and 2
Otherwise, it looks like it might work, but add something to make sure that if the ping is interrupted before four program loops so that the averaging wont return a bad heading target (i.e. program looped three times, actual heading is 180 degrees, average returns a target heading of (0+180+180+180)/4= 135 degrees, robot turns 45 degrees off course).