Chief Delphi

Chief Delphi (http://www.chiefdelphi.com/forums/index.php)
-   Java (http://www.chiefdelphi.com/forums/forumdisplay.php?f=184)
-   -   Java Toggle Button (http://www.chiefdelphi.com/forums/showthread.php?t=106698)

RoastBeefer 29-05-2012 13:13

Java Toggle Button
 
Hello, we have a conveyor belt powered by a motor on our bot. We want to press a button and make it run until we press the same button again. We cannot figure out how to do this. Here is what we currently have for our code:
Code:

//Conveyor Belt
      boolean belt = false;
      conveyorMotor.set(0);
      if(belt == false){
          if(stick.getRawButton(3)){
              belt = true;
              conveyorMotor.set(1);   
          }
          else if(belt == true){
              if(stick.getRawButton(3)){
              belt = false;
              conveyorMotor.set(0);   
              }             
          }

Currently this only turns on the belt while pressed and stops as soon as we let go. I feel like we're taking the totally wrong approach to this. Please help

Mark McLeod 29-05-2012 13:32

Re: Java Toggle Button
 
You need an interlock, something along the pseudo-code lines of:

Code:

boolean belt = false;
boolean toggle = true;
 
if (toggle && Button) {  // Only execute once per Button push
  toggle = false;  // Prevents this section of code from being called again until the Button is released and re-pressed
  if (belt) {  // Decide which way to set the motor this time through (or use this as a motor value instead)
    belt= false;
    conveyorMotor.set(1);
  } else {
    belt= true;
    conveyorMotor.set(0);
  }
} else if(Button == FALSE) {
    toggle = true; // Button has been released, so this allows a re-press to activate the code above.
}


artdutra04 29-05-2012 13:49

Re: Java Toggle Button
 
Quote:

Originally Posted by RoastBeefer (Post 1171902)
Hello, we have a conveyor belt powered by a motor on our bot. We want to press a button and make it run until we press the same button again. We cannot figure out how to do this. Here is what we currently have for our code:
Code:

//Conveyor Belt
      boolean belt = false;
      conveyorMotor.set(0);
      if(belt == false){
          if(stick.getRawButton(3)){
              belt = true;
              conveyorMotor.set(1);   
          }
          else if(belt == true){
              if(stick.getRawButton(3)){
              belt = false;
              conveyorMotor.set(0);   
              }             
          }

Currently this only turns on the belt while pressed and stops as soon as we let go. I feel like we're taking the totally wrong approach to this. Please help

Are you reinitializing the belt = false every time you execute the following code? If so, every time you run the above code, belt will get set to false and only become true if the button is currently pressed.

Also, to implement a toggling routine in code that takes input from a human, you need a way to slow it down or track previous states. For example, if a toggle function runs once every 10ms, a human pressing a button for 1/2 a second will cause the code to toggle 50 times.

There are two ways to overcome this: timers (only allowing the code to toggle once every ___ ms), or by only toggling the output on button transitions (such as from a not pressed state to a pressed state). Here's a real quick piece of [untested] code that works off the latter principle:

Code:

// Run this only once to initialize the variables
boolean beltStatus = false;
boolean previousButton = false;
boolean currentButton = false;

Code:

// Run the following code continuously
previousButton = currentButton
currentButton = stick.getRawButton(3);

if (currentButton && !previousButton)
{
        beltStatus = beltStatus ? false : true;
}

conveyorMotor.set((double)(beltStatus ? 1 : 0));

This code works by only looking for button transitions (e.g. last time the code ran the button was not pressed and this time it is pressed). It then toggles the state of beltStatus if this transition is detected. After that, the motor output is set by using another ternary operation to typecast the boolean belt state as a double.

Ether 29-05-2012 14:06

Re: Java Toggle Button
 
Quote:

Originally Posted by artdutra04 (Post 1171909)
beltStatus = beltStatus ? false : true;

or:

beltStatus = !beltStatus;




linuxboy 02-06-2012 04:30

In terms of having things run only once per button press the command based template for WPILib has a nice feature where it takes care of that for you in your OI class.

Pseudo code for OI.java
Button toggle = new JoystickButton(BUTTON-NUMBER); //put a joystick button into a var
toggle.whenPressed(new toggleConveyorCommand); //upon press run the toggle command once

Pseudo code for toggleConveyorCommand.java:
execute() { //the execute part
if(Conveyor.getInstance().isRunning()) {//if the conveyor singleton is running
Conveyor.getInstance().stop(); //stop it
} else { //if not
Conveyor.getInstance().start();// start it
}
}

daniel_dsouza 08-06-2012 16:04

Re: Java Toggle Button
 
You could do this in 2 parts:

Code:

//In the code that iterates:
    if (getButton() == true) state = true; //if button is pressed, var goes to true
    else if(state && !getButton()) { //if button was pressed, but isn't now
            belt.toggle();
            state= false; //says button was not pressed for next instance
    }

//In your belt class:
    public void toggle() {
          if (motor.get() == 1) motor.set(0); //this could be simpler depending on your application
          else if (motor.get == 0) motor.set(1);
    }

This is similar to some sensitivity code we wrote last year:
Code:

if (GAMEPAD_R1) shiftUp = true;
else if(GAMEPAD_R2) shiftDown = true;
else if(shiftUp && !GAMEPAD_R1) { //only allows shift if button has been pushed, then released, to allow one shift per click.
    drivetrain.shift(true);
    shiftUp = false;
}
else if(shiftDown && !GAMEPAD_R2){
    drivetrain.shift(false);
    shiftDown = false;
}



All times are GMT -5. The time now is 10:12.

Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi