Button command problems
Hi guys,
I was hoping someone could help me out with a strange problem I am
experiencing using the button command.
I have 4 buttons connected to my stamp to pins 3,4,5 &6. They are
connected with a 1K resister in series with the pin and a 47k pullup
resister (As in Scott Edwards book). I also have a serial LCD at
pin15 and DS1302 (with 1 Farad super Cap) connected to pins 1,2 & 3.
Everything runs from a 5V 800mA regulated power supply.
I have this chunk of code to reset my LCD display, read the time from
the DS1302 and display the date and time. It reads 3 buttons and
loops back.
OUTS = %0000000000000000
DIRS = %1000000000000111
Setup:
For idx = 0 to 30
GOSUB rsdp
GOSUB ReadRTCBurst
serout 15,bps,[noparse][[/noparse]HEX2 Date,"/",HEX2 Month,"/",HEX2 Year," ", DEC2 12-
(24-(Hours.HIGHNIB*10+Hours.LOWNIB)//12),":",HEX2 Minutes,":",HEX2
Seconds]
serout 15,bps,[noparse][[/noparse]$FE,$C0," Change Date/Time?"]
serout 15,bps,[noparse][[/noparse]$FE,$94,"Field D/S EXIT"]
serout 15,bps,[noparse][[/noparse]$FE,$D4," Blk Yel Red WHT "]
BUTTON 3,0,255,250,BtnBLK,1,setDT
BUTTON 5,0,255,250,BtnRED,1,setDL
BUTTON 6,0,255,250,BtnWHT,1,exitDT
DEBUG DEC idx," "
NEXT
RETURN
This all seems to work fine, until I add code in the setDT or setDL
subroutines. When I run the program it appears as if the button pins
are "floating" and idx value randomly increments anywhere from 0 to
10 before exiting the loop and going to the setDL subroutine. If I
change the order of the Button commands it always exits at the first
one, if I use different pins, the same happens.
I have removed the code from the subroutines and it is working OK
again. If I press any of the buttons it exits the loop correctly.
If I let the loop run through the 30 count, it exits to another
similar piece of code and the buttons work correctly from there as
well. I have measured my voltage and it is a constant 4.99v at the
regulator and at the buttons.
Anyone have any thoughts? (Unfortunately I don't have all of the code
in tact as I changed it to use a serial 4 x 4 keypad instead.)
Thanks in advance
Cheers
Col
I was hoping someone could help me out with a strange problem I am
experiencing using the button command.
I have 4 buttons connected to my stamp to pins 3,4,5 &6. They are
connected with a 1K resister in series with the pin and a 47k pullup
resister (As in Scott Edwards book). I also have a serial LCD at
pin15 and DS1302 (with 1 Farad super Cap) connected to pins 1,2 & 3.
Everything runs from a 5V 800mA regulated power supply.
I have this chunk of code to reset my LCD display, read the time from
the DS1302 and display the date and time. It reads 3 buttons and
loops back.
OUTS = %0000000000000000
DIRS = %1000000000000111
Setup:
For idx = 0 to 30
GOSUB rsdp
GOSUB ReadRTCBurst
serout 15,bps,[noparse][[/noparse]HEX2 Date,"/",HEX2 Month,"/",HEX2 Year," ", DEC2 12-
(24-(Hours.HIGHNIB*10+Hours.LOWNIB)//12),":",HEX2 Minutes,":",HEX2
Seconds]
serout 15,bps,[noparse][[/noparse]$FE,$C0," Change Date/Time?"]
serout 15,bps,[noparse][[/noparse]$FE,$94,"Field D/S EXIT"]
serout 15,bps,[noparse][[/noparse]$FE,$D4," Blk Yel Red WHT "]
BUTTON 3,0,255,250,BtnBLK,1,setDT
BUTTON 5,0,255,250,BtnRED,1,setDL
BUTTON 6,0,255,250,BtnWHT,1,exitDT
DEBUG DEC idx," "
NEXT
RETURN
This all seems to work fine, until I add code in the setDT or setDL
subroutines. When I run the program it appears as if the button pins
are "floating" and idx value randomly increments anywhere from 0 to
10 before exiting the loop and going to the setDL subroutine. If I
change the order of the Button commands it always exits at the first
one, if I use different pins, the same happens.
I have removed the code from the subroutines and it is working OK
again. If I press any of the buttons it exits the loop correctly.
If I let the loop run through the 30 count, it exits to another
similar piece of code and the buttons work correctly from there as
well. I have measured my voltage and it is a constant 4.99v at the
regulator and at the buttons.
Anyone have any thoughts? (Unfortunately I don't have all of the code
in tact as I changed it to use a serial 4 x 4 keypad instead.)
Thanks in advance
Cheers
Col

Comments
Since the BUTTON command uses an address for branching, it's not ideal to use
more than one in a loop. My suggestion would be a custom scanning and
debouncing routine. The nice thing about it is that you'll use fewer
variables and with aliasing, you can keep your code very concise.
If you'll move your button inputs to pins 4 - 7, this routine will work for
you and return a "1" for any pressed button:
x VAR Nib
buttons VAR Nib
btn0 VAR buttons.Bit0
btn1 VAR buttons.Bit1
btn2 VAR buttons.Bit2
btn3 VAR buttons.Bit3
Get_Buttons:
buttons = %1111 ' assume pressed
FOR x = 1 TO 5
buttons = buttons & ~InB
PAUSE 5
NEXT
RETURN
The routine ensures that the button was held for the entire cycle by ANDing
the last current reading with the last. BTW, you can modify this routine to
work with any set of pins, you'll just have to preset and test each
individually.
Of course, you'll want to rename the bit variables to something that makes
more sense for your program.
-- Jon Williams
-- Applications Engineer, Parallax
In a message dated 6/26/02 7:56:51 AM Central Daylight Time,
aussiecol39@y... writes:
> Hi guys,
>
> I was hoping someone could help me out with a strange problem I am
> experiencing using the button command.
>
> I have 4 buttons connected to my stamp to pins 3,4,5 &6. They are
> connected with a 1K resister in series with the pin and a 47k pullup
> resister (As in Scott Edwards book). I also have a serial LCD at
> pin15 and DS1302 (with 1 Farad super Cap) connected to pins 1,2 & 3.
>
> Everything runs from a 5V 800mA regulated power supply.
>
> I have this chunk of code to reset my LCD display, read the time from
> the DS1302 and display the date and time. It reads 3 buttons and
> loops back.
>
> OUTS = %0000000000000000
> DIRS = %1000000000000111
> Setup:
> For idx = 0 to 30
> GOSUB rsdp
> GOSUB ReadRTCBurst
> serout 15,bps,[noparse][[/noparse]HEX2 Date,"/",HEX2 Month,"/",HEX2 Year," ", DEC2 12-
> (24-(Hours.HIGHNIB*10+Hours.LOWNIB)//12),":",HEX2 Minutes,":",HEX2
> Seconds]
> serout 15,bps,[noparse][[/noparse]$FE,$C0," Change Date/Time?"]
> serout 15,bps,[noparse][[/noparse]$FE,$94,"Field D/S EXIT"]
> serout 15,bps,[noparse][[/noparse]$FE,$D4," Blk Yel Red WHT "]
> BUTTON 3,0,255,250,BtnBLK,1,setDT
> BUTTON 5,0,255,250,BtnRED,1,setDL
> BUTTON 6,0,255,250,BtnWHT,1,exitDT
> DEBUG DEC idx," "
> NEXT
> RETURN
>
> This all seems to work fine, until I add code in the setDT or setDL
> subroutines. When I run the program it appears as if the button pins
> are "floating" and idx value randomly increments anywhere from 0 to
> 10 before exiting the loop and going to the setDL subroutine. If I
> change the order of the Button commands it always exits at the first
> one, if I use different pins, the same happens.
>
> I have removed the code from the subroutines and it is working OK
> again. If I press any of the buttons it exits the loop correctly.
>
> If I let the loop run through the 30 count, it exits to another
> similar piece of code and the buttons work correctly from there as
> well. I have measured my voltage and it is a constant 4.99v at the
> regulator and at the buttons.
>
> Anyone have any thoughts? (Unfortunately I don't have all of the code
> in tact as I changed it to use a serial 4 x 4 keypad instead.)
>
> Thanks in advance
>
> Cheers
> Col
>
[noparse][[/noparse]Non-text portions of this message have been removed]
thanks for the fast response. Took me a bit of reading to work out
exactly how your code works, but it all makes sense now :-)
This does lead me to ask another question though.
Unless I am mistaken (which is very likely) GOSUB also uses an
address for branching. Does this also mean it is not advisable to use
more than one GOSUB in a loop? The manual mentions a limit of 4
nested GOSUBs but doesn't seem to mention a limit within a loop.
Is this the case or does GOSUB work differently to BUTTON.
Thanks again for your advice.
Cheers
Col
--- In basicstamps@y..., jonwms@a... wrote:
> Col:
>
> Since the BUTTON command uses an address for branching, it's not
ideal to use
> more than one in a loop. My suggestion would be a custom scanning
and
> debouncing routine. The nice thing about it is that you'll use
fewer
> variables and with aliasing, you can keep your code very concise.
>
> If you'll move your button inputs to pins 4 - 7, this routine will
work for
> you and return a "1" for any pressed button:
>
> x VAR Nib
> buttons VAR Nib
> btn0 VAR buttons.Bit0
> btn1 VAR buttons.Bit1
> btn2 VAR buttons.Bit2
> btn3 VAR buttons.Bit3
>
> Get_Buttons:
> buttons = %1111 ' assume pressed
> FOR x = 1 TO 5
> buttons = buttons & ~InB
> PAUSE 5
> NEXT
> RETURN
>
> The routine ensures that the button was held for the entire cycle
by ANDing
> the last current reading with the last. BTW, you can modify this
routine to
> work with any set of pins, you'll just have to preset and test each
> individually.
>
> Of course, you'll want to rename the bit variables to something
that makes
> more sense for your program.
>
> -- Jon Williams
> -- Applications Engineer, Parallax
>
>
>
>
>
> In a message dated 6/26/02 7:56:51 AM Central Daylight Time,
> aussiecol39@y... writes:
>
>
> > Hi guys,
> >
> > I was hoping someone could help me out with a strange problem I
am
> > experiencing using the button command.
> >
> > I have 4 buttons connected to my stamp to pins 3,4,5 &6. They are
> > connected with a 1K resister in series with the pin and a 47k
pullup
> > resister (As in Scott Edwards book). I also have a serial LCD at
> > pin15 and DS1302 (with 1 Farad super Cap) connected to pins 1,2 &
3.
> >
> > Everything runs from a 5V 800mA regulated power supply.
> >
> > I have this chunk of code to reset my LCD display, read the time
from
> > the DS1302 and display the date and time. It reads 3 buttons and
> > loops back.
> >
> > OUTS = %0000000000000000
> > DIRS = %1000000000000111
> > Setup:
> > For idx = 0 to 30
> > GOSUB rsdp
> > GOSUB ReadRTCBurst
> > serout 15,bps,[noparse][[/noparse]HEX2 Date,"/",HEX2 Month,"/",HEX2 Year," ",
DEC2 12-
> > (24-(Hours.HIGHNIB*10+Hours.LOWNIB)//12),":",HEX2
Minutes,":",HEX2
> > Seconds]
> > serout 15,bps,[noparse][[/noparse]$FE,$C0," Change Date/Time?"]
> > serout 15,bps,[noparse][[/noparse]$FE,$94,"Field D/S EXIT"]
> > serout 15,bps,[noparse][[/noparse]$FE,$D4," Blk Yel Red WHT "]
> > BUTTON 3,0,255,250,BtnBLK,1,setDT
> > BUTTON 5,0,255,250,BtnRED,1,setDL
> > BUTTON 6,0,255,250,BtnWHT,1,exitDT
> > DEBUG DEC idx," "
> > NEXT
> > RETURN
> >
> > This all seems to work fine, until I add code in the setDT or
setDL
> > subroutines. When I run the program it appears as if the button
pins
> > are "floating" and idx value randomly increments anywhere from 0
to
> > 10 before exiting the loop and going to the setDL subroutine. If
I
> > change the order of the Button commands it always exits at the
first
> > one, if I use different pins, the same happens.
> >
> > I have removed the code from the subroutines and it is working OK
> > again. If I press any of the buttons it exits the loop correctly.
> >
> > If I let the loop run through the 30 count, it exits to another
> > similar piece of code and the buttons work correctly from there
as
> > well. I have measured my voltage and it is a constant 4.99v at
the
> > regulator and at the buttons.
> >
> > Anyone have any thoughts? (Unfortunately I don't have all of the
code
> > in tact as I changed it to use a serial 4 x 4 keypad instead.)
> >
> > Thanks in advance
> >
> > Cheers
> > Col
> >
>
>
>
>
> [noparse][[/noparse]Non-text portions of this message have been removed]
for is nesting them too deep. Sometimes a subroutine will have GOSUB in it
-- that's nesting. This is where you have to be careful.
What I meant in my first message was that each _individual_ BUTTON command
has an address, so it becomes a bit tricky (but not impossible) to use
multiple commands to scan a bunch on inputs. I wrote the routine I sent some
time ago to deal with this problem. The nice thing is that the subroutine is
very easy to modify for a number of multiple inputs. If you keep your inputs
on even nibble or byte boundaries (like InA, InB, InL, InH) then it's very
concise as well.
-- Jon Williams
-- Parallax
In a message dated 6/27/02 8:09:57 AM Central Daylight Time,
aussiecol39@y... writes:
> Hi Jon,
>
> thanks for the fast response. Took me a bit of reading to work out
> exactly how your code works, but it all makes sense now :-)
>
> This does lead me to ask another question though.
>
> Unless I am mistaken (which is very likely) GOSUB also uses an
> address for branching. Does this also mean it is not advisable to use
> more than one GOSUB in a loop? The manual mentions a limit of 4
> nested GOSUBs but doesn't seem to mention a limit within a loop.
>
> Is this the case or does GOSUB work differently to BUTTON.
>
> Thanks again for your advice.
>
> Cheers
> Col
>
[noparse][[/noparse]Non-text portions of this message have been removed]