PBasic Probelm

Hi,
I have 3 push buttons that I am using as a switches. I am using last year’s robot controller. What I want to do is when I press a button once, I want it to be like a toggle button. When I press a button, I want the controller to run a sub routine. That is simple, I know, but here is the catch:
If while running the sub-routine, a second button is pressed, I want the RC to ignore the second button. When the RC is done executing the subroutine, then I want it to be able to recieve a signal from any other button, but not until it is done executing the first sub routine.
Also, I forgot, in PBasic, is this how you used to do sub routines?

IF condition THEN
gosub FIRST
ENDIF

FIRST:
'code

Is that all there is to it or do I have to declare the sub routine in a different way or end the sub routine in a different way. I’ll appreciate any help.

I think that you can do that. I never worked with last years controllers though, so don’t believe me. :wink:

You need two subroutines:
One for when the button state is up doing:
Set flag to 0
And the other when the button state is down doing:
Set flag to 1
(other stuff)

This way, the flag will be 1 if the button is pressed down.
Then at the top of the other button’s code, put an if flag = 0 then,
so that code will not execute unless the button is up.

Do something like this: (this is in pseudo-code)


global variable FirstActivated initialized to 0

Check if first button is press
  If it is, toggle the state of FirstActivation (I.E. if it is 1 then make it 0; if it is 0 then make it 1)

Check if FirstActivated is 1
  If it is, do what ever you want to do here.

Check if Second button is pressed.
  If it is, check if FirstActivated is 0
    If is is, then do your second button action.

One thing you have to remember is that the state of the buttons can only change when you do the serin statement at the top of your code. Thus, even if button2 is pressed while you are doing the subroutine for button1, you won’t see that button2 is pressed until the next loop. If button1 and button2 were pressed at approximately the same time, you’ll see both after the serin. In other words, you never have to worry about subroutine2 executing in the middle of subroutine1, your code will flow in order.

You also need a branch after the IF statement to hop over the “FIRST: code”, otherwise the code just falls into the “FIRST: code.”

I don’t know PBASIC specifically, but I’ll try.

FIRST is a label. Wouldn’t you use goto, not gosub?
I know that in Visual Basic (similar so far), you define a sub as:

Public Sub foo ()
 'Some Code Here
 'Call subroutine
 foo2
End Sub

Is it any diferent in PBASIC?

In PBasic the “basic” program structure would look like this:


MainLoop:
'---------- Serin Command - Get Data from Master uP -------------
  Serin COMA\COMB, INBAUD, [oi_swA,oi_swB,rc_swA,rc_swB,p1_x,PB_mode,p2_y,p1_y]
. . .
  gosub RESCALE_STICK
. . .
  Serout USERCPU, OUTBAUD, [255,255,127,relayA,127,127,pwm2,pwm1,127,127,127,127,pwm9,127,127,127,127,127,127,127]
 
Goto MainLoop:
 
'-------- SUBROUTINES ----------------------------------------
 
RESCALE_STICK:	 
'Rescale the output of the joysticks
. . .
RETURN
Stop

1 routine. ‘gosub’ instead of ‘goto’. ‘return’ to go to the most recent gosub. ‘stop’ to halt everything. Got it.

I would do something like this:


None         con 0
DoingAction1 con 1
DoingAction2 con 2
DoingAction3 con 3

ProgramState var byte

'Initialization
ProgramState = None

MainLoop:
'---------- Serin Command - Get Data from Master uP -------------
  Serin COMA\COMB, INBAUD, [oi_swA,oi_swB,rc_swA,rc_swB,p1_x,PB_mode,p2_y,p1_y  ]

. . .

  if ProgramState = None then
    if switch1 <> 0 then ProgramState = DoingAction1
    if switch2 <> 0 then ProgramState = DoingAction2
    if switch3 <> 0 then ProgramState = DoingAction3
  endif

  if ProgramState = DoingAction1 then gosub DoAction1
  if ProgramState = DoingAction2 then gosub DoAction2
  if ProgramState = DoingAction3 then gosub DoAction3

. . .

  Serout USERCPU, OUTBAUD, [255,255,127,relayA,127,127,pwm2,pwm1,127,127,127,1  27,pwm9,127,127,127,127,127,127,127]
 
Goto MainLoop:
 
'-------- SUBROUTINES ----------------------------------------

DoAction1:
  *Do some stuff...*]
  if Done then ProgramState = None
  return

DoAction2:
  *Do some other stuff...*]
  if Done then ProgramState = None
  return

DoAction3:
  *Do some fluff...*]
  if Done then ProgramState = None
  return

Stop

(Standard disclamer)

[edit]
Note 1: As Joe mentioned, more than one button could be pressed at the same time. The way I’ve coded it, button 3 would have the highest priority, and button 1 the lowest (because of the order of the if statements.)

Note 2: I didn’t indicate how the variable “Done” gets set… Or even that it’s a variable, for that matter. It could be a logical expression like “elapsedProgramCycles > 80” or “proximitySensor = 1”.

Note 3: Make sure your subroutines return quickly. They should only calculate or set outputs. It won’t work to do something like this:


  for i = 1 to 80 
    pwm1 = 255
  next i
  return

Instead, it should be something like:


  ' Make sure JJ gets initialized somewhere. (Like when you set the ProgramState variable.)
  pwm1 = 255
  JJ = JJ+1
  if JJ = 80 then ProgramState = None
  return

[/edit]