BoeBot Escape Corners - add beeps to indicate value in counter variable - fails
John Kauffman
Posts: 653
In the Boe-BOT text ver 3.0, the last exercise in the whiskers chapter uses the file EscapeCorners.BS2. It contains four sections:
'
[ Variables , Initialization ]
'
[ Main Routine ] - Checks if stuck and if so escape
' --- [Tactile navigation from RoamingWithWhiskers.bs2]
'
[ Subroutines ] - Forward, back, etc.
In the process of checking for being stuck, a COUNTER var is incremented. My goal is to provide an audible signal to express the value in the COUNTER. Each time the counter changed there will be a number of beeps = the new value.
The original EscapingCorners.BS2 tested and works in all aspects.
I added after each change to COUNTER: For Next with upperbound of COUNTER and in the loop a beep.
‘ After each increment of COUNTER
counter = counter + 1 ' from original code
FOR nibBeepCounter = 1 TO Counter
FREQOUT 4, 500, 2000, 3000
PAUSE 250
NEXT
Symptoms:
The result is erratic – I can not figure out the pattern of beeps – it does not match the counter value.
The beeps are also of abnormally low volume
Diagnostic Observation:
If I drop the duration of the beep from 500 mSec to 10 mSec and the pause to from 250 mSec to 10 mSec it works (albeit very fast).
Troubleshooting to date:
- Variable size: nibBeepCounter never goes above 5.
- COUNTER is used both to hold the counts for the escape decision and as the end value on the loop of beeps, but I don’t think those two uses will interfere with each other.
Any help would be appreciated. Code attached and listed
'
[ Title ]
' Robotics with the Boe-Bot - EscapingCorners.bs2
'
[ Variables ]
pulseCount VAR Byte ' FOR...NEXT loop counter.
counter VAR Nib ' Counts alternate contacts.
old7 VAR Bit ' Stores previous IN7.
old5 VAR Bit ' Stores previous IN5.
nibBeepCounter VAR Nib
'
[ Initialization ]
FREQOUT 4, 2000, 3000 ' Signal program start/reset.
counter = 1 ' Start alternate corner count.
' **** addition of loop below
FOR nibBeepCounter = 1 TO Counter
FREQOUT 4, 500, 2000, 3000
PAUSE 250
NEXT
' **** addition of loop above
old7 = 0 ' Make up old values.
old5 = 1
'
[ Main Routine ]
DO
' --- Detect Consecutive Alternate Corners
' See the "How EscapingCorners.bs2 Works" section that follows this program.
IF (IN7 <> IN5) THEN ' One or other is pressed.
IF (old7 <> IN7) AND (old5 <> IN5) THEN ' Different from previous.
counter = counter + 1 ' Alternate whisker count + 1.
' **** addition of loop below
FOR nibBeepCounter = 1 TO Counter
FREQOUT 4, 10, 2000, 3000
PAUSE 10
NEXT
' **** addition of loop above
old7 = IN7 ' Record this whisker press
old5 = IN5 ' for next comparison.
IF (counter > 4) THEN ' If alternate whisker count = 4,
counter = 1 ' reset whisker counter
FREQOUT 4,500,1500,2000
PAUSE 250
FREQOUT 4,500,1500,2000
PAUSE 250
GOSUB Back_Up ' and execute a U-turn.
GOSUB Turn_Left
GOSUB Turn_Left
ENDIF ' ENDIF counter > 4.
ELSE ' ELSE (old7=IN7) or (old5=IN5),
counter = 1 ' not alternate, reset counter.
ENDIF ' ENDIF (old7<>IN7) and
' (old5<>IN5).
ENDIF ' ENDIF (IN7<>IN5).
' --- Same navigation routine from RoamingWithWhiskers.bs2
IF (IN5 = 0) AND (IN7 = 0) THEN ' Both whiskers detect obstacle
GOSUB Back_Up ' Back up & U-turn (left twice)
GOSUB Turn_Left
GOSUB Turn_Left
ELSEIF (IN5 = 0) THEN ' Left whisker contacts
GOSUB Back_Up ' Back up & turn right
GOSUB Turn_Right
ELSEIF (IN7 = 0) THEN ' Right whisker contacts
GOSUB Back_Up ' Back up & turn left
GOSUB Turn_Left
ELSE ' Both whiskers 1, no contacts
GOSUB Forward_Pulse ' Apply a forward pulse
ENDIF ' and check again
LOOP
'
[ Subroutines ]
Forward_Pulse: ' Send a single forward pulse.
PULSOUT 13,850
PULSOUT 12,650
PAUSE 20
RETURN
Turn_Left: ' Left turn, about 90-degrees.
FOR pulseCount = 0 TO 20
PULSOUT 13, 650
PULSOUT 12, 650
PAUSE 20
NEXT
RETURN
Turn_Right:
FOR pulseCount = 0 TO 20 ' Right turn, about 90-degrees.
PULSOUT 13, 850
PULSOUT 12, 850
PAUSE 20
NEXT
RETURN
Back_Up: ' Back up.
FOR pulseCount = 0 TO 40
PULSOUT 13, 650
PULSOUT 12, 850
PAUSE 20
NEXT
RETURN
'
[ Variables , Initialization ]
'
[ Main Routine ] - Checks if stuck and if so escape
' --- [Tactile navigation from RoamingWithWhiskers.bs2]
'
[ Subroutines ] - Forward, back, etc.
In the process of checking for being stuck, a COUNTER var is incremented. My goal is to provide an audible signal to express the value in the COUNTER. Each time the counter changed there will be a number of beeps = the new value.
The original EscapingCorners.BS2 tested and works in all aspects.
I added after each change to COUNTER: For Next with upperbound of COUNTER and in the loop a beep.
‘ After each increment of COUNTER
counter = counter + 1 ' from original code
FOR nibBeepCounter = 1 TO Counter
FREQOUT 4, 500, 2000, 3000
PAUSE 250
NEXT
Symptoms:
The result is erratic – I can not figure out the pattern of beeps – it does not match the counter value.
The beeps are also of abnormally low volume
Diagnostic Observation:
If I drop the duration of the beep from 500 mSec to 10 mSec and the pause to from 250 mSec to 10 mSec it works (albeit very fast).
Troubleshooting to date:
- Variable size: nibBeepCounter never goes above 5.
- COUNTER is used both to hold the counts for the escape decision and as the end value on the loop of beeps, but I don’t think those two uses will interfere with each other.
Any help would be appreciated. Code attached and listed
'
[ Title ]
' Robotics with the Boe-Bot - EscapingCorners.bs2
'
[ Variables ]
pulseCount VAR Byte ' FOR...NEXT loop counter.
counter VAR Nib ' Counts alternate contacts.
old7 VAR Bit ' Stores previous IN7.
old5 VAR Bit ' Stores previous IN5.
nibBeepCounter VAR Nib
'
[ Initialization ]
FREQOUT 4, 2000, 3000 ' Signal program start/reset.
counter = 1 ' Start alternate corner count.
' **** addition of loop below
FOR nibBeepCounter = 1 TO Counter
FREQOUT 4, 500, 2000, 3000
PAUSE 250
NEXT
' **** addition of loop above
old7 = 0 ' Make up old values.
old5 = 1
'
[ Main Routine ]
DO
' --- Detect Consecutive Alternate Corners
' See the "How EscapingCorners.bs2 Works" section that follows this program.
IF (IN7 <> IN5) THEN ' One or other is pressed.
IF (old7 <> IN7) AND (old5 <> IN5) THEN ' Different from previous.
counter = counter + 1 ' Alternate whisker count + 1.
' **** addition of loop below
FOR nibBeepCounter = 1 TO Counter
FREQOUT 4, 10, 2000, 3000
PAUSE 10
NEXT
' **** addition of loop above
old7 = IN7 ' Record this whisker press
old5 = IN5 ' for next comparison.
IF (counter > 4) THEN ' If alternate whisker count = 4,
counter = 1 ' reset whisker counter
FREQOUT 4,500,1500,2000
PAUSE 250
FREQOUT 4,500,1500,2000
PAUSE 250
GOSUB Back_Up ' and execute a U-turn.
GOSUB Turn_Left
GOSUB Turn_Left
ENDIF ' ENDIF counter > 4.
ELSE ' ELSE (old7=IN7) or (old5=IN5),
counter = 1 ' not alternate, reset counter.
ENDIF ' ENDIF (old7<>IN7) and
' (old5<>IN5).
ENDIF ' ENDIF (IN7<>IN5).
' --- Same navigation routine from RoamingWithWhiskers.bs2
IF (IN5 = 0) AND (IN7 = 0) THEN ' Both whiskers detect obstacle
GOSUB Back_Up ' Back up & U-turn (left twice)
GOSUB Turn_Left
GOSUB Turn_Left
ELSEIF (IN5 = 0) THEN ' Left whisker contacts
GOSUB Back_Up ' Back up & turn right
GOSUB Turn_Right
ELSEIF (IN7 = 0) THEN ' Right whisker contacts
GOSUB Back_Up ' Back up & turn left
GOSUB Turn_Left
ELSE ' Both whiskers 1, no contacts
GOSUB Forward_Pulse ' Apply a forward pulse
ENDIF ' and check again
LOOP
'
[ Subroutines ]
Forward_Pulse: ' Send a single forward pulse.
PULSOUT 13,850
PULSOUT 12,650
PAUSE 20
RETURN
Turn_Left: ' Left turn, about 90-degrees.
FOR pulseCount = 0 TO 20
PULSOUT 13, 650
PULSOUT 12, 650
PAUSE 20
NEXT
RETURN
Turn_Right:
FOR pulseCount = 0 TO 20 ' Right turn, about 90-degrees.
PULSOUT 13, 850
PULSOUT 12, 850
PAUSE 20
NEXT
RETURN
Back_Up: ' Back up.
FOR pulseCount = 0 TO 40
PULSOUT 13, 650
PULSOUT 12, 850
PAUSE 20
NEXT
RETURN
Comments
I really am stuck on it (not posted as a puzzler).
Don't be intimidated by amount of code. It is just EscapeCorners.bs2 with two places where COUNTER is incremented I added a 4-line loop.
Thanks.
1. You are a little inconsistant using the variable name counter, you have it defined as "counter" {counter VAR Nib ' Counts alternate contacts.} but then use it later as "Counter" {FOR nibBeepCounter = 1 TO Counter}. I dont remember if PBASIC is case sensitive for sure, but I think it is.
2. counter is defined as a Nib, pretty sure that means: two bits, for a total of four values, 00, 01, 10, 11. so counter can have four values ranging from 0 to 3, but it's not big enough to hold the value 4. This makes me question the compare statement {IF (counter > 4) THEN ' If alternate whisker count = 4,}
I hope this helps.
Good thought on re-checking var size. Nib is four bits (0-15) so values up to five should be OK.
But I still wonder if somehow I am over-running the 15 because illogical results are often from that error.
I agree I am inconsistent with var case - but I don't think it is a problem in PBasic. Following four-line program tokenizes. It would not if PBasic were case sensitive because last two lines would assign a value to non-existent var
ABC VAR Byte
ABC = 5
abc = 5
AbC = 5
I'm thinking we are still stuck on a solution.
I originally had duration of the beep 500 mSec and the pause 250 mSec.
In a series of diagnostic tests I tried changing that duration and pause to a very low value and I think, maybe, it worked (almost out of range of human perception, so it could be my wishful thinking.)
The code I posted was after that diagnostic test. When beep duration is 500 and pause 250, then fails - beep pattern does not match expected.
Any other thoughts? Thanks.