picking auto program

whew, the extension might give me the time to get my “auto code picking” program working, so that I dont have to carry around my laptop during the competition. I have written several auto programs that have worked surprisingly well, but I have been having a bit of trouble writing code to select which one I want to run. I built a switch box wired to rc_sw1 through rc_sw8 (rc_sw0 used for the pressure switch) and plugged it into the RC’s digital inputs, but it fails to select the program I wish to run. Could someone provide me with some guidance on the matter?

-Mike

It is impossible to tell you what is wrong with the details given.

What types of switches are you using, and how are they connected to the RC?

Does the box you made pinout with a multimeter the way that you think it should?

Does a debug statement showing the states of the switches show what you expect.

What code are you using to try to switch programs?

Answer those, and people here will be much better able to help you.

What types of switches are you using, and how are they connected to the RC?

-They are 2 position switches, on and off. Each switch has one connection to a digital input pin and the other goes to a common digital input ground.

Does the box you made pinout with a multimeter the way that you think it should?

-This was tried, everything worked as it should

Does a debug statement showing the states of the switches show what you expect.

-I have no idea how debug works

What code are you using to try to switch programs?

-I was hoping a simple IF THEN in the autonomous section of code would perform this task

example:
counter var word
counter=0

IF auton mode = 1 THEN
select counter

IF rc_sw1=1 THEN start_left:
IF rc_sw2=1 THEN start_right:

'Starting on left side of field
start_left:
(left auto program here)
goto imdone:

'Starting on right side of field
start_right:
(right auto program here)
goto imdone:

ELSE 'Resume Human Control
imdone:

First of all, I’m not sure if your line “IF auton mode = 1 THEN” is a typo cause you were typing fast, or if it’s copied from your code. The variable is “auton_mode,” so double check that (although I’d assume you’d get a tokenize error if you forgot the _ in your code).

Another problem may be the actual status of this bit. Have you followed the instructions on enabling auto mode (here or here)? There are basically two ways to do it: set the team number to zero, or make a dongle (the dongle I made this year is shown below).

If you’re checking the auton_mode bit, you have to have turned it on in the first place. Not sure if you did this or not - you never specified.

Another suggestions: just a small note: it would have been a lot more simpler and elegant if you just hooked the left and right side to one toggle switch…

IF sw = 1 THEN <left code>
ELSE <right code>

But with the goto imdone, it’ll still work.

[edit]Forgot to upload that pic of my dongle… apparently you can’t upload attachments to a attachmentless post when editing it… glare at Brandon)

dongle.jpg


dongle.jpg

*Originally posted by Mike375 *
**Does a debug statement showing the states of the switches show what you expect.

-I have no idea how debug works**

put this in your program and download it:

DEBUG cls,bin8 rc_swA,cr

a little window will appear with a 1’s and 0’s representation of the first 8 digital inputs.

**What code are you using to try to switch programs?

-I was hoping a simple IF THEN in the autonomous section of code would perform this task

example:
counter var word
counter=0

IF auton mode = 1 THEN
select counter**

is this all your IF is to decide ? I see no ‘endif’, efendi.

IF rc_sw1=1 THEN start_left:
IF rc_sw2=1 THEN start_right:

With no distinction, these should execute all the time

**'Starting on left side of field
start_left:
(left auto program here)
goto imdone:

'Starting on right side of field
start_right:
(right auto program here)
goto imdone:

ELSE 'Resume Human Control
imdone: **

I would make the converse statement,

if auton_mode = 0 then goto end_o_this_code

{auto mode stuff, like if left_sw then goto the_left, &c}

end_o_this_code:

rest of program:

I like
direction VAR bit
program VAR bit(2)

direction = sw5
program = sw6 <<1 + sw7

program1 CON 0

if program = program1 then

endif

if program = …

eh, problem there is you’re wasting precious bits. Last year we used up ALL of our memory for our program, and this year we’ve been VERY conservative with our memory (i.e. if you put your light-relay-on code at the very end of your code, then you can use the two light relay bits as temporary swap bits cause they’re just hard-coded later on).

For example…
direction = sw5
If you’re setting direction to be equal to sw5, there’s no need to make a seperate bit for it. Just make “direction” an alias for “sw5” if you don’t want to use sw5 (aliases take no memory).

Same thing with
program1 CON 0
I see no reason for this. Just make the if statement “IF program = 0…”

On PC programming, there’s no real problem with memory allocation being as leniant as you’re doing it if it’s something as small as the robot code is (although it’s much more efficient if you use less memory).

However, with something that has as little memory as a PBASIC stamp, you should be really careful with memory allocation - otherwise, you’re going to run out.

*Originally posted by SuperDanman *
**eh, problem there is you’re wasting precious bits. Last year we used up ALL of our memory for our program, and this year we’ve been VERY conservative with our memory (i.e. if you put your light-relay-on code at the very end of your code, then you can use the two light relay bits as temporary swap bits cause they’re just hard-coded later on).

For example…
direction = sw5
If you’re setting direction to be equal to sw5, there’s no need to make a seperate bit for it. Just make “direction” an alias for “sw5” if you don’t want to use sw5 (aliases take no memory).

Same thing with
program1 CON 0
I see no reason for this. Just make the if statement “IF program = 0…”

On PC programming, there’s no real problem with memory allocation being as leniant as you’re doing it if it’s something as small as the robot code is (although it’s much more efficient if you use less memory).

However, with something that has as little memory as a PBASIC stamp, you should be really careful with memory allocation - otherwise, you’re going to run out. **

Right…I have room for 20 more bytes in my auton program (160 bits). :slight_smile: 3 bits aren’t going to make that much of a difference…I’m not going to run out, and we are done with the programming. :slight_smile:

You know there are 8 slots on the RC right?

Here…Lemme put into comments what need to be fixed:

'********************

counter var word
counter=0

IF auton mode = 1 THEN 'needs to be auton_mode
select counter

IF rc_sw1=1 THEN start_left: 'lose the colon…
IF rc_sw2=1 THEN start_right: 'lose the colon

'Starting on left side of field
start_left:
(left auto program here)
goto imdone:

'Starting on right side of field
start_right:
(right auto program here)
goto imdone:

ELSE 'Resume Human Control
imdone:

'**************************

Here is what it should look like corrected (with a few tweaks added for efficency):

'**************************

counter var word
counter=0

IF auton_mode = 1 THEN
goto auton_on
else
goto imdone
endif

auton_on:
select counter

IF rc_sw1=1 THEN start_left
IF rc_sw2=1 THEN start_right

'Starting on left side of field
start_left:
(left auto program here)
goto imdone

'Starting on right side of field
start_right:
(right auto program here)
goto imdone

'Resume Human Control
imdone:

'**********************

You could also just use 1 switch for the left-right selection. Have it if the switch is open, then it goes left, else it goes right. This way, you avoid the instance of having both acidetally closed or open. Here is what your code would look like:

'**********************

counter var word
counter=0

IF auton_mode = 1 THEN
goto auton_on
else
goto imdone
endif

auton_on:
select counter

IF rc_sw1=1 THEN
goto start_left
else
goto start_right
endif

'Starting on left side of field
start_left:
(left auto program here)
goto imdone

'Starting on right side of field
start_right:
(right auto program here)
goto imdone

'Resume Human Control
imdone:

'*********************

Hope this helps.

Bill B.

select var nib 'in the variable initialization part

select = (rc_sw1 * 2) + rc_sw2 'in the start of autonomous mode

if select = 1 then follow_the_yellow_brick_road

if select = 2 then fly_vertically_through_space

if select = 3 then seek_and_stack_all_drivers_on_opposing_team

'put regular code here Make sure that you don’t run through
'two sections at once

The preceding code may or may not have been taken from our robot code :smiley:

But you get the idea.

the word “select” is a reserved operator. choose a different one.

I got ours to work with a 3-position switch using simple if/then statements…

Oh. It wasn’t the word I used anyway.

What is select used for then?

*Originally posted by Jeff_Rice *
**What is select used for then? **

Select is like a multi-condition IF or a BRANCH.

From the PBASIC 2.5 Documentation:

**SELECT…CASE can be used to cleanly replace multiple IF…THEN…ELSE structures. The PBASIC syntax
for SELECT…CASE is ( | denotes mutually-exclusive items ):

SELECT expression
CASE | TCASE ELSE | condition(s)
statement(s)
ENDSELECT

Notes:
  • expression can be a variable, a constant or an expression.
  • condition can be in the form:

      {condition-op} #

      -- where condition-op is an optional conditional operator: =, <>, <, >, >= or <=
      -- # is a variable, a constant or an expression
  or…

      # TO #

      -- Indicates a range of the first number to the next number, inclusive
      -- Conditional operators are not allowed in this form.

  • Multiple conditions within the same case can be separated by commas ( , ).
  • When a CASE is True, the default function is for the CASE's statement(s) to be executed, then
    program execution jumps to the first statement following ENDSELECT.
  • TCASE, meaning “Through CASE”, behaves exactly like CASE, except that it causes the previous
    CASE (if executed) to continue program execution at the first statement within the TCASE,
    instead of jumping to after the ENDSELECT. After execution of the statements within TCASE,
    execution jumps to after ENDSELECT, unless followed by another TCASE.
Example:

SELECT irCmd
CASE 0 TO 3
HIGH irCmd

CASE AllOff, Mute
OutA = %0000

CASE ELSE
DEBUG “Bad Command”, CR
ENDSELECT

**

well since I was paranoid, our team taped all the touch sensor pos/neg connections to make sure they didn’t short.

some simple code like this can test your sensors

if not (rc_sw1 = 1) then skip1
PWM1 = 254
skip1

just press the sensor, see if it moves PWM1, and change rc_sw1 to rc_sw2, rinse and repeat

actually found one or two that didn’t work on ours

907
Brian Lim

Thank you gwross. But I use 2.0. Don’t want to mess with a possibly buggy compiler.

If neg_logic <> fun then you_use_twopointfive
fun = 254 - syntax_frustrations
goto end_of_code
you_use_twopointfive:
fun = 254 - syntax_frustrations - compiler_worries + normal_logic
end_of _code

Hmm.
They seem about equal. Oh well. I don’t want to download another program. Until next year anyway.

Oops. Went off on a tangent. But anyway, I like converting the switches to a binary nibble. You don’t have to use a byte for an analog input, and all you have to do is move their bits to their respective places in the nibble.

Brian, why don’t you just use debug to test sensors?

For those of you that may still be struggling with autonomous code, here is some code snippets that may help.

loopCnt VAR byte 'Loop counter Low byte
loopCntHigh VAR nib 'Loop counter High nibble

StradegyNumber VAR nib 'The Stradegy number selected on robot

Stradegy1 VAR rc_swB.bit5 ’ Stradegy Selection Switch 1
Stradegy2 VAR rc_swB.bit6 ’ Stradegy Selection Switch 2
Stradegy3 VAR rc_swB.bit7 ’ Stradegy Selection Switch 3

loopCnt=0
loopCntHigh=0

MainLoop:

'>>>>>>>>>>>>>>>>>>> LOOP COUNTER <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
IF auton_mode THEN
IF (loopCnt + 1 > 255) THEN
loopCntHigh = loopCntHigh + 1
loopCnt = 0
ELSE
loopCnt = loopCnt + 1
ENDIF
ELSE
loopCnt = 0
loopCntHigh = 0
ENDIF

'>>>>>>>>>> STRADIGY SELECTION <<<<<<<<<<<<<<<<<<<<<<
'This section move the stradegy switches into the StradegyNumber varible for program use
StradegyNumber.Bit0 = Stradegy1
StradegyNumber.Bit1 = Stradegy2
StradegyNumber.Bit2 = Stradegy3

'>>>>>>>>>> AUTONOMOUS MODE <<<<<<<<<<<<<<<<<<<<<
IF auton_mode THEN 'Check for Autonomous mode
SELECT StradegyNumber
CASE 0
'Stradegy 0 code goes here
CASE 1
'Stradegy 1 code goes here
CASE 2
'Stradegy 2 code goes here
CASE 3
'Stradegy 3 code goes here
CASE 4
'Stradegy 4 code goes here
CASE ELSE 'Not a valid stradegy
PWM1 = 127
PWM2 = 127
ENDSELECT 'End the autonomous mode stradegy selection
ELSE 'Not in Autonomous Mode
loopCnt=0 'Reset Loop Counter when not in Autonomous Mode
loopCntHigh=0
ENDIF

Tim Tedrow

*Originally posted by SuperDanman *
**eh, problem there is you’re wasting precious bits.
(snip)

Same thing with
program1 CON 0
I see no reason for this. Just make the if statement “IF program = 0…”

**

Constants do not take up any extra memory or variable space. Check the Parallax manual.
They do make your code much more readable!

However, assuming the above example had a few programs (program1=0, program2=1, program3=2, etc…), it is confusing to stagger your indices like that. Starting it at program0=0 is preferred.