MoboTools Buttons, clearing a button press

UPDATE: Changed shortPressed() to just pressed and it seems to have fixed the problem but I really don't understand why......

Still super new to this. I have a set of 4 buttons and a switch (gnd or vcc). The switch selects which set of buttons can be used. I'm checking the switch using buttons.state(SW) and it it's low then buttons A and B are active and I'm using state on those to see if they are being pressed and held in (moving a stepper) When the switch is HIGH, buttons C and D are active and they start or stop an automatic cycle of the stepper (back and forth) I've got it more or less working right, the buttons work as they should and only the active ones work when the switch is in whichever state BUT if the switch is set to A/B and I press button C or D, nothing happens.... until I flip the switch to the automatic cycle position and it seems to have remembered that button C or D was pressed before and the automatic cycle starts instantly... Or at least that's what it looks to be doing. If I don't touch C or D I can switch back and forth without issue but if I press one while it's in manual mode it starts a cycle as soon as the switch is flipped over. Related Code:

#define MAX8BUTTONS     // This saves ressources if you don't need more than 8 buttons

#include <MobaTools.h>

/* eps32 test code */

const byte buttonPins [] = { 13,16,17,18, 19 };
enum : byte {SW_SEL, MAN_UP, MAN_DOWN, AUT_START, AUT_STOP };
const byte buttonCount = sizeof(buttonPins);

MoToButtons Buttons( buttonPins, buttonCount, 20, 500 ); // 500ms to distinguish short/long


//const int SEL_SW = 13;      // Manual / auto select switch
//const int MAN_UP = 16;      // Stepper Manual Up button
//const int MAN_DN = 17;      // Stepper Manual Down Button
//const int AUT_START = 18;   // Auto Start Button
//const int AUT_STOP = 19;    // Auto Stop Button
const int HOME_SW = 33;     // upper home switch

const int DIR = 2;          // Stepper DIR Pin 2
const int STEP = 4;         // Stepper STEP Pin 4

const int SPEED_IN = 32;    // Analog Input
//const int CYCLES_IN = xx;  // Analog Input
//const int DWELL_IN = xx;  // Analog Input

bool isStepping = false;
bool home_state = 0;
bool MAN_UP_STATE = LOW;
bool MAN_UP_PREV = LOW;
bool MAN_DN_STATE = LOW;
bool MAN_DN_PREV = LOW;
bool AUT_START_STATE = LOW;
//int DWELL_DATA = 0;
//int DWELL = 0;
//int Start_Time = 0;
//int Stop_Time = 0;
int Cycle_To_Do = 0;
int cycle_cnt=0;

long maxSpeed = 20000;
int ramp_len=500;

bool HOMED = false;

                              // ballscrew is 5mm pitch
const long EndPoint = 36576;  //52832 = 26"     36576 = 18"     24384 = 12"
long nextPos = 0;

MoToStepper myStepper (400,STEPDIR); // setps per rev and what type of control

void setup()
{  
  Serial.begin(115200);
//  pinMode(AUT_START,INPUT_PULLUP);
//  pinMode(AUT_STOP,INPUT_PULLUP);
//  pinMode(MAN_UP,INPUT_PULLUP);
//  pinMode(MAN_DN,INPUT_PULLUP);
  
  pinMode(HOME_SW,INPUT_PULLUP);
  
  myStepper.attach( STEP, DIR );      //4, 2
  myStepper.setSpeed( maxSpeed ); 
  myStepper.setRampLen(400);   //400
  
  delay(2000);        // need to prevent partial run when loading 

  Cycle_To_Do=2;          // this will come from selector switch CYCLES_IN

  // ***** HOMING THE CARRIGE *****
  myStepper.setZero(0);               //
  myStepper.setSpeed( 5000 );         // slow speed for homing
  
  myStepper.moveTo(3000);             // move the carrige down some
  while ( myStepper.distanceToGo()!=0 )
  {
    Serial.println("Staging");
    myStepper.moveTo(3000);   
  }

  while (HOMED == false )           // move up to home switch
   {
    Serial.println("Homing");
    home_state = digitalRead(HOME_SW);  // Check the switch
                                        // It was not working
                                        // correctly when I used
                                        // if (digitalRead(HOME_SW) == 0)
                                        // but the switch was buggy
                                        // so maybe ok now that its fixed

    myStepper.moveTo(myStepper.currentPosition()-400);    // keep moving up
        if (home_state==0)
        {
          myStepper.stop();
          myStepper.setZero(1200);          // come down off the switch
          myStepper.moveTo(0);
          HOMED=true;
          Serial.println("SOFT");
          
          Serial.println("HOMED");
        }
        
   }
   //if (myStepper.distanceToGo()==0 && HOMED == true)
   //     {
   //       myStepper.setSpeed(maxSpeed);     // Set full speed
   //       Serial.println("HOMED");
   //     }
}


void loop()
{
Buttons.processButtons();

if(Buttons.state(SW_SEL))    //****************** manual mode *********** 
{
  if(Buttons.state(MAN_UP))
  {
    Serial.println("UP button pressed");
    if (myStepper.currentPosition()-400 >0)
    {
      myStepper.moveTo(myStepper.currentPosition() - 400);
      if(digitalRead(HOME_SW)==false)
      {
        myStepper.stop();
        Serial.println("LIMIT");
      }
    }
    else
    {
      myStepper.moveTo(0);
    }
  }
  else if(Buttons.state(MAN_DOWN))
{
      myStepper.moveTo(myStepper.currentPosition() + 500);
      Serial.println("DOWN button pressed");
} 

}
else    //************************ automnatic mode ************************** 
{
  if( !isStepping )     // not currently cycling
  {
    if ( Buttons.shortPress(AUT_START) )
    //    if(digitalRead(AUT_START)==false) // check for start button press
      {
        myStepper.setSpeed(maxSpeed);     // Set full speed
        Serial.println("START button pressed");
        isStepping = true;
        myStepper.moveTo(EndPoint); 
      }
  }

  else   // is running cycles
  {
    if ( myStepper.distanceToGo()==0 )              // reached target
      {
        if(myStepper.currentPosition() == EndPoint) // if it's at the bottom
        {
          myStepper.moveTo(0);                      // new target at the top
        }
        else                                        // it's at the top
        {
          myStepper.moveTo(EndPoint);               // new targer at the bottom
          cycle_cnt++;                              // count the # of cycles
        }
                                                    // if it's at the top
                                                    // and had done the # of 
                                                    // cycles needed
      if( cycle_cnt>=Cycle_To_Do && myStepper.currentPosition() == 0)
      {
        myStepper.stop();
        isStepping = false;
        cycle_cnt=0;
        Serial.println("done");
      }

    }
    else            // moving between end points
    {
          if ( Buttons.shortPress(AUT_STOP) )
          //if(digitalRead(AUT_STOP)==false)        // check the stop button
        {
          Serial.println("STOP button pressed");
          myStepper.setSpeed(0);              // stop with ramp
//          stepperPause.setTime( 1000 );       // not sure if needed
          myStepper.setSpeed(maxSpeed);       // reset speed
          myStepper.moveTo(0);                // go back to the up position
          cycle_cnt=Cycle_To_Do;              // cancel any outstanding cycles
          isStepping = false;
        }
    }
  }
  }
}


I would have thought the Press of the AUT_START while SW_SEL was low would be wiped out next time through the loop where it was no longer pressed but apparently not.

Every iteration of the loop() calls

Buttons.processButtons();

without knowing how the library works, look into whether events, or however it reports activity, hang around or if they are "use it or lose it", like a button got pressed, if you didn't do anything with it, does it persist?

Either way, when you switch banks, you have to be to, or know you do not need to, flush the events from the other bank.

Read all the events and do nothing. In a simple library, one might only need to clear a flag that meant you were supposed to do something without actually doing anything - mande up library here:

  if (myButton.gotPresst()) ;  // eat the button went down event

where the gotPresst() method only returns true once per leading edge of a button push.

Does something like that account for the difference you are observing?

a7

You can use ezButton library. The library helps you manages the debounce and press events. You can also use an array to manage multiple button, see this example:

bool myButtons.pressed( uint8_t buttonNbr );
True if button ‘buttonNbr’ was pressed. This event is set when the button was pressed and
> reset after the call of this method or if it is released.

bool myButtons.shortPress( uint8_t buttonNbr );
True if button ‘buttonNbr’ was pressed short. This event is set when the button is released
after a short press and reset after the call of this method or if it is pressed again.

To distinguish a short press from a long press, this event can only be set after the button is released ( or 'short time' is over for longPress). The method 'pressed()' is simply a state change detection and is fired as soon as the button becomes pressed.

If you want to use shortPress() you can call it with every loop, but don't do anything with it if the switch is in the wrong position.

I think I get it now (the difference) On the iteration of the loop that contains the call to check the buttons, the pressed() sees that the button is no longer pressed and clears that state for that button while the shortpress() happened on the "un-press" and it doesn't see any change from last time and nothing was done with the information so it remains tripped...

Onward to the next problem of reading a couple of potentiometers (for maxspeed and a dwell between cycles) without blocking the code. fun never stops

Thanks again for the clarifications

Exactly, you got it :sunglasses:
I'm glad I could help.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.