I need to program some presets for a robot competing in elevation. The only issue/complication there is is that I only have limit and bumper switches. So i would think you would do it by running the motor for a certain amount of time when a button is pressed. I just can’t figure out how to program the robot to recognize when the button is pressed a certain # of times. I have access to easyc v2 for pic.
to make successful presets you really NEED an encoder or potentiometer on the arm.
Button as in button on the joystick? This is very doable but it is much easier if you have a bitmap module to store the last/current state of all the buttons on the joystick. (Last being since your last update cycle - I am not sure how you designed your code but I assume you are placing your logic inside of a loop)
If the current state of the button is down and the last state of the button was up, the user has ‘pressed’ the button once the button is down. Swap these two conditions and it will be when the button is released. It is important that both these conditions be true. You cannot just check to see if the current state of the button is ‘down’ because holding the button down would yield as many presses as as many calls checking its state - which is obviously undesired.
Per a button press you can increment a variable - then compare this variable to something per logic cycle.
Here is an idea on how to make a one way encoder with a limit switch: ROBOTC
The team mentioned in the post was able to accomplish it, so it looks like it works. And although the code given is in ROBOTC, you should be able to use the basic workings and modify if for EasyC.
What is a preset? What is a button?
Running a motor for a fixed time is called “open loop”, and your results will vary depending on charge in the battery, not as reliable as “closed loop” feedback with bumper switches and limit switches.
Here is my guess at a more clear paraphrase of your request:
- I am using 75mhz RC controller and PIC processer with EasyC V2
- My application is game Elevation (from several years ago) with a standard dual tread intake, arm, 4w base type robot.
- I have just one joystick controller to use.
- I like tank drive on channels 1,3
- I dont want to use channels 2,4 since they twitch while I drive on ch1,3.
- I use channel 6 up/down for intake/outtake control
- I want to be able to press the channel 5 up button or channel 5 down button to control the arm position to specific positions.
- I want the arm to move to 3 specific preset positions, aka low/med/high
- I have unlimited number of bumper/limit switches to use for feedback.
- I know a pot for analog feedback would be better, but I cant use that per my local classroom rules.
Did I guess right? If not, you can update in the same language format.
If you attach your current program, we can see what level programming you have already, so we know the best level of discussion to help you.
There are two components to a closed loop feedback solution: hw, sw.
HW (hardware): bumper/lit switches to show the current position of the arm.
– High and low feedback are just limit switches
– the simplest hw for middle positions is just a “swipe-by” limit switch that is only closed as the arm passes by that correct position.
SW (software programming) can follow the usual Sense, Plan, Act format.
– Sensing is easy, just read the current values of all the switches, and get the values of the joystick buttons.
– Plan part1: figure out what the driver wants to do; here is where we need to read the joystick button variables and decide what they mean.
– Plan part2: Given the current meaning of what the driver wants to do, and given the limit switch feedback, where is the arm, and how do we need to move it to do what the driver wants.
A reasonable control method for arm presets might be this:
- press and release ch5 up button to move arm to next higher preset
- press and releast ch5 dn button to move arm to next lower preset
– never move arm higher than high, or lower than low.
see State diagram - Wikipedia
For a statemachine to implement this, we need a variable S
that can hold a number representing the state,
and conditions to move between states.
Pseudo code:
while(1){
// sense
tank(); // tank drive
digital_joystick_to_motor(); // intakes
t = get_joystick(5); // get ch5, returns 0, 127, 255 for dn/none/up
// plan part 1, what does driver want?
s_next = s; // default stay in same state as before
if ( 0==s && 255 == t) { s_next = 1 } // from low0 to temp1
if ( 1==s && 127 == t) { s_next = 2 } // from temp1 to mid2
if ( 2==s && 255 == t) { s_next = 3 } // from mid2 to temp3
if ( 3==s && 127 == t) { s_next = 4 } // from temp3 to high4
if ( 4==s && 0 == t ) { s_next = 5} // from high4 to temp 5
if ( 5==s && 127 == t) { s_next = 2} // from temp5 to mid 2
if ( 2==s && 0 == t) { s_next = 6} // from mid2 to temp6
if ( 6==s && 127 ==t) { s_next = 0} // from temp6 to low0
// now we know where we were (s), and where we are now (s_next)
s = s_next; // move to next state, might need to do this later
// Plan part 2, do what the driver wanted
if ( 0 == s) { // state 0, want arm at low position
arm = 0; // lower arm
if ( low_limit_switch) { arm = 127 } // dont lower past bottom
}
if ( 4 ==s ) { // state 4, want arm at high position
arm = 255; // raise arm
if ( high_limit_switch) { arm = 127} // dont raise past top
}
// Act
SetMotor( arm_motor, arm );
wait(20); // take your time, also helps debounce buttons
} // end while
I’m a little rusty at Pic V2 code, so I might have embarassed myself by typing untested pseudo code,
but this example is intended to show how to split code into Sense/Plan/Act,
how to implement a simple statemachine (with one if for each transition).
It should work for preset high and preset low.
See if you can figure out how to put a swipe-by limit switch for a middle position and stop the arm when reaching it.
thanks for all the help. This is the code I have managed to pull together:
#include “Main.h”
void OperatorControl ( unsigned long ulTime )
{
int a;
int b;
int c;
int d;
int e;
int f;
int g;
int t;
a = GetDigitalInput ( 1 ) ;
c = GetDigitalInput ( 3 ) ;
d = GetDigitalInput ( 4 ) ;
e = GetDigitalInput ( 5 ) ;
f = GetDigitalInput ( 6 ) ;
g = GetDigitalInput ( 7 ) ;
t = get_joystick(5);
while ( 1 ) // Insert Your RC Code Below
{
while ( 1==1 )
{
if ( a == 0 && t == 255 )
{
SetMotor ( 7 , 0 ) ;
SetMotor ( 8 , 255 ) ;
if ( c == 0 && t == 127 )
{
SetMotor ( 7 , 127 ) ;
SetMotor ( 8 , 127 ) ;
}
}
if ( c == 0 && t == 255 )
{
SetMotor ( 7 , 0 ) ;
SetMotor ( 8 , 255 ) ;
if ( d == 0 && t == 127 )
{
SetMotor ( 7 , 127 ) ;
SetMotor ( 8 , 127 ) ;
}
}
if ( d == 0 && t == 127 )
{
SetMotor ( 7 , 0 ) ;
SetMotor ( 8 , 255 ) ;
if ( f == 0 )
{
continue ; // continue to next if (f)
}
}
if ( e == 0 && t == 255 )
{
SetMotor ( 7 , 0 ) ;
SetMotor ( 8 , 255 ) ;
if ( f == 0 && t == 127 )
{
SetMotor ( 7 , 127 ) ;
SetMotor ( 8 , 127 ) ;
}
}
if ( f == 0 && t == 127 )
{
SetMotor ( 7 , 0 ) ;
SetMotor ( 8 , 255 ) ;
if ( f == 0 )
{
continue ; // continue to next if (f)
}
}
if ( g == 0 && t == 0 )
{
SetMotor ( 7 , 255 ) ;
SetMotor ( 8 , 0 ) ;
if ( a == 0 && t == 127 )
{
SetMotor ( 7 , 127 ) ;
SetMotor ( 8 , 127 ) ;
}
}
}
}
}
I realize there will probably be a number of mistakes as I have never really done any programming with any type of sensors/having to write proper code. As for you speculations jgraber, you were correct about most things:
-We are using the pic system with easyC V2
-We are playing elevation in our area
-We have a classic 4wd robot with 2 4"omni’s at the front and 2 4" wheels at the back however we are using a 4 bar lift with a mini version of team 39’s elevation intake on the end of it
-As for the channels that setup is completely accurate
-We want 4 presets: Auto loaders,low, med, high
-We do have many bumper/ limit switches available( we have about 6 classroom comp. kits in use with 6 teams in our school plus extras and no one is using sensors)
-We only have 3-wire motors and servos to work with
Motors 7,8 apparently go to the arm?
You have your Sense lines outside the loop, so that won’t work.
You have two while(1) loops, not sure why, maybe for the continue?
Your single letter variables apply to switch inputs, but you didn’t comment what they are for. What arm positions does each switch input mean?
You dont have much planning here, just acting based on senses.
You dont have any state memory.
More (any!) comments in your code would be helpful.
Did you understand that my example started in state=0,
and moved to state 1 when ch5 up was pressed,
and then moved from state1 to state2 when ch5 up was released?
And that if ch5 is not pressed, the state stays the same as last time?
I have a bubble chart somewhere I can post.
https://vexforum.com/gallery/files/1/5/6/8/arm_preset_state_bubble.jpg
There are 7 states shown, numbered 0…6.
Each arrow is a state transition.
Arrow from top (or bottom) represent up (or down) button is pressed.
Arrow from sides represent no buttons pressed (ie button released).
Each state transition is implemented by an IF statement.
The arrow state transitions from state 0 to state 1 to state 2 would be coded as:
if (0==state && 256==ch5) { new_state=1; }
if (1==state && 127==ch5) { new_state=2; }
Remember that this is only Planning part 1, to determine where the driver wants the arm to be.
Planning part 2 is also required, to look at the current arm position, compared to the above state, and decide if the arm needs to be moved, and in what direction.