Preventing repeated actuations while button pressed

#include "vex.h"
#include "wings.h"

using namespace vex;
using namespace std;

class WingsCon
{
    Wings wings = Wings();
    bool lwing_state = false;
    bool rwing_state = false;
    bool lbutton_state = false;
    bool rbutton_state = false;
    void toggle_lwing();
    void toggle_rwing();
    bool ldebounce(bool raw_button_state);
    bool rdebounce(bool raw_button_state);
    bool lbutton_debounce[3] = {false, false, false};
    bool rbutton_debounce[3] = {false, false, false};

    int lwing_timeout = 0;
    int rwing_timeout = 0;
    const int timeout_default = 7;

public:
    WingsCon();
    void flap(bool pressed_lbutton, bool pressed_rbutton);
};

WingsCon::WingsCon()
{
    lwing_timeout = 0;
    rwing_timeout = 0;
}

void WingsCon::flap(bool pressed_lbutton, bool pressed_rbutton)
{
    pressed_lbutton = ldebounce(pressed_lbutton);
    pressed_rbutton = rdebounce(pressed_rbutton);
    if (lwing_timeout <= 0 || lwing_timeout > 7){
        if (pressed_lbutton && !this->lbutton_state)
        {
            this->toggle_lwing();
            lwing_timeout = 7;
        }
    }
    else {
        lwing_timeout--;
    }
    if (rwing_timeout <= 0 || rwing_timeout > 7){
        if (pressed_rbutton && !this->rbutton_state)
        {
            this->toggle_rwing();
            rwing_timeout = 7;
        }
    }
    else {
        rwing_timeout--;
    }
    Brain.Screen.clearScreen();
    Brain.Screen.printAt(1, 15, false, "%d", lwing_timeout);
    Brain.Screen.printAt(1, 30, false, "%d", rwing_timeout);
    this->lbutton_state = pressed_lbutton;
    this->rbutton_state = pressed_rbutton;
}

bool WingsCon::ldebounce(bool raw_button_state)
{
    lbutton_debounce[2] = lbutton_debounce[1];
    lbutton_debounce[1] = lbutton_debounce[0];
    lbutton_debounce[0] = raw_button_state;
    if (lbutton_debounce[0] == lbutton_debounce[1] && lbutton_debounce[1] == lbutton_debounce[2] && lbutton_debounce[2] != lbutton_state)
        return !lbutton_state;
    return lbutton_state;
}

bool WingsCon::rdebounce(bool raw_button_state)
{
    rbutton_debounce[2] = rbutton_debounce[1];
    rbutton_debounce[1] = rbutton_debounce[0];
    rbutton_debounce[0] = raw_button_state;
    if (rbutton_debounce[0] == rbutton_debounce[1] && rbutton_debounce[1] == rbutton_debounce[2] && rbutton_debounce[2] != lbutton_state)
        return !rbutton_state;
    return rbutton_state;
}

void WingsCon::toggle_lwing()
{
    if(lwing_state == false) {
        wings.extend_lwing();
        lwing_state = true;
    }
    else {
        wings.retract_lwing();
        lwing_state = false;
    }
}

void WingsCon::toggle_rwing()
{
    if(this->rwing_state == false) {
        this->wings.extend_rwing();
        this->rwing_state = true;
    }
    else {
        this->wings.retract_rwing();
        this->rwing_state = false;
    }
}

The last two lines of the flap function aren’t doing anything, they’re not assigning the value of the pressed_lbutton state to the lbutton_state variable.

And the flap function timeout variable always goes to an absurdly high number when reset to 7.

Do you know why this may be? And are there other ways of preventing a component from being actuated multiple times when pressing a button?

You can use a function callback with the .pressed method to trigger a function when a button is pressed.

void toggleclaw() { claw.set(!claw.value()); }

And at the top of driver control before the while true put this

 Controller1.ButtonA.pressed(toggleclaw);
4 Likes