The switch needs a pullup resistor. I assume you mean you want to read the switch often, but take some particular action if the switch stays open for longer than 1/4 second?
Assuming that closed gives a low level and open is high level...
Method 1, if the program can pause to see if the switch stays open for > 1/4 second.
DO
' stuff
IF switch=1 THEN '
PAUSE 250
IF switch=1 THEN ' still open after 1/4 second
' do something
ENDIF
ENDIF
' other stuff
LOOP
Method 2, if counting the 1/4 second has to be merged into other tasks.
switch VAR in0 ' switch attached to in0 with pullup
ticks VAR byte
DO
' stuff
IF switch=1 THEN '
ticks=ticks + 1 MAX 25 ' or MAX 26 if it needs single shot action
ELSE
ticks=0 ' reset timer
ENDIF
IF ticks=25 THEN ' still open after 1/4 second
' do something
ENDIF
ENDIF
' other stuff
PAUSE 8 ' 8 milliseconds per loop available for more program tasks. Main loop runs in around 10 milliseconds.
LOOP
There are a lot of ways to do this, but you have to provide more detail about the goal.
I am making a robotic lawn mower that uses Sonar for the main object detection. I am dragging a switch in grass to determine if the robot was in grass or on a drive way, If in the grass the switch would be closed and open on the driveway, I am assuming the switch is going to open and close a lot in the grass so I wanted a pause before the robot reacted.
I updated the code and this only seems to work the first time it runs the program what should I change? Thanks for any ones help.
' {$STAMP BS2}
' {$PBASIC 2.5}
Ping PIN 14
PingServo PIN 0
LeftServo PIN 13
RightServo PIN 12
rawDist VAR Word
sweepcount VAR Word
x VAR Byte
pulseCount VAR Byte
switch VAR IN15
Ticks VAR Byte
DO
DEBUG ? IN15
FOR sweepcount = 350 TO 1150 STEP 200
FOR x = 0 TO 1
PULSOUT 0, sweepcount
PAUSE 20
NEXT
GOSUB GetSonar
NEXT
FOR sweepcount = 950 TO 550 STEP 200
FOR x = 0 TO 1
PULSOUT 0, sweepcount
PAUSE 20
NEXT
GOSUB GetSonar
NEXT
IF switch=0 THEN ' 'change 1 and 0 for real run
ticks=ticks + 1 MAX 25 ' or MAX 26 if it needs single shot action
ELSE
ticks=0 ' reset timer
ENDIF
IF ticks=1 THEN ' still open after 1/4 second
GOSUB Back_Up
GOSUB Turn_Left
GOSUB Turn_left
ENDIF
PAUSE 8 ' 8 milliseconds per loop available for more program tasks. Main loop runs in around 10 milliseconds.
I think you probably want,
IF ticks=25 THEN ...
instead of
IF ticks=1 THEN ...
That is because ticks counts up and is only at 1 for one cyclee, and the time limit happens when ticks=25 and stays there so long as the switch remains closed (switch=0). Also, your loop probably takes a lot longer than 10 milliseconds to execute, so it may be necessary to play with that limit.
limit CON 25 ' <---- play with this number to get the best time out limit
ticks=ticks + 1 MAX limit
'and later...
IF ticks=limit THEN ...
And defensive coding would use ">=" -- just on principle, it's safer to check for "greater than or equal" than simply "equal". Logically there's no difference, but "Greater than or equal" catches more conditions, and is therefore safer.
Comments
Assuming that closed gives a low level and open is high level...
Method 1, if the program can pause to see if the switch stays open for > 1/4 second.
Method 2, if counting the 1/4 second has to be merged into other tasks.
There are a lot of ways to do this, but you have to provide more detail about the goal.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com
' {$STAMP BS2}
' {$PBASIC 2.5}
Ping PIN 14
PingServo PIN 0
LeftServo PIN 13
RightServo PIN 12
rawDist VAR Word
sweepcount VAR Word
x VAR Byte
pulseCount VAR Byte
switch VAR IN15
Ticks VAR Byte
DO
DEBUG ? IN15
FOR sweepcount = 350 TO 1150 STEP 200
FOR x = 0 TO 1
PULSOUT 0, sweepcount
PAUSE 20
NEXT
GOSUB GetSonar
NEXT
FOR sweepcount = 950 TO 550 STEP 200
FOR x = 0 TO 1
PULSOUT 0, sweepcount
PAUSE 20
NEXT
GOSUB GetSonar
NEXT
IF switch=0 THEN ' 'change 1 and 0 for real run
ticks=ticks + 1 MAX 25 ' or MAX 26 if it needs single shot action
ELSE
ticks=0 ' reset timer
ENDIF
IF ticks=1 THEN ' still open after 1/4 second
GOSUB Back_Up
GOSUB Turn_Left
GOSUB Turn_left
ENDIF
PAUSE 8 ' 8 milliseconds per loop available for more program tasks. Main loop runs in around 10 milliseconds.
LOOP
'
Sub
GetSonar:
LOW Ping
PULSOUT Ping, 5
PULSIN Ping, 1, rawDist
IF (rawDist < 2200) THEN ' adjust to change distance
IF (sweepcount < 750) THEN
GOSUB Back_Up
GOSUB Turn_Left
ELSEIF (sweepcount > 750) THEN
GOSUB Back_Up
GOSUB Turn_Right
ENDIF
ELSE
GOSUB Forward_Pulse
ENDIF
RETURN
Forward_Pulse:
IF (IN10 = 1) THEN ' Left Bumper Contact
GOSUB Back_Up ' Back up & turn right
GOSUB Turn_Right
GOSUB Turn_Right
ELSEIF (IN9 = 1) THEN ' Right Bumper Contact
GOSUB Back_Up ' Back up & turn right
GOSUB Turn_left
GOSUB Turn_Left
ENDIF
FOR pulsecount = 0 TO 5
PULSOUT LeftServo, 850
PULSOUT RightServo, 650
PAUSE 20
NEXT
RETURN
Turn_Left:
FOR pulseCount = 0 TO 20
PULSOUT LeftServo, 650
PULSOUT RightServo, 650
PAUSE 20
NEXT
RETURN
Turn_Right:
FOR pulseCount = 0 TO 20
PULSOUT LeftServo, 850
PULSOUT RightServo, 850
PAUSE 20
NEXT
RETURN
Back_Up:
FOR pulseCount = 0 TO 40
PULSOUT LeftServo, 650
PULSOUT RightServo, 850
PAUSE 20
NEXT
FOR pulseCount = 0 TO 7
PULSOUT LeftServo, 650
PULSOUT RightServo, 850
PAUSE 20
NEXT
RETURN
IF ticks=25 THEN ...
instead of
IF ticks=1 THEN ...
That is because ticks counts up and is only at 1 for one cyclee, and the time limit happens when ticks=25 and stays there so long as the switch remains closed (switch=0). Also, your loop probably takes a lot longer than 10 milliseconds to execute, so it may be necessary to play with that limit.
limit CON 25 ' <---- play with this number to get the best time out limit
ticks=ticks + 1 MAX limit
'and later...
IF ticks=limit THEN ...
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com