is stepper.runToPosition(); a blocking function?

[update/fixed!(kinda/ish)]
So i have fix all this by designing a new programme with 1 raspberry pi + 3 arduino.
please read the 2nd page as i will tell you more about it, and perhaps you can take a look if you’re having similar trouble that i had. my email is fongching123.fc@gmail.com . feel free to ask me questions about it.

[end of the update part]

So I’m currently working on a project in which involves controlling a drilling tank. The tank’s arduino board(a mega in case you’re wondering, which also means I use only one to control everything) consist of various components:
ps2x receiver, slider(where I’m stuck at debugging, and the drill is attached to it), controller(for the wheels/trackers, not important to what I’m trying to fix), the relay(for the drill itself to spin CCW,CW, and stop, of course).

Now, I hope to make the slider to move down and up as I press a desired button on ps2, be it with acceleration or with constant speed(though I prefer the former).

void drilldown()
{
stepper.move(-20000);
stepper.runToPosition();
}

void drillup()
{
stepper.move(20000);
stepper.runToPosition();
}

//i use these voids just to “simplify” the code a bit

if (ps2x.ButtonPressed(PSB_CROSS))//something wrong with this
{

Serial.println(“manually going down”);
drilldown();
Serial.println(“going up”);
drillup();

}

Yet, whenever I press that button(cross,aka x) it will go up and down, but it will then execute all other buttons i designed in the code as well, which are,

void motorstop()
{
digitalWrite(drillpul, LOW);
digitalWrite(drilldir, LOW);
Serial.println(“drill off”);
}

void motorON()
{
digitalWrite(drillpul, LOW);
digitalWrite(drilldir, HIGH);
Serial.println(“drill on”);
}

if (ps2x.ButtonPressed(PSB_SQUARE))
{
motorON();
Serial.println(“square”);

}

if (ps2x.ButtonPressed(PSB_CIRCLE))
{
motorstop();
Serial.println(“circle”);
}

if (ps2x.ButtonPressed(PSB_SELECT))
{
Serial.println(“stop”);
stop();
}
delay(20);

AND

if (ps2x.ButtonPressed(PSB_START))
{
speed = 100;
for ( int i = 0; i < 3; i++) //not me bro
{

forward(speed);
delay(1500);
stop();
motorON();
drilldown();
drillup();
delay(100);
motorstop();
delay(1500);
Serial.println(“execute”);
delay(100);
}
}

As of now, I know the bug is due to the function stepper.runToPosition(); is a blocking function, so it will stop program execution until it is done(though I’m not yet grasp the idea of that fully). Therefore, it somehow neglects the if statements and run all functions in the button anyways.

Hence, is there anyway for me to make the slider move down with a buttonpressed, and perhaps with acceleration?And it would be very much helpful for you to send a solution with some explanation about the code and on what is a blocking function, as well as how the libraries work.

thank you so much for reading all this.

tank_3.3_testing_controls.ino (8.64 KB)

Why does nobody Read this before posting a programming question and follow the advice given ?

FongChing:
And it would be very much helpful for you to send a solution with some explanation

Please post your complete program. And please use the code button </>
codeButton.png

so your code 
looks like this

and is easy to copy to a text editor See How to use the Forum

Also please use the AutoFormat tool to indent your code for easier reading.

Generally if you want a responsive program it should not have any delay()s or other blocking functions.

...R

@FongChing

Other post/duplicate DELETED
Please do NOT cross post / duplicate as it wastes peoples time and efforts to have more than one post for a single topic.

Could you take a few moments to Learn How To Use The Forum.
It will help you get the best out of the forum in the future.
Other general help and troubleshooting advice can be found here.

Bob.

I am terribly sorry for not following the rules, I did skim the “read this before…” but I guess I didn’t put that in my mind.And do I have to reupload the post with the correct format or just let it be? It is the first time I posted a forum so hopefully you will forgive me actions. Here is the complete program, however, I can’t find the </> button in reply so I have to paste the code (auto formatted) without your desired text format.

(MOD EDIT)

#include <AccelStepper.h>

#include <PS2X_lib.h>  //for v1.6

//PS2手柄引脚;
#define PS2_DAT        13
#define PS2_CMD        11
#define PS2_SEL        10
#define PS2_CLK        12

// 电机控制引脚;
#define PWMA 5  //ENA
#define in1 6
#define in2 7
#define PWMB 4  //ENB
#define in3 8
#define in4 9

//STEPPER SLIDER SETTING
#define dirPin 51
#define stepPin 53
#define enaPin 49
#define motorInterfaceType 1

// DRILLER STETING
#define drillpul 45
#define drilldir 43


AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);
/******************************************************************
  select modes of PS2 controller:
    - pressures = analog reading of push-butttons
    - rumble    = motor rumbling
  uncomment 1 of the lines for each mode selection
******************************************************************/
#define pressures   true
//#define pressures   false
#define rumble      true
//#define rumble      false

PS2X ps2x; // create PS2 Controller Class

//right now, the library does NOT support hot pluggable controllers, meaning
//you must always either restart your Arduino after you connect the controller,
//or call config_gamepad(pins) again after connecting the controller.

int error = 0;
byte type = 0;
byte vibrate = 0;
int speed;//小车速度

void (* resetFunc) (void) = 0;

/******初始化******/
void setup()
{
 pinMode(PWMA, OUTPUT);
 pinMode(PWMB, OUTPUT);
 pinMode(in1, OUTPUT);
 pinMode(in2, OUTPUT);
 pinMode(in3, OUTPUT);
 pinMode(in4, OUTPUT);
 pinMode(drillpul, OUTPUT);
 pinMode(drilldir, OUTPUT);
 stepper.setMaxSpeed(20000);
 stepper.setAcceleration(10000);
 digitalWrite(enaPin, HIGH);
 stepper.setCurrentPosition(0);
 digitalWrite(drillpul, LOW);
 digitalWrite(drilldir, HIGH);

 Serial.begin(57600);
 delay(300) ;        //added delay to give wireless ps2 module some time to startup, before configuring it
 //CHANGES for v1.6 HERE!!! **************PAY ATTENTION*************

 //setup pins and settings: GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error
 error = ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT, pressures, rumble);

 if (error == 0)
 {
   Serial.print("Found Controller, configured successful ");
   Serial.print("pressures = ");
   if (pressures)
     Serial.println("true ");
   else
     Serial.println("false");
   Serial.print("rumble = ");
   if (rumble)
     Serial.println("true)");
   else
     Serial.println("false");
   Serial.println("Try out all the buttons, X will vibrate the controller, faster as you press harder;");
   Serial.println("holding L1 or R1 will print out the analog stick values.");
   Serial.println("Note: Go to www.billporter.info for updates and to report bugs.");
 }

 else if (error == 1)
 {
   Serial.println("No controller found, check wiring, see readme.txt to enable debug. visit www.billporter.info for troubleshooting tips");
   resetFunc();
 }
 else if (error == 2)
 {
   Serial.println("Controller found but not accepting commands. see readme.txt to enable debug. Visit www.billporter.info for troubleshooting tips");
 }

 else if (error == 3)
 {
   Serial.println("Controller refusing to enter Pressures mode, may not support it. ");
 }

 //  Serial.print(ps2x.Analog(1), HEX);

 type = ps2x.readType();
 switch (type)
 {
   case 0:
     Serial.print("Unknown Controller type found ");
     break;

   case 1:
     Serial.print("DualShock Controller found ");
     break;

   case 2:
     Serial.print("GuitarHero Controller found ");
     break;

   case 3:
     Serial.print("Wireless Sony DualShock Controller found ");
     break;
 }
}// END SETUP

//定义小车运动方式



void turnLeft(int speed)//左转
{
 digitalWrite(in1, HIGH);
 digitalWrite(in2, LOW);
 digitalWrite(in3, LOW );
 digitalWrite(in4, HIGH);
 analogWrite(PWMA, 150);
 analogWrite(PWMB, 150);
}

void forward(int speed)//右转 rotate right
{
 digitalWrite(in1, HIGH);
 digitalWrite(in2, LOW);
 digitalWrite(in3, HIGH);
 digitalWrite(in4, LOW);
 analogWrite(PWMA, speed);
 analogWrite(PWMB, speed);
}

void turnRight(int speed)//goes back both
{
 digitalWrite(in1, LOW);
 digitalWrite(in2, HIGH);
 digitalWrite(in3, HIGH );
 digitalWrite(in4, LOW);
 analogWrite(PWMA, speed);
 analogWrite(PWMB, speed);
}

void backward(int speed)//后退  //should go forward hypothetically
{
 digitalWrite(in1, LOW);
 digitalWrite(in2, HIGH);
 digitalWrite(in3, LOW);
 digitalWrite(in4, HIGH);
 analogWrite(PWMA, speed);
 analogWrite(PWMB, speed);
}

void stop() // 停止;
{
 digitalWrite(in1, LOW);
 digitalWrite(in2, LOW);

 analogWrite(PWMA, 0);
 analogWrite(PWMB, 0);
 delay(20);
}
void drilldown()
{

 //digitalWrite(enaPin, LOW);
 stepper.move(-20000);
 stepper.runToPosition();

 //delay(1000);
}
void drillup()
{
 //digitalWrite(enaPin,LOW);
 stepper.move(20000);
 stepper.runToPosition();

 //delay(1000);
}

void motorstop()
{
 digitalWrite(drillpul, LOW);
 digitalWrite(drilldir, LOW);
 Serial.println("drill off");
}
void motorON()
{
 digitalWrite(drillpul, LOW);
 digitalWrite(drilldir, HIGH);
 Serial.println("drill on");
}

void loop() {
 /* You must Read Gamepad to get new values and set vibration values
   ps2x.read_gamepad(small motor on/off, larger motor strenght from 0-255)
   if you don't enable the rumble, use ps2x.read_gamepad(); with no values
   You should call this at least once a second
 */
 if (error == 1) {//skip loop if no controller found
   return;
 }
 if (type == 2) { //Guitar Hero Controller
   return;
 }
 else  { //DualShock Controller
   ps2x.read_gamepad(false, vibrate); //read controller and set large motor to spin at 'vibrate' speed
 }

 //start 开始运行,电机初PWM为100;
 if (ps2x.ButtonPressed(PSB_START))
 {
   speed = 100;
   for ( int i = 0; i < 3; i++) //not me bro
   {

     forward(speed);
     delay(1500);
     stop();
     motorON();
     drilldown();
     drillup();
     delay(100);
     motorstop();
     delay(1500);
     Serial.println("execute");
     delay(100);
   }
 }
 // Stop

 if (ps2x.ButtonPressed(PSB_SELECT))
 {
   Serial.println("stop");
   stop();
 }
 delay(20);


 if (ps2x.ButtonPressed(PSB_CROSS))//something wrong with this
 {
   //drillstate = LOW;
   Serial.println("manually going down");
   drilldown();
   Serial.println("manually going up");
   drillup();
   delay(100);
   Serial.println("at position zero");
 }
 if (ps2x.ButtonPressed(PSB_SQUARE))
 {
   motorON();
   Serial.println("square");

 }
 if (ps2x.ButtonPressed(PSB_CIRCLE))
 {
   motorstop();
   Serial.println("circle");
 }







 if (ps2x.Button(PSB_L1) || ps2x.Button(PSB_R1)) { //print stick values if either is TRUE(摇杆)
   Serial.print("Stick Values:");
   Serial.print(ps2x.Analog(PSS_LY), DEC); //Left stick, Y axis. Other options: LX, RY, RX
   Serial.print(",");
   Serial.print(ps2x.Analog(PSS_LX), DEC);
   Serial.print(",");
   Serial.print(ps2x.Analog(PSS_RY), DEC);
   Serial.print(",");
   Serial.println(ps2x.Analog(PSS_RX), DEC);

   int LY = ps2x.Analog(PSS_LY);
   int LX = ps2x.Analog(PSS_LX);
   int RY = ps2x.Analog(PSS_RY);
   int RX = ps2x.Analog(PSS_RX);

   if (LY < 125) //前进
   {
     speed = 2 * (127 - LY);
     forward(speed);
     delay(20);
   }

   if (LY > 128) //后退
   {
     speed = 2 * (LY - 128);
     backward(speed);
     delay(20);
   }

   if (LX < 125) //左转
   {
     speed = 2 * (127 - LX);
     turnLeft(speed);
     delay(20);
   }

   if (LX > 128) //右转
   {
     speed = 2 * (LX - 128);
     turnRight(speed);
     delay(20);
   }

   if (LY >= 125 && LY <= 128 && LX >= 125 && LX <= 128) //如果摇杆居中
   {
     stop();
     delay(20);
   }
   else
   {
     stop();
     delay(20);
   }

 }
}

Modified you code for you. You got that one for free LOL
Next time it will be up to you.

Bob.

</ hello? />

wait a minute, is it just me or there is no tool bar in quick reply???

Imgur

Imgur

is it just me or there is no tool bar in quick reply???

There is if you enable it in your forum setup

UKHeliBob:
There is if you enable it in your forum setup

It would be more helpful for newbies (and for us) if it was enabled by default - may you could have a word with the developers?

That sort of change should not take more than 5 minutes of someone's time.

...R

[/ I guess /] you can type [//]??

well never mind [//] doesn't work

ok hi

Anyways, is there anyway to run the slider without having the bug I mentioned at my first (chronologically and literally) post? I am on the verge of giving up and losing hope......

FongChing:
Anyways, is there anyway to run the slider without having the bug I mentioned at my first (chronologically and literally) post? I am on the verge of giving up and losing hope…

I presume you are referring to the program in Reply #4 ?

I am not familiar with the PS2. Does your Arduino program receive the correct data for the button that you want to cause the slider to move?

And I don’t know which piece of code in your program is intended to move the slider - is it the drilldown() function? If so, why refer to it as a slider?

…R

@Robin2 thanks for replying.

1.answer to your first question :

Robin2:
I presume you are referring to the program in Reply #4 ?

  1. Yes.

  2. answer to your second question :

Robin2:
I am not familiar with the PS2. Does your Arduino program receive the correct data for the button that you want to cause the slider to move?

2.I have already confirmed that the button chosen transmit the correct signal to the Arduino board(the tank) (by using the Serial.print() and also every other buttons work the exact way I want it to be). So basically the problem is narrowed down to the void drilldown() function (inside it)

3&4. answer to your third and fourth question :

Robin2:
And I don't know which piece of code in your program is intended to move the slider - is it the drilldown() function? If so, why refer to it as a slider?

3&4. yes, the drilldown() is to move the slider down(or leftwards, rightwards, upwards, depends on how you orientate the slider) And long story short, the drill is screwed into the moving block of the slider, therefore by moving the slider, the mini drill will also move, hence I call the function as drilldown

Also, Ive looked up to this forum which had a slider moving problem once again

but other people suggest him to use multistepper library, could that be a way? even though I've tried it and it was futile( I haven't tried tried but simply tested it with one or two functions in it, and the multi lib is already in accel lib)

Side note : you replied to that person 6 years ago, and now is 2020, a decade gone, just like that, wow!

OK, if I understand things you want a piece of code something like this

if (ps2x.ButtonPressed(xxxxxx)) {
   // use the drilldown() function to do something
}

You already seem to have some stuff like that in your program - calling motorON() and motorstop(). Are those parts working?

If they are, then what exactly do you want to happen using the drilldown() function?

And what actually happens with the code in Reply #4 that calls drilldown()?

...R

@Robin2

0.your first question with insinuation

Robin2:
OK, if I understand things you want a piece of code something like this

if (ps2x.ButtonPressed(xxxxxx)) {

// use the drilldown() function to do something
}

  1. Yes, your description of my code is exactly the same it goes (that means what you thinking is what I'm thinking)

!.first question :

  1. Yes, motorON() and motorstop() are working, they turn on the drill(which it will spin clockwise fast, like very fast) and turn of the drill respectively. And YES, they will execute when the buttons that are with those function perfectly.

Let me answer your second and third question concurrently, so that it will be more clear to you.

2&3 questions :
2&3. So what I want for drilldown(){ or drillup() } is to move the slider down or up, just move like, let's say 20000 steps or so, and preferably with ACCELERATION.

HOWEVER,(Q3), right now, the drilldown() function does move exactly like I wanted it to(moving down for like 20000 steps with accel), but then after it execute the function, the Arduino board will run all the buttons in ps2 controller (only the buttons that are programmed in the code, and they will run exactly in the order I typed in the code, meaning square -> circle -> select -> start -> then L1|L2 -> AND THEN BACK TO NORMARL, which means I can control the Arduino tank, once all of the above are ran once)

OHHH, also I tried using like a for loop self-made function to move the slider exactly the same as accel stepper, however, it results in the same thing.

Which leads me to a thing I don't get, why a blocking function will cause the Arduino board to ignore or the if condition and call all the functions on the ps2x, and to make it crystal clear you (hopefully, I am awful at conveying meanings) the analog stick on the ps2x would not run even though all others do, I'm pretty confident this is because the code requires L1|L2 and either stick to press together, but then the bug(run everything) only runs all buttons consecutively, so the analog sticks would not be called.

FongChing:
but then after it execute the function, the Arduino board will run all the buttons in ps2 controller

I don't understand what you mean.

Do you mean that it calls functions for PS2 buttons that have not been pressed?

You have a function called ps2x.read_gamepad() which (I presume) gets the values from the PS2. Is there another function that could be used to delete any button-presses that might have accumulated?

...R

@Robin2

Robin2:
Do you mean that it calls functions for PS2 buttons that have not been pressed?

Yes exactly, it will call every single buttons consecutively after I pressed the "cross" or "triangle button".

Robin2:
You have a function called ps2x.read_gamepad() which (I presume) gets the values from the PS2. Is there another function that could be used to delete any button-presses that might have accumulated?

I am pretty sure that the bug is not due to button-presses that have accumulated, because the bug happens even when I pressed x or triangle every time I reupload or reset the Arduino board. And the fact that the buttons are called in order of the void loop() part of the code. And I do think if you don't have readgamepad() nothing can be done.

Why is this line

if (ps2x.Button(PSB_L1) || ps2x.Button(PSB_R1))

using Button() rather than ButtonPressed() ?

Can you post a link to the documentation for the PS2X library?

...R

hmmmm, it is pretty weird to look back what you had been struggling before. so in case another curious youngling stumble upon the exact trouble i had(though i have a strong feeling nobody will ever read this and find this problem anyways). this is my solution. I switched to using raspberrypi, and 3 extra arduino to control each part. So i use raspberry pi to control the wheels, 1 arduino for slider, drill(relay), and a stepper motor, the other two for ultrasonic sensor. And boom, pretty much a bugless tank u get.

though hate to break it to you, this is all i can tell you, i'm not sure u can use one arduino to do all this, but if you want to take it to the next level, than use raspberry pi(it can even take photos, recording with camera sensor). Good luck on your endeavour and never ever give up!