Example of a program that resets with too many LCD updates

Started by charliem101101 October 16, 2003
Hi all,

Here is an example of some code that reads two buttons to increment
two variables i and j and display their values on the LCD via com3.
You can really upset this program with quick or slow botton presses
and it will reset at different stages.

Any ideas on why I am upsetting the BX24 would be greatly
appreciated because I am trying to get a more complex menu driven
program to work (it suffers from the same faults!)

Thanks for any help you can give - the code is below

CharlieM

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Option Explicit

Dim com3in(1 to 15) as byte
Dim com3out(1 to 40) as byte
const debounce as single = 0.3
dim i as integer
dim j as integer
dim buttonpress as byte

Public Sub Main()

call putpin (6, bxinputpullup) 'Configure button to
increment i
call putpin (7, bxinputpullup) 'Configure button to
increment j
call putqueuestr(com3out, chr(14)) 'Reset LCD controller
call sleep(1.0) 'Wait for reset
Call openqueue(com3in, 15)
call openqueue(com3out, 40)
call definecom3(0, 5, bx1000_1000)
call opencom(3, 9600, com3in, com3out)
call putqueuestr(com3out, chr(20) & chr(255))'Set LCD
brightness
call putqueuestr(com3out, chr(12) & "**MAIN*PROGRAM**")'1st
LCD line
call putqueuestr(com3out, CHR(17) & CHR(1) & CHR(0) &_
"******AREA******")' 2nd LCD line
i = 0 'Initialise variable
j = 0 'Initialise variable

do
call setbuttonpress()
select case buttonpress
case 6
call incrementi
call updatelcd
case 7
call incrementj
call updatelcd
end select
loop

End Sub

sub updatelcd() 'Updates the LCD via com3
call putqueuestr(com3out, chr(12) & "var._i=_" & cstr(i)
& "_____")
call putqueuestr(com3out, chr(17) & chr(1) & chr(0)
& "var._j=_"&_
cstr(j)& "_____")
end sub

sub incrementi() 'Increments variable i
i = i+1
end sub

sub incrementj() 'Increments variable j
j = j+1
end sub

sub setbuttonpress() 'Detects which button has been pressed and
released
dim i as byte
do
for i = 6 to 7
if getpin(i) = 0 then
call sleep(debounce)
do until getpin(i) = 1
loop
buttonpress = i
exit sub
end if
next
loop
end sub



Hi Charlie
Firstly these two lines: call putqueuestr(com3out,
chr(14)) 'Reset LCD controller
call sleep(1.0) 'Wait for reset

should be after the lines defining the coms port and opening the 2 queues.

Secondly I suspect you are overflowing the queues by putting data into
the queues faster than its taken out.
Try updating your coms routine to this (new bits in blue):
'*****************************************************************
sub updatelcd() 'Updates the LCD via com3
call putqueuestr(com3out, chr(12) & "var._i=_" & cstr(i)
& "_____")
call putqueuestr(com3out, chr(17) & chr(1) & chr(0)
& "var._j=_"&_
cstr(j)& "_____")
do while statusqueue(ocom3)
sleep(2)
loop
do while (RamPeek(CuInt(21))and bx0100_0000)=bx1000_0000)
loop

end sub
'********************************************************************

neil

charliem101101 wrote:

> Hi all,
>
> Here is an example of some code that reads two buttons to increment
> two variables i and j and display their values on the LCD via com3.
> You can really upset this program with quick or slow botton presses
> and it will reset at different stages.
>
> Any ideas on why I am upsetting the BX24 would be greatly
> appreciated because I am trying to get a more complex menu driven
> program to work (it suffers from the same faults!)
>
> Thanks for any help you can give - the code is below
>
> CharlieM
>
> ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
> Option Explicit
>
> Dim com3in(1 to 15) as byte
> Dim com3out(1 to 40) as byte
> const debounce as single = 0.3
> dim i as integer
> dim j as integer
> dim buttonpress as byte
>
> Public Sub Main()
>
> call putpin (6, bxinputpullup) 'Configure button to
> increment i
> call putpin (7, bxinputpullup) 'Configure button to
> increment j
> call putqueuestr(com3out, chr(14)) 'Reset LCD controller
> call sleep(1.0) 'Wait for reset
> Call openqueue(com3in, 15)
> call openqueue(com3out, 40)
> call definecom3(0, 5, bx1000_1000)
> call opencom(3, 9600, com3in, com3out)
> call putqueuestr(com3out, chr(20) & chr(255))'Set LCD
> brightness
> call putqueuestr(com3out, chr(12) & "**MAIN*PROGRAM**")'1st
> LCD line
> call putqueuestr(com3out, CHR(17) & CHR(1) & CHR(0) &_
> "******AREA******")' 2nd LCD line
> i = 0 'Initialise variable
> j = 0 'Initialise variable
>
> do
> call setbuttonpress()
> select case buttonpress
> case 6
> call incrementi
> call updatelcd
> case 7
> call incrementj
> call updatelcd
> end select
> loop
>
> End Sub
> '*****************************************************************
> sub updatelcd() 'Updates the LCD via com3
> call putqueuestr(com3out, chr(12) & "var._i=_" & cstr(i)
> & "_____")
> call putqueuestr(com3out, chr(17) & chr(1) & chr(0)
> & "var._j=_"&_
> cstr(j)& "_____")
> end sub
> '********************************************************************
> sub incrementi() 'Increments variable i
> i = i+1
> end sub
>
> sub incrementj() 'Increments variable j
> j = j+1
> end sub
>
> sub setbuttonpress() 'Detects which button has been pressed and
> released
> dim i as byte
> do
> for i = 6 to 7
> if getpin(i) = 0 then
> call sleep(debounce)
> do until getpin(i) = 1
> loop
> buttonpress = i
> exit sub
> end if
> next
> loop
> end sub > Yahoo! Groups Sponsor
> <http://hits.411web.com/cgi-bin/autoredir?campU6&lineid614674&prop=egroupweb&pos=HM" target="_blank" rel="nofollow">http://rd.yahoo.com/M%9395.3614674.4902533.1261774/D=egroupweb/S06554205:HM/A24963/R=0/SIGo885gmo/*http://hits.411web.com/cgi-bin/autoredir?campU6&lineid614674&prop=egroupweb&pos=HM >
> ">http://docs.yahoo.com/info/terms/>.


Hi Charlie,
I have some suggestions, on my last project I had problems reading switches because the BX-24 is so fast and the switches were "slow" and bounced BOTH on closing AND opening. The fast loops were catching some of the bounces and seeing them as actuations. There are also a few suggestions about the code, please accept them as "things to try" and not "the gospel" until proven good in the real world by exhaustive testing.

Use 25 ms for debouncing both edges:
Const debounce As Single = 0.025

Use Call Delay(debounce) instead of call sleep(debounce).
I think Sleep wanted an "unsigned integer count" NOT "time" in "single".

Since i is dimmed as an integer, re-dimming i as byte in the sub feels uncomfortable, use a variable name that isn't used somewhere else.

I don't know what happens to integers inc'ed past 32767 in all conditions, so I put boundary limits like:
If i <= 32766 Then
i = i +1
End If

Any time I use "case", I include an "else" case to catch any bugs until the code is verified "good".

I would suggest a simpler construct for the main do-loop until you get it working as you want it to, then go back and try the "case" style. Example:

.............................
i = 0
j = 0
buttonpress = 0

Do
Call setbuttonpress() 'waits for a button press and release
If buttonpress = 6 Then
Call incrementi
Call updatelcd
End If
If buttonpress = 7 Then
Call incrementj
Call updatelcd
End If
Loop 'forever

The "exit sub" out of the nested "for=next" and "do-loop" feels uncomfortable, I suggest direct "exit do" and direct assignment of "buttonpress". Example:

Sub setbuttonpress()
Do
If GetPin(6) = 0 Then 'get first edge of closing
Call Delay(debounce) 'wait 25 ms for settle
Do
Loop Until GetPin(6) = 1 'get first edge of opening
Call Delay(debounce) 'wait 25 ms for settle
buttonpress = 6
Exit Do
End If
If GetPin(7) = 0 Then 'get first edge of closing
Call Delay(debounce) 'wait 25 ms for settle
Do
Loop Until GetPin(7) = 1 'get first edge of opening
Call Delay(debounce) 'wait 25 ms for settle
buttonpress = 7
Exit Do
End If
Loop
End Sub

I hope this helps, Eric



--- In , "Eric Serdahl" <eserdahl@p...> wrote:
> Hi Charlie,
> I have some suggestions, on my last project I had problems reading
switches because the BX-24 is so fast and the switches were "slow"
and bounced BOTH on closing AND opening. The fast loops were
catching some of the bounces and seeing them as actuations. There
are also a few suggestions about the code, please accept them
as "things to try" and not "the gospel" until proven good in the
real world by exhaustive testing.
>
> Use 25 ms for debouncing both edges:
> Const debounce As Single = 0.025
>
> Use Call Delay(debounce) instead of call sleep(debounce).
> I think Sleep wanted an "unsigned integer count" NOT "time"
in "single".
>
> Since i is dimmed as an integer, re-dimming i as byte in the sub
feels uncomfortable, use a variable name that isn't used somewhere
else.
>
> I don't know what happens to integers inc'ed past 32767 in all
conditions, so I put boundary limits like:
> If i <= 32766 Then
> i = i +1
> End If
>
> Any time I use "case", I include an "else" case to catch any bugs
until the code is verified "good".
>
> I would suggest a simpler construct for the main do-loop until you
get it working as you want it to, then go back and try the "case"
style. Example:
>
> .............................
> i = 0
> j = 0
> buttonpress = 0
>
> Do
> Call setbuttonpress() 'waits for a button press and
release
> If buttonpress = 6 Then
> Call incrementi
> Call updatelcd
> End If
> If buttonpress = 7 Then
> Call incrementj
> Call updatelcd
> End If
> Loop 'forever
>
> The "exit sub" out of the nested "for=next" and "do-loop" feels
uncomfortable, I suggest direct "exit do" and direct assignment
of "buttonpress". Example:
>
> Sub setbuttonpress()
> Do
> If GetPin(6) = 0 Then 'get first edge of
closing
> Call Delay(debounce) 'wait 25 ms for settle
> Do
> Loop Until GetPin(6) = 1 'get first edge of
opening
> Call Delay(debounce) 'wait 25 ms for settle
> buttonpress = 6
> Exit Do
> End If
> If GetPin(7) = 0 Then 'get first edge of
closing
> Call Delay(debounce) 'wait 25 ms for settle
> Do
> Loop Until GetPin(7) = 1 'get first edge of
opening
> Call Delay(debounce) 'wait 25 ms for settle
> buttonpress = 7
> Exit Do
> End If
> Loop
> End Sub
>
> I hope this helps, Eric >