Let's Make Robots!

seriously messed up program or a small mistake? - new

hi peeps

 

wasnt sure where to put this but i decided as im utterly clueless this would be a good place to start.

i finally completed my akira programming (after a sleep deprived war with the "if/elseif" protocol) and frankly rather than being over joyed the only sound from my mouth was - "huh?".

the ultrasonic detection has gone out of the window (every now and again it spots something at its side - twitches then resets itself - the rest of the time its blind)

this is my first time at pbasic - i tested all the sections individually and they were fine - but combined its just a gibbering mess

the site wouldnt allow upload so ive just cut, paste and am now hoping for genius inspiration

thanks guys

 

dom

update : 26-08-12

 

thanks to your advice and a lot of instruction reading ive managed to produce something much closer to what i was after...

only problem is that its still as blind as a bat - (slight ultrasonic joke there ;)  )

if i stand in front of akira (and keep shuffleing to the side) it eventually spots me - but it quite happily runs straight into the wall and starts humping it without any real reaction. i tested that the activation of the tracks wasnt interfering with the ultrasonics so im still a bit lost.

ive changed all the dodgy goto's and gosubs and overall it should be much cleaner but i still think im missing a major blaringly obvious mistake - so again im asking for your help.

ive replaced the ver1 with ver2 as you'll see below

 

thanks again peeps

 

dominic

 

10:09:12

ive updated it again mainly to keep myself up to speed and cos im going to create a link to it

dom

 

; Akira version 2


; Pin names

; Digital output
symbol doutpin0 = B.0    ;servo - could symbol it "servo" - ive left it for now
symbol doutpin1 = B.1   
symbol doutpin2 = B.2    ;LED (red)
symbol doutpin3 = B.3    ;Trig pulse, ultrasonic sensor (direct chip output)
symbol doutpin4 = B.4    ;motor A
symbol doutpin5 = B.5    ;motor A
symbol doutpin6 = B.6    ;motor B
symbol doutpin7 = B.7    ;motor B

; Digital input
symbol dinpin0 = pin0
symbol dinpin1 = pin1
symbol dinpin2 = pin2
symbol dinpin3 = pin3    ;push button input
symbol dinpin4 = pin4
symbol dinpin5 = pin5
symbol dinpin6 = pin6    ;Echo, ultrasonic sensor
symbol dinpin7 = pin7

; Analogue input
;symbol aninpin0 = c.0
;symbol aninpin1 = c.1   
;symbol aninpin2 = c.2
;symbol aninpin3 = c.3

; General symbols
symbol LED = B.2



; Variable symbols
'    (byte variables [bx] can store integer numbers between 0 and 255)
;    (word variables [wx] can store integer numbers between 0 and 65535)
;    (bit variables  [bitx] can store single bits - ie 1 or 0)





;list (to keep track)

;b0 = bit variable = bit7: bit6: bit5: bit4: bit3: bit2: bit1: bit0
;b1 = bit variable = bit15: bit14: bit13: bit12: bit11: bit10: bit9: bit8

;b2 =  vgap     variable gap
;b3 =  vgap2

;(b5:b4) = w2 = range ; 16 bit word variable for range (ultrasonic input)
;(b7:b6) = w3
;(b9:b8) = w4
;(b11:b10) = w5

;
;b12 = forward distance
;b13 = left distance
;b14 = right distance
;b15 = ultrasonic detector output (in cm)
;b16 = headbutt = danger (getting too close - 1= do something , 0 = safe)
;b17 = headshake (distance scan count)
;b18= hell - just to keep it looping for now
;b19 = left
;b20 = right


symbol vgap = b2        ;variable gap
    let vgap = 1    ;vgap = 1 as standard (no real difference)
   
symbol vgap2 = b3        ;variable gap
    let vgap2 = 1    ;wait vgap = 1 as standard
   
symbol for_distance = b12

symbol left_distance = b13

symbol right_distance = b14
   
symbol headbutt = b16    ;getting too close
    let headbutt = 0    ;0=safe
   
symbol headshake = b17

symbol hell = b18
    let hell = 0
   
symbol left = b19
    let left = 0
symbol right = b20
    let right = 0
   

;Ultrasonic detector

symbol trig = 3 ; Define output pin for Trigger pulse
;- seems happy with just 3 not B.3
symbol echo = 6 ; Define input pin for Echo pulse
; - again happy with 6 not pin6
symbol range = w2 ; 16 bit word variable for range (ultrasonic input)
            ; removes the need for the max 250 safety check
symbol distance = b15    ;ultrasonic detector output (is this needed? - no
                ;- its the origional test version - max was 255
                ;leave it in in case you revert - reverted - see notes








;  program start


main:


;debug distance; option for testing - does not require a specific variable


;wake up - servo and led
gosub wakeup

;push button input
gosub pushbutton

;pause to allow fingers to escape
pause 500

;LED on (stays on for duration)
gosub ledon


do


static_scan: ;(to get us started)

    ;standard scan
   
gosub servo_standard


;does forward direction have more than 20cm free movement?
; yes? we are off (goto mobile scan)

if for_distance > 20 then goto mobile_scan


   
    ; no? out of left and right which has more space?
   

   
if left_distance > right_distance then gosub akira_left_turn    
; left? then turn left and check again

if left_distance < right_distance then gosub akira_right_turn     
; right? then turn right and check again


pause 2500 ;wait 2.5 seconds ie 90 degree turn
gosub akira_stop

   
   
goto static_scan    ; check again with a static scan
   
   
mobile_scan:

    ;move forward
   
gosub akira_forward
   
    ;scan (distance) 5 times or till object spotted (15cm)
   
for headshake = 1 to 5
gosub servo_distance
if headbutt = 1 then exit
next headshake
   
    ;scan (sweep) once
   
gosub servo_sweep
   
    ;tweak away from any object
   
if headbutt = 1 and left = 0 and right = 0 then goto static_scan                ;front

if headbutt = 1 and left = 0 and right = 1 then gosub akira_left_tweak        ;right
if headbutt = 1 and left = 0 and right = 2 then gosub akira_left_tweak        ;far right

if headbutt = 1 and left = 1 and right = 0 then gosub akira_right_tweak        ;left
if headbutt = 1 and left = 2 and right = 0 then gosub akira_right_tweak        ;far left

if headbutt = 1 and left >= 1 and right >=1 then goto static_scan


   
    ;carry on mobile scan unless...
   
goto mobile_scan
   
    ;less than 10cm means stop and turn (ie goto main)
   
   
loop until hell = 1 ; frozen over





goto main    ; pure paranoia - but you never know

stop




; Main program end


; Gosubs


; Wake up

wakeup:
servo doutpin0, 150    ;center the servo
    pause 200
   
for vgap = 1 to 3         ;three LED flashes
gosub ledflash
next vgap
return
   
   
; push button input

pushbutton:
;if dinpin3 = 1 then return
;    else goto pushbutton
;    endif
;return


'Loop until pushbutton is pressed.
do while dinpin3 = 0
loop
return



;symbol dinpin3 = pin3    ;push button input
; also needs a voltage from this section to power the switch



; LED gosubs


; General symbols
; symbol LED = B.2


ledflash:     ;one flash,0.5 sec gap
    high led
    pause 500
    low led
    pause 500
    return

ledon:
    high led
    return

ledoff:
    low led
    return
       
       
;movement


;right forward

;high 5
;low 4


;left forward

;high 6
;low 7

; 2 meters
;20 sec
;thus 1m in 10 sec or 10cm per sec

;turning
;right angle = 8 sec however this is with full grip which causes damage
;with PVA glue - one revolution = 9 sec




;Movement gosubs

akira_forward:

high 5
low 4
high 6
low 7
return

akira_stop:

low 5
low 4
low 6
low 7
return

akira_backwards:

low 5
high 4
low 6
high 7
return

akira_right_turn:

low 5
high 4
high 6
low 7
return

akira_left_turn:

high 5
low 4
low 6
high 7
return

akira_right_tweak:

low 5
low 4
high 6
low 7
pause 200    ;0.2 of a second
high 5    ;return to forward
low 4
high 6
low 7
pause 200
return

akira_left_tweak:

high 5
low 4
low 6
low 7
pause 200    ;0.2 of a second
high 5    ;return to forward
low 4
high 6
low 7
pause 200
return



; Servo movement

; Digital output
; symbol doutpin0 = B.0    ;servo

; note on pauses - the motor needs time to respond otherwise
;it moves staight onto the next command (you just get a shiver)
;(pause 100 is pretty much the absolute fastest... pause 150 is better)
;also - greater movement - greater time needed


   



servo_sweep:        ;use later

let headbutt = 0
let left = 0
let right = 0

gosub look_forward
gosub ultra
    if distance < 10 then gosub danger_forward
   
   
gosub look_little_right
gosub ultra
    if distance < 10 then gosub danger_right

gosub look_right
gosub ultra
    if distance < 7 then gosub more_danger_right

gosub look_forward
gosub ultra
    if distance < 10 then gosub danger_forward
   

gosub look_little_left
gosub ultra
    if distance < 10 then gosub danger_left

gosub look_left
gosub ultra
    if distance < 7 then gosub more_danger_left
   

return

danger_forward:
let headbutt = 1
return


danger_left:
let headbutt = 1
let left = 1
return


danger_right:
let headbutt = 1
let right = 1
return

more_danger_left:
let headbutt = 1
let left = 2
return


more_danger_right:
let headbutt = 1
let right = 2
return



servo_standard:        ;used for turning on the spot

gosub look_forward            ;allow time to reach
gosub ultra            ;ultrasonic the range
let for_distance = distance        ;transfer range info to forward distance variable

gosub look_left
gosub ultra
let left_distance = distance

gosub look_forward

gosub look_right
gosub ultra
let right_distance = distance

gosub look_forward
return


servo_distance:        ;checks general area in front - no specifics

let headbutt = 0

gosub look_forward
gosub ultra
    if distance < 15 then let headbutt = 1
    endif

gosub glimpse_right
gosub ultra
    if distance < 15 then let headbutt = 1
    endif

gosub look_forward
gosub ultra
    if distance < 15 then let headbutt = 1
    endif

gosub glimpse_left
gosub ultra
    if distance < 15 then let headbutt = 1
    endif

return






    ;ver 2
   
look_forward:    ;150
servopos doutpin0, 150   
pause 200
return


look_left:        ;225
servopos doutpin0, 225   
pause 200
return


look_right:        ;75
servopos doutpin0, 75   
pause 200
return


look_little_left:    ;185
servopos doutpin0, 185   
pause 200
return


look_little_right:;115
servopos doutpin0, 115   
pause 200
return


glimpse_left:    ;170
servopos doutpin0, 170
pause 200
return


glimpse_right:    ;130
servopos doutpin0, 130   
pause 200
return




;Ultrasonic detector

;symbol trig = 3 ; Define output pin for Trigger pulse
;symbol echo = 6 ; Define input pin for Echo pulse
;symbol range = w1 ; 16 bit word variable for range
;symbol distance = b15    ;ultrasonic detector output



ultra:
pulsout trig,2 ; produce 20uS trigger pulse (must be minimum of 10uS)
pulsin echo,1,range ; measures the range in 10uS steps
pause 10 ; recharge period after ranging completes
; now convert range to cm (divide by 5.8) or inches (divide by 14.8)
; as picaxe cannot use 5.8, multiply by 10 then divide by 58 instead
let distance = range * 10 / 58 ; multiply by 10 then divide by 58
debug range ; display range via debug command (optional for testing) - repositioned
return ; and around forever

; 95cm max? (it changes - 50 cm was v accurate)...other than that...spot on
; output is on b7 variable - w1 or range works just as well









end ;of program


; notes 19:9:12

;changed pushbutton loop to birds version - its just cleaner
; w1 variable was also your vgaps - changed to w2

;replaced let range = range * 10 / 58 with distance - b variable might need less time





;new notes

;repeated servo twitch pre button push (only slight but why?)

; general movement is closer to what i planned except for the fact that the little
; bugger needs glasses (which is complicated for a sound based vision system)
; is it a slow reaction time or do i have the reaction distance wrong?



;old Notes (pre 26-08-12)


;something is causing it to go back to the very beginning (pre pushbutton)
; as this doesnt happen in simulate im thinking an input is the cause

;ultrasonics appear completely useless - only serious pestering causes response

;managed a tweak - servo stuck left

;ultrasonics work better with a white board - dont ask

;board on left = left servo freeze then reset

;board on right = left servo freeze then reset (one example of a correct turn tho)






Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

As far as I can tell, your Servo_sweep code is wrong.

In the mobile_scan section, you gosub servo_sweep and test for values 1 to 6 and everything above or equal to 7 is an error. But in the servo_sweep section, you add your positions instead of setting the exact value, which pretty fast will give 7 and more.

my 5 cent so far.

 

that was exactly the kind of thing i was looking for

 

dom

hi

thanks to you lot i managed to get some movement from the little bugger and for that im very greatfull

thanks again

 

dom

I recommand using the SERVOPOS pin, pulse command instead of the SERVO pin, pulse command after you have initialised the servo with a SERVO pin, pulse command. This prevents resetting of the timer, which could
cause ‘jitter’. Make also sure to connect the signal line of the servo via a 330 Ω resistor with the output pin of your board.

I also recommand to re-organize the program. I would take the sensor readings with according if-then-checkbacks in the main routine and the according movements in subroutines.

the servo pos sounds live a smart move - as for the tidying up (reorganising) i was hoping to find the blaring mistakes first before i start that (but i do realise it may help find them too - we shall see)

 

dom

You are very thorough.

Pushing through your program I will attempt to make some points.

let vgap = 1 <-- Not required
for vgap = 1 to 3

pushbutton:
if dinpin3 = 1 then return
    else goto pushbutton
    endif
;you have no return, therefore your routine will fall through and make the LED blink again.

A different way to go about this:
pushbutton:
   'Loop until pushbutton is pressed.
   DO WHILE dinpin3 != 1
   LOOP
return

In your movement routines you call out pin numbers, yet you gave them labels/symbols at the beginning of your program. Pick one and stick with it. :P :)

For making pretty code, instead of main: goto main, consider
main:
   DO
   'main line code
   LOOP

 Your servo_sweep code could possibly make headbutt = a very large number, especially if you drive into a corner.

The following lines are pretty pointless:

;less than 10cm means stop and turn (ie goto main)

goto main

The program will never see them.

 

As I am not perfectly well versed in PICAXE, I believe the pushbutton function might need to be if dinpin3 = HIGH, or, as I wrote it DO WHILE dinpin3 != HIGH

so basically this kind of system prefers highs and lows rather than ones and zeros?

now i think on it that does make sense as a positive (high) input might still be a little variable so shouldnt realy be treated as a digital variable.

(oh - and if anyone says anything about it technically being a negative variable then i will "technically" travel over to thier country and slap them! ... theres nerd / geek and proud - and then theres just being annoying)

 

dom

perfect start to my tweaking

i love the vgap bit, not sure if the pushbutton needs changing but will try it none the less and the DO/LOOP skill is about to be added to my arsenal

turns out i wrote the vgap bit in the first place (im just starting to reposition everything tonight) - the point you were making was about fixing a value for the variable beforehand not being nessesary - does this mean the 

for vgap = 1 to 3

sets the variable to one for itself and never actually needs resetting - or for that matter variables dont actually need any form of pre-setting as they look after themselves?

 

dom