Assign buttons to CNC Shield

Hello forum

I am in the process of using an Arduino UNO + CNC Shield + 3 x A4988 drivers + 3 Stepper Motors. I have limit switches assigned to each of the axis as well.

Thanks to the guidance and tutorials in this forum, I've managed to program the movement of the motor routines.

What i currently need help with is how to connect buttons to the CNC shield.

Button 1:
On press i would like to pause the logic/interrupt the program. Pressing it again would resume the program

Button 2:
Pressing it would reverse the movement of the motors till the trigger the limit switch, after which they will stop. Sort of a go-to-home/reset button.

Have shared my wip code here.

To give you a background, i am new to arduino. Have taken this up to address a specific automation requirement in my factory which is to wind tape around a sheet of acrylic.

// simple stepper motor control 
#define EN 8 // stepper motor enable
#define X_DIR 5 // x axis direction control
#define Y_DIR 6 // y axis direction control
#define Z_DIR 7 // z axis direction control
#define X_STP 2 // x axis step control
#define Y_STP 3 // y axis step control
#define Z_STP 4 // z axis step control
const int limitPin = 9; 
long int stps=15;
int delayTime=15;


void step(boolean dir, byte dirPin, byte stepperPin, int steps)
{
  digitalWrite(dirPin, dir);
  delay(50);
  for (int i = 0; i < steps; i++) {
    digitalWrite(stepperPin, HIGH);
    delayMicroseconds(8);
    digitalWrite(stepperPin, LOW);
    delayMicroseconds(800);
  }
}

void setup (){
  // setup stepper motor I/O pin to output
  pinMode(X_DIR, OUTPUT); pinMode(X_STP, OUTPUT);
  pinMode(Y_DIR, OUTPUT); pinMode(Y_STP, OUTPUT);
  pinMode(Z_DIR, OUTPUT); pinMode(Z_STP, OUTPUT);
  pinMode(EN, OUTPUT);
  digitalWrite(EN, LOW);
  pinMode(limitPin, INPUT_PULLUP);

}

void loop (){
  // 200 steps per turn
  while( digitalRead(limitPin) == LOW)
  step(false, X_DIR, X_STP, 180); 
  step(false, Y_DIR, Y_STP, 500); 
  step(false, Z_DIR, Z_STP, 200); 
  delay(1000);
  
   step(false, X_DIR, X_STP, 1800); 
  step(false, Y_DIR, Y_STP, 500); 
  step(false, Z_DIR, Z_STP, 200); 
  delay(1000);

  if( digitalRead(limitPin) == LOW)
  step(true, X_DIR, X_STP, 1800);  
  step(true, Y_DIR, Y_STP, 200); 
  step(true, Z_DIR, Z_STP, 200); 
  delay(1000);
  
  }

Hello and good morning
Did you run any tutorial to learn how a stepper work in conjunction with an Arduino?

Hi

Yes. I did go through the basic stepper code examples and watched a couple of youtube videos related to this to get the motors working as expected.

My next challenge is to incorporate buttons.

Have You been running the code You posted? I doubt You have.
Curly brackets looks like missing here and there.

Here is the pin mapping for the CNC shield V3 to the Uno. You can connect your switches to any of the unused pins like pins 12, 13 or the analog pins A0 - A3 (or, of course, the limit switch pins). The analog pins are really digital pins with analog input as a special function so can be used for switches.

cnc shield Uno pins

Tell which CNC shield You've got. The shields I've got has pins designed for end switches. They show up as Limit ?-Axis in the picture by @groundFungus.

Got the Protoneer CNC Shield v3. About the missing parenthesis, must have missed one while pasting. But the code works nevertheless.

The thing is I am trying to help out my father in law's business that has sunk a bit due to the pandemic and figuring out a way to automate a specific taping process which would otherwise require manual labour.

That sounds like the one I use.
Could You post the actual code again?
The first one can't possibly work.
In loop both while and if must be missing curly brackets.

// simple stepper motor control 
// only x axis is used for dolly
#define EN 8 // stepper motor enable
#define X_DIR 5 // x axis direction control
#define Y_DIR 6 // y axis direction control
#define Z_DIR 7 // z axis direction control
#define X_STP 2 // x axis step control
#define Y_STP 3 // y axis step control
#define Z_STP 4 // z axis step control
const int limitPin = 9; 
long int stps=15;
int delayTime=15;


/*
// step(): to control direction and steps of stepper motor
// parameter: dir for direction control, 
//                   dirPin maps to DIR pin of stepper motor,
//                   stepperPin maps to STEP pin of stepper motor
// return value: none
*/

void step(boolean dir, byte dirPin, byte stepperPin, int steps)
{
  digitalWrite(dirPin, dir);
  delay(50);
  for (int i = 0; i < steps; i++) {
    digitalWrite(stepperPin, HIGH);
    delayMicroseconds(8);
    digitalWrite(stepperPin, LOW);
    delayMicroseconds(800);
  }
}

void setup (){
  // setup stepper motor I/O pin to output
  pinMode(X_DIR, OUTPUT); pinMode(X_STP, OUTPUT);
  pinMode(Y_DIR, OUTPUT); pinMode(Y_STP, OUTPUT);
  pinMode(Z_DIR, OUTPUT); pinMode(Z_STP, OUTPUT);
  pinMode(EN, OUTPUT);
  digitalWrite(EN, LOW);
  pinMode(limitPin, INPUT_PULLUP);

}

void loop (){
  // 200 steps per turn
  while( digitalRead(limitPin) == LOW)
  step(false, X_DIR, X_STP, 180); // run 360 mm
  step(false, Y_DIR, Y_STP, 500); 
  step(false, Z_DIR, Z_STP, 200); 
  delay(1000);
  
   step(false, X_DIR, X_STP, 1800); // run 360 mm
  step(false, Y_DIR, Y_STP, 500); 
  step(false, Z_DIR, Z_STP, 200); 
  delay(1000);

  if( digitalRead(limitPin) == LOW)
  step(true, X_DIR, X_STP, 1800);  // run 360 mm in reverse direction
  step(true, Y_DIR, Y_STP, 200); 
  step(true, Z_DIR, Z_STP, 200); 
  delay(1000);
  
}```

This is essentially a mishmash of various codes i had read up in this forum. Would greatly appreciate a bit of handholding.

Would really want to make this happen for him

P.s. ignore the comments in the code.

Your while() and if() blocks are missing curly brackets like @ Railroader says. The way that you have it written, only the first line of code after each is executed conditionally. Look at the reference for the if structure and the while loop to see the syntax.

Also, the way that it is written, the motors will not run at the same time. They will run in sequence. X then Y then Z. Is that what you want? If they are to run simultaneously, you can use the MultiStepper class of the AccelSteper library.

The program seems to be working just like i wanted for some reason. Will read up on the parenthesis bit.

As for the sequence, yes I want motor B to start once motor A is finished.

If you can help me with the codes for the two buttons, I would be able to work on it, understand and customise it to my requirement.

As much as I want to completely understand the Arduino ecosystem, this project needs to be completed over the weekend, and hence the hurry.

To help you it would be very helpfull if you exactly describe the logic of the program. Up till now, I have no idea what the logic is, and when and how the motors should move - and when you like to interrupt them. Your program is blocking, and that's problematic if you want to react on button presses.

N.B.

That's the wrong way. You should insert comments to your sketch, that really describe what should happen here and there. This would help a lot too.

Copying the code into IDE, using autoformat, it looks like this:
Note the comment "Railroader complain".

void loop () {
  // 200 steps per turn
  while ( digitalRead(limitPin) == LOW)
      step(false, X_DIR, X_STP, 180); // Railroader complains
  step(false, Y_DIR, Y_STP, 500);
  step(false, Z_DIR, Z_STP, 200);
  delay(1000);

  step(false, X_DIR, X_STP, 1800); // run 360 mm
  step(false, Y_DIR, Y_STP, 500);
  step(false, Z_DIR, Z_STP, 200);
  delay(1000);

  if ( digitalRead(limitPin) == LOW)
      step(true, X_DIR, X_STP, 1800); // Railroader complains
  step(true, Y_DIR, Y_STP, 200);
  step(true, Z_DIR, Z_STP, 200);
  delay(1000);

}

digitalRead(limitPin) will only affect the X moves, not Y or Z. Is that good?

And the 180 steps are executed independently of what the limit switch does. So it can go up to 180 steps beyond the limit switch. Is that really ok?

Thank you for your responses.. Let me try and explain the logic a bit more clearly.

The whole setup is to automatically wrap tape around the sides of a rectangular 4 x 2 inch acrylic plate.

There are 3 motors in total in my setup - 1 for each axis

The action is as follows:
Motor A will perform an action - feed the blank acrylic tape to a central platform.
Motor B will then perform an action - the central platform will rotate thus wrapping the tape around the acrylic plate
Motor C will perform an action finally - An arm containing a blade will move along an axis and cut the excess tape after the above wrapping process is done.

When the above actions are taking place, say I want to pause the action at a particular step, I would like a button or switch to help me achieve that, pressing it again would resume the operation. This is to check for instance, if the tape wrapping process is going as planned and make adjustments if required after which the routine can be unpaused.

I am still reading up on how limit switches can be programmed, So in my code example I had pasted one such code after referring to an example, hence just one axis is mentioned.

Do let me know if this is clear.

Before thinking of running the entire project make sure the so to say subsystem, subfunctions, work. If they don't work all higher level thinking is waisted efforts..

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