Mobatools step counting blocking issue

I'm having a problem with my CW jog button. I'm hoping to read the steps as I hold the button down and stop when I release button. When I press the CW button, I have stepper_1.moveTo(20000); so that it stops at the 20000 position if I held it down. However, I think my code is blocking it somehow. When I press and release the button, the stepper just runs all the way to 20000 while its counting steps in serial monitor. I tried moving this code to the Loop section and no change. Any ideas?

Here's the problem area -

void toCWdirection() {                                // buffer tank jog CW
    stepper_1.setSpeedSteps( 5000, 0 );
    stepper_1.moveTo(20000); 
    while (stepper_1.moving())
      Serial.println(stepper_1.readSteps()); 
                                     
  }

Here's my complete code -

// trying to home without use of limit switch. cw ccw buttons go same way.


#define MAX8BUTTONS // saves RAM because only 4 switches are used
#define MAX_STEPPER 6
#include <MobaTools.h>

const int STEPS_PER_REV = 800;
const int POS_MAX = 20000;
const int FORTY_METER_POSITION = 5000;
const int EIGHTY_METER_POSITION = 10000;
const int ONESIXTY_METER_POSITION = 16000;

//create stepper object ( 800 steps / rev - 1/4 microstep )

// Stepper 1 buffer tank
const byte stepper1_pul = 2;
const byte stepper1_dir = 3;
MoToStepper stepper_1( STEPS_PER_REV, STEPDIR );

// Stepper 2 IPA tank
const byte stepper2_pul = 4;
const byte stepper2_dir = 5;
MoToStepper stepper_2( STEPS_PER_REV, STEPDIR );

const byte enaPin = 7;




// buttons must switch to Gnd
enum { buttonZero, buttonCW, buttonCCW, forty_meter_button, eighty_meter_button, onesixty_meter_button } ; // create names for the buttons
const byte buttonPins[] = {22, 23, 24, 26, 27, 28 }; // assign pins to the buttons
const byte buttonCnt = sizeof(buttonPins);
MoToButtons myButton( buttonPins, buttonCnt, 20, 500 );

// limit switch at refpoint
const byte refPin1 = 25;         // limit pin stepper 1 homing
const byte refPin2 = 29;         // limit pin stepper 2 homing
const byte atRefpoint = LOW;   // dependig wether it is a NO or NC switch





void setup() { 
  Serial.begin(115200); while (!Serial);


// Stepper 1
  stepper_1.attach( stepper1_pul, stepper1_dir );
  stepper_1.attachEnable( enaPin, 10, LOW );         // Enable active

// Stepper 2
  stepper_2.attach( stepper2_pul, stepper2_dir );
  stepper_2.attachEnable( enaPin, 10, LOW );        // Enable active

  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(refPin1, INPUT_PULLUP );
  pinMode(refPin2, INPUT_PULLUP );

  Serial.println("Starting loop");
}

void loop() 

{
  myButton.processButtons();          // reading and processing the buttons ( e.g. debouncing and state change detection)

  digitalWrite( LED_BUILTIN, digitalRead( refPin1 ) );

  
    // check buttons and react accordingly
  if ( myButton.pressed(buttonZero) ) {                                   // home all steppers to zero position
    Serial.println(" Find ref point");
    toRefPoint();
  }
  if ( myButton.pressed(buttonCW) ) {                                     // jog slow clockwise direction
    Serial.println("Jog CW towards end");
    toCWdirection();
  }
  if ( myButton.pressed(buttonCCW) ) {                                    // jog slow counter clockwise direction
    Serial.println("Jog CCW back to 0 ");
    toCCWdirection();
  }
  if ( myButton.pressed(forty_meter_button) ) {                           // move to 40m position
    Serial.println("Move towards the 40M position");
    toFortyPoint();
  }
   if ( myButton.pressed(eighty_meter_button) ) {                         // move to 80m position
    Serial.println("Move towards the 80M position");
    toEightyPoint();
  }
   if ( myButton.pressed(onesixty_meter_button) ) {                       // move to 160m position
   Serial.println("Move towards the 160M position");
   toOnesixtyPoint();
  }
   
  if ( myButton.released(buttonCW) || myButton.released(buttonCCW) ) {
   Serial.println("Stop the stepper");
   stepper_1.rotate(0);
  }

}

void toRefPoint() {                                    // Homing: move all steppers to ref point and set zeropoint

    Serial.println("homing buffer tank...");                      // buffer tank start homing...
    stepper_1.setSpeedSteps( 10000, 200 ); 
    stepper_1.doSteps(-2000);
    while (stepper_1.moving()) {
      Serial.println(stepper_1.readSteps());
    }
    
    delay (2000);
    
    Serial.println("hard stop reached, now move forward a small bit");
    stepper_1.doSteps(100);
    while (stepper_1.moving()) {
      Serial.println(stepper_1.readSteps());
    }
    Serial.println("now set zero");  
    stepper_1.setZero();
    stepper_1.moveTo(0);
    while (stepper_1.moving()) {
      Serial.println(stepper_1.readSteps());
    }
    
    Serial.println("buffer tank homing finished!");
} 
  


void toFortyPoint() {                                  // buffer tank 40 meter position
    stepper_1.setSpeedSteps( 40000, 500 );
    stepper_1.moveTo( FORTY_METER_POSITION ); 
    while (stepper_1.moving())
      Serial.println(stepper_1.readSteps());                              
  
  }

void toEightyPoint() {                                 // buffer tank 80 meter position
    stepper_1.setSpeedSteps( 40000, 500 );
    stepper_1.moveTo( EIGHTY_METER_POSITION ); 
    while (stepper_1.moving())
      Serial.println(stepper_1.readSteps());                              
  
  }

void toOnesixtyPoint() {                               // buffer tank 160 meter position
    stepper_1.setSpeedSteps( 40000, 500 );
    stepper_1.moveTo( ONESIXTY_METER_POSITION );
    while (stepper_1.moving())
      Serial.println(stepper_1.readSteps());                               
  
  }

void toCWdirection() {                                // buffer tank jog CW
    stepper_1.setSpeedSteps( 5000, 0 );
    stepper_1.moveTo(20000); 
    while (stepper_1.moving())
      Serial.println(stepper_1.readSteps()); 
                                     
  }

void toCCWdirection() {                                // buffer tank jog CCW
    stepper_1.setSpeedSteps( 5000, 0 );
    stepper_1.moveTo(0); 
      

                      
  }
 

You will have to write a piece of code that checks the button all the time and as soon as you release the button execute a function-call

stepper_1.stop();

or
instead of commanding the MobaTools to move to position 20000
writing code that does
a single step
check if button is still pressed
if yes do another single step
if no: no more steps

this while loop must have inside the while-loop

myButton.processButtons(); 
// checking if button is still pressed
// if button is released 
stepper_1.stop();
// leave while-loop

Ok I tried this here. I don't think I'm writing it correctly.

void toCWdirection() {                                // buffer tank jog CW
    stepper_1.setSpeedSteps( 2000, 0 );
    stepper_1.moveTo(20000); 
    while (stepper_1.moving() || myButton.processButtons()); 
      Serial.println(stepper_1.readSteps());
      stepper_1.stop();
                                       
  }

what do you think?

where in this line of code

myButton.processButtons();

is exactly specified that one special particular button that you are pressing / releasing?

nowhere.

You are already using different buttons. Which lines of code do specify a button and the button's-state?

Me personal I will not post working code.
You will have to ask specific questions and post your best attempts how to write the code

The function-call

stepper_1.stop();

does what its name says.
After installing the MobaTools on your computer there is a subfolder
"MobaTools"
inside this folder there is the documentation as a PDF-file
"MobaTools-260-en.pdf"
or
maybe "MobaTools-250-en.pdf"
or
"MobaTools-251-en.pdf"
or similar
Inside the documentation you can read what

stepper_1.stop();

is doing

1 Like

Ok that makes sense. I need to give this more thought. I will look for that PDF file and read it.

Here is what I have now.

void toCWdirection() {                                // buffer tank jog CW
    stepper_1.setSpeedSteps( 2000, 0 );
    stepper_1.moveTo(20000);
    while (stepper_1.moving() && myButton.pressed(buttonCW));
    Serial.println(stepper_1.readSteps());  
  }   

However, this only prints the current step location once upon pushing the button and stops printing. But now the stepper does stop when I release the button. I would have thought this while loop would have fixed it as it makes sense to me. I wasn't sure where the stepper_1.stop(); would even go to help. I've been reading the Mobotools pdf file.

This doesn't work. You must learn to write nonblocking code - at least code that is only blocking for very short periods. The evaluation of the buttons needs the .processButtons() method to be called frequently - at least more frequently than the debug time ( 20ms in your sketch ).

Ok I see. Let me think about this. I have a code blocking misunderstanding.

Here's another failed attempt -

void toCWdirection() {                                // buffer tank jog CW
    stepper_1.setSpeedSteps( 2000, 0 );
    stepper_1.moveTo(20000);
    while (stepper_1.moving() && !myButton.released(buttonCW))
      Serial.println(stepper_1.readSteps());
    if (myButton.released(buttonCW))
    stepper_1.stop();
  }  

Where can I see an example of some non blocking while loop code that might work for me?

each and every while-loop without any exception is blocking !
non-blocking while-loop is a contradiction in itself.

The only way to write NON-blocking code is to have zero-while-loops and zero for-loops

The only way to write NON-blocking code is to have one

SINGLE loop

This loop is

void loop() itself

For NON-blocking code ALL looping must be based on the looping of
void loop() itself

I have already written how it must be coded

This is still blocking code because it uses a inner while-loop.
This while-loop reacts only on that one particular button and nothing else

void toCWdirection() {                                // buffer tank jog CW
  stepper_1.setSpeedSteps( 2000, 0 );
  stepper_1.moveTo(20000);

  while (stepper_1.moving() ) { // <<<= opening curly brace
    // reading in the state of the button again and again and again
    // how should your code "know" if a button is pressed or released LATER
    // The only way is to read-in the button-state
    // again and again and again I_N_S_I_D_E the while-loop
    myButton.processButtons(); // <<< read-in button-states

    if (myButton.released(buttonCW)) {
      stepper_1.stop();
      break;
    }
    Serial.println(stepper_1.readSteps());
  }
}

Ok I see what you're saying now! So we have to monitor the myButton.processButtons();inside the while loop for any changes in condition. And if my button gets released, the break; exits the loop. This makes me think about this a different way now. Thank you for your help and time to write out the detailed explanation of whats going on. I've been working on this problem all night haha.

This works great now with your help. Thanks again! Time to move on to the next issue lol

do you want to control how far the stepper goes with buttons?

something like this

int pos;
void loop ()
{
    myButton.processButtons ();

    if (myButton.pressed(buttonCW) ) {
        stepper_1.setSpeedSteps ( 40000, 500 );
        toCWdirection ();
        do {
            pos += 100;
            stepper_1.moveTo (pos);
            while (stepper_1.moving())
                Serial.println (stepper_1.readSteps());

            myButton.processButtons ();
        } while (myButton.pressed(buttonCW));
    }

    if (myButton.pressed(buttonCCW) ) {
        stepper_1.setSpeedSteps ( 40000, 500 );
        toCCWdirection ();
        do {
            pos -= 100;
            stepper_1.moveTo (pos);
            while (stepper_1.moving())
                Serial.println (stepper_1.readSteps());

            myButton.processButtons ();
        } while (myButton.pressed(buttonCCW));
    }

Ok I see! Thank you for posting this. I will try this out as well!

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