I’m pretty amateur at programming and coding and this is the first year I’m attempting to use robot c, but I was wondering if it is possible to program a button to when pressed it reverses your 4 motor or two motor drive train? My robot currently has two front sides and I don’t really want to spend rigorous hours learning to sufficiently drive in reverse any knowledge helps!
To be quite fair, I actually have never used RobotC despite knowing several other languages, so I can only give you worded instructions of how I would do it.
- make an integer named “direction” or something and set it to 1.
- for every function that moves your drive motors multiply the speed by “direction”
- now set up your button that you want to use to change the direction, and make it such that every time you press it, it multiples your direction variable by -1
IE:
task main()
{
int yourSPEEEEEEED = 100;
int direction =1;
if(vexRT[Btn420]){
direction*=-1;
}
// any time you want to move your drive motors
motor[port69] = direction*yourSPEEEEEEED ;
}
Hopefully this explanation is sufficient, although if it somehow breaks your robot its not my fault lol.
Also this might not work, but it should.
Edit: looked up RobotC syntax so, unless I’m stupid, it should work okay.
Have a variable that inverts the power that is sent to the motors:
int frontDirection = 1;
while(true){
if(vexRT[Btn6D] && frontDirection == 1){ //if you press the button and the current value is 1
frontDirection = -1; //change the value to -1
}
else if(vexRT[Btn6D] && frontDirection == -1){ //if you press the button and the current value is -1
frontDirection = 1; //change the value to 1
}
motor[left1] = motor[left2] = vexRT[Ch3] * frontDirection;
motor[right1] = motor[left2] = vexRT[Ch2] * frontDirection;
wait1mSec(20);
}
/*
If the value of frontDirection is 1, then pushing the joysticks forward will move the robot forward
If the value of frontDirection is -1, then pushing the joysticks forward will move the robot backward
This lets you switch which side of the robot is the front with the press of a button
*/
EDIT: I posted nearly the same idea as @littlebro5 just a slightly different approach. (I was busy writing it in robotC and didn’t see them post their code already). I think if you put this into your usercontrol task and replace the motor names, this should work as is.
Let us know if you have any other questions!
Wouldn’t they need some sort of Debounce for this to work consistently?
Yes, that’s a feature that I’ve seen in toggle programs we’ve used. It makes sense to have it.
It’s been a while since I had to actually program that myself, I just remember being frustrated trying to do something similar.
@Sky13 just so you understand. Since I assume you are using a Vex joystick you will need to use a vex button and not a switch. Switches are nice because once they are toggled it will assume that value until it is un-switched manually, unlike a button that automatically returns to it’s original potion and value. If you are not pressing a button it is reading a value of ‘0’, when that button is pressed it will read ‘1’. Your frustration may come from what happens in between. A more experienced programmer may be able to explain this better but when you press that button, due to the nature of electronics the button’s value doesn’t simply go from 0 —> 1, it may instead “bounce” before finally reading ‘1’ so it would look like this if you printed the results of the few micro seconds after the button is pressed. " 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1 " This will toggle your code several times so that maybe you get the result you desire, and your drive is reversed, and maybe not.
You will need to research how to write debounce code, or perhaps someone here might know more about this and be able to help.
If you search on the forum for toggle codes, you will find one with a debounce feature. I will see if I can find one. If memory serves me - the debounce includes a slight delay (to try to outlast the switch bounce) and a check to see that you didn’t just toggle the state…
Here is a variant on what @Colossus wrote. It includes a debounce as well as simplifying the switch of frontDirection. It also fixes the motor[left2] mistake.
int frontDirection = 1;
ClearTimer(T1);
while(true) {
if(vexRT[Btn6D] && time1[T1] > 200) { // if you press the button more than 0.2 s after last time
ClearTimer(T1);
frontDirection = -frontDirection; // switch the value from 1 to -1 or from -1 to 1
}
motor[left1] = motor[left2] = vexRT[Ch3] * frontDirection;
motor[right1] = motor[right2] = vexRT[Ch2] * frontDirection;
wait1mSec(20);
}
What program is that?
Actually, better not to do it this way because you want swap left and right. I was just editing the prior one to fix an error, simplify something, and add in the delay. I’ll rewrite it to function properly a little later.
OK. So I’ve gone back and fixed a bigger issue as well. When you switch which way is “front,” you also switch right and left. I’ll keep the labels “left1,” “left2,” “right1,” and “right2” below. Those right and lefts are based on the default front, which I’ve called true with “originalFront,” the front if you haven’t yet changed it. But when you change it you’ll find turning very difficult with the above code, which is why I’ve corrected it below.
bool originalFront = true;
ClearTimer(T1);
while(true) {
if(vexRT[Btn6D] && time1[T1] > 300) { // if you press the button more than 0.3 s after last time
ClearTimer(T1);
originalFront = !originalFront; // switch the value from true to false or false to true
}
if(originalFront) {
motor[left1] = motor[left2] = vexRT[Ch3];
motor[right1] = motor[right2] = vexRT[Ch2];
}
else {
motor[left1] = motor[left2] = -vexRT[Ch2];
motor[right1] = motor[right2] = -vexRT[Ch3];
}
wait1mSec(20);
}
presumably if you with an int with alternating values of 1 and -1, you could skip the if else to make it easier to add into your code - but i could be wrong; wouldn’t be the first time.
Read my comment above about right and left. If you only drive straight forward or straight back, it will seem fine. But your turning will be backward because your left stick controls the right motors and your right stick controls the left motors. That’s what I’d missed before in the code I was editing, so I made a new version to have that part work properly.
That’s actually really clever, you could also just use two buttons if you don’t want to worry about complicated variables
Using timers is a very hacky way to debounce your button presses. I recommend waiting until the button is unpressed.
if (vexRT[Btn6D]) {
int integer *= -1;
while(vexRT[Btn6D]) {}
}
This cleaner approach will work much more consistently. This may pause your program for a bit if you hold down the button for some reason, but you can just stick the if statement inside a task to get rid of that.
I really like both of those approaches. You can also do something like this if you’re interested in not having any delay time in your main loop. (In pseudocode)
int driveCoefficient = 1;
bool switchDrivePressed = false;
if(6D is pressed and switchDrivePressed is false){
driveCoefficient = driveCoefficient * -1;
switchDrivePressed = true;
}
if(6D isn't pressed){
switchDrivePressed = false;
}
motors(drive) = joystick input * driveCoefficient;
Basically, the switchDrivePressed variable will keep track of whether or not 6D is actually pressed, allowing the toggle to only iterate once. If this is unclear, I can explain differently with a real example to clarify. Hope this helps!
Yes. That’s a good way and generally my preference because you clearly know which way you’re choosing.
Yes, I agree, though with the delay I would not use this outside of a task. Usually you won’t interfere with yourself, but you may well easily with a partner controller. As a task, definitely. However, don’t stick this in a task as is. You want to give it a delay within the while loop so the brain knows when it has time to run the other tasks.
I understand the desire to have such a drive coefficient, but it doesn’t really help here. The problem with this pseudo-code is that you have ended up with weird turning when you’re flipped your front to the other side.
im confused, couldn’t you just reverse the motors? that way the motors will rotate in the opposite direction.
Edit* nvm i understand now.
Sorry for the confusion, I was just trying to show the way to make a button not oscillate a trillion times a second with a second variable. The idea of this code is if you press the button once, it switches the state, and if you press it again, it switches it back. It’s not going to continually oscillate when you press the button the way it will if you just say if 1 then 2 and if 2 then 1. But you’re right about the coefficient, your setup looks a lot more natural to drive.