I’ve been wondering how to make a button pull back our puncher while driving and using our intake so we can drive around and press a button so our puncher will auto reload but I can’t seem to get it to work. I’m new to the whole coding aspect of vex so I don’t know much about how it all works but if anyone could help that’d be awesome. I’ll include what i’ve been trying to do but it doesn’t work because instead of pulling the puncher back it just sits and ticks the puncher back 1 tooth whenever we press the B button. I’ll also include the first thing I tried farther down because I feel like it could work if it didn’t stop all the other motors until the puncher was finished pulling back. I’ll include the actual file for the code as well incase it needs to all be seen.
problem with this one is the puncher motor doesn’t pull it back all in one go but rather ticks the teeth on the gear running the puncher 1 tooth per click of the B button*
//Puncher control
if(Controller1.ButtonA.pressing()) {
Puncher.spin(directionType::fwd,100,velocityUnits::pct);
}
else if(Controller1.ButtonB.pressing()) {
Puncher.rotateFor(6,rotationUnits::rev,100,velocityUnits::rpm,false);
}
else {
Puncher.stop(brakeType::hold);
}
First thing I tried stops all other motors from running while the puncher is pulling back*
//Puncher control
if(Controller1.ButtonA.pressing()) {
Puncher.spin(directionType::fwd,90,velocityUnits::pct);
}
else if(Controller1.ButtonB.pressing()) {
Puncher.rotateFor(1.8,timeUnits::sec,100,velocityUnits::pct);
}
else {
Puncher.stop(brakeType::hold);
}
I didn’t actually read the code, but it seems that your while loop is running faster than what you’re pressing the button. Therefore, it thinks that you’re just holding the button down, wanting it to keep going.
My solution would be to, in the else if statement, add a line of code that stops runnning that particular shooter drawback function (after the small turn) until the button reads unpressed again.
I’m not really good enough at this stuff to explain a potential problem (or more so explanation as to why it might not work) with my solution, but I’ll try: The button readouts very quickly toggle between 1 and 0 during the time the button is being depressed.
This would lead to more problems because the code sees the 1 and 0 (pressed and not pressed) toggling quickly and will move on with the code. It will once again read the 1 and then 0, running the function again with the same result, all the while, to the driver, the button was only pushed once.
There is a solution to this I read about in another thread I probably couldn’t find again from a few months ago. Maybe someone more programming savvy can help.
[Disclaimer: I don’t know if this next part will work]
I don’t know if this would work, but what if you put a wait statement before (or after) the motor runs, allowing the button to finish its toggling without the code reading it. I have no clue what value would work, but it might be worth trying.
I have not used V5 myself yet I do have experience coding in C++ and I am trying to do the same thing with my puncher using RobotC. I have the motor running using a motor encoder and run it like any other motor using a while loop task AutoPunch(){ while(true) { draw = SensorValue[Punch]; while(draw < 100) { motor[Puncher1] = 127; motor[Puncher2] = 127; } motor[Puncher1] = 10; motor[Puncher2] = 10; }
This just has the motor running until it reaches a value that loads the puncher just enough then holds the puncher loaded, until we press another button that just runs the puncher when the button is pressed to fire.
For V5, when I am setting the motor power to 10 it sounds like it would be the same thing as setting the motors to brake.
Let me know if something like this will work on the new V5 system. I am using a potentiometer to read the rotation of the puncher but the new V5 motors have built in encoders that you can use in place of the potentiometer.
Try using a task to multithread using tasks (to run code asynchronously), so that even if the puncher is locked into a loop, it won’t affect other code from running.
//functions with control code
void puncherControl(){
//puncher control code
}
void robotControl(){
//robot control code
}
// put task initialization in main execution function
vex::task puncherTask(puncherControl);
vex::task controlTask(robotControl);
The problem with the older version is motor.rotateFor is blocking. You fixed this in the second version. Your new problem is actually the reverse of what someone above said. It’s not that it’s cycling too quickly, more like too slowly. But that’s not something to be fixed. The problem is that you press the button, but once you’ve released it you keep hitting the “else” to fire off motor.stop.
My personal preference is to use events.
void CockPuncher(void) {
Puncher.rotateFor(1.8,timeUnits::sec,100,velocityUnits::pct); // defined somewhere
}
Controller1.Button.pressed(CockPuncher); // placed before the while(true) loop
You could do similar for firing. I would not use motor.spin in conjunction with motor.rotateFor, though. I would use another motor.rotateFor for firing, so you always know how far that slip gear has rotated.