Arduino UNO CNC shield - controlling 4 stepper motors

Hello all,

For a small home project I need to control four stepper motors individually. The Arduino UNO CNC shield looks perfect, it seems it can drive four stepper motors as it allows driving four stepper drivers. However, when looking at example code, e.g. link then I see only three stepper motors being driven (i.e. x y and z).

  1. How is the fourth driver used?
  2. Can it also fully drive a stepper motor as well? Referring to the fact that the CNC shield uses Arduino PWM ports of which the UNO only has three (and not four...)

Kind regards,
Arjan

Yes it can. I don't know any stepper library that uses PWM to control the stepper. You don't need PWM capable pins to drive the stepper.

Hi MicroBahner, thanks for replying. I got it, I mistakenly thought that the board was using PWM as the UNO's PWM pins were used. However, at closer inspection the PWM function of these pins isn't used, they are just used as normal digital pins.

By adding two jumpers (orange and green box) at the location shown in the picture the Driver A can be controlled by using pins 12 and 13.

Arjan

You use the 4th motor (A) just like the other 3 except the step pin for the A is pin 12 and the dir pin is pin 13 once the jumpers are in place. That means that you no longer have the spindle enable or spindle direction control.

#define CW 0
#define CCW 1

const byte stepPin = 12; // x axis > 2, y axis > 3, z axis > 4 a axis > 12
const byte dirPin = 13; // x axis > 5, y axis > 6, z axis > 7 a axis > 13
const byte enablePin = 8; // enable on the CNC shield is held HIGH (disabled) by default

unsigned long stepTime = 2400;

void setup()
{
   Serial.begin(115200);
   pinMode(stepPin, OUTPUT);
   pinMode(dirPin, OUTPUT); 
   pinMode(enablePin, OUTPUT);
   digitalWrite(enablePin, LOW);  // enable steppers
   digitalWrite(dirPin, CCW);
}

void loop()
{
  oneStep();
}

void oneStep()
{
   static unsigned long timer = 0;
   unsigned long interval = stepTime;
   if (micros() - timer >= interval)
   {
      timer = micros();
      digitalWrite(stepPin, HIGH);
      delayMicroseconds(10);
      digitalWrite(stepPin, LOW);
   }
}

If you need a limit (home) switch for the A axis (as well as x, y, z), you will need to use one of the analog pins for the sensor.

And here is the test code from the link in the op modified to include the A axis.

#include <AccelStepper.h>

// Voor de Arduino Uno + CNC shield V3
#define MOTOR_X_ENABLE_PIN 8
#define MOTOR_X_STEP_PIN 2
#define MOTOR_X_DIR_PIN 5


#define MOTOR_Y_ENABLE_PIN 8
#define MOTOR_Y_STEP_PIN 3
#define MOTOR_Y_DIR_PIN 6


#define MOTOR_Z_ENABLE_PIN 8
#define MOTOR_Z_STEP_PIN 4
#define MOTOR_Z_DIR_PIN 7

#define MOTOR_A_ENABLE_PIN 8
#define MOTOR_A_STEP_PIN 12
#define MOTOR_A_DIR_PIN 13

AccelStepper motorX(1, MOTOR_X_STEP_PIN, MOTOR_X_DIR_PIN);
AccelStepper motorY(1, MOTOR_Y_STEP_PIN, MOTOR_Y_DIR_PIN);
AccelStepper motorZ(1, MOTOR_Z_STEP_PIN, MOTOR_Z_DIR_PIN);
AccelStepper motorA(1, MOTOR_A_STEP_PIN, MOTOR_A_DIR_PIN);

void setup()
{
   pinMode(MOTOR_X_ENABLE_PIN, OUTPUT);
   pinMode(MOTOR_Y_ENABLE_PIN, OUTPUT);
   pinMode(MOTOR_Z_ENABLE_PIN, OUTPUT);
   pinMode(MOTOR_A_ENABLE_PIN, OUTPUT);

   motorX.setEnablePin(MOTOR_X_ENABLE_PIN);
   motorX.setPinsInverted(false, false, true);
   motorX.setAcceleration(100);
   //motorX.setMaxSpeed(100);
   //motorX.setSpeed(100);
   motorX.enableOutputs();

   motorY.setEnablePin(MOTOR_Y_ENABLE_PIN);
   motorY.setPinsInverted(false, false, true);
   motorY.setAcceleration(100);
   //motorY.setMaxSpeed(100);
   //motorY.setSpeed(100);
   motorY.enableOutputs();

   motorZ.setEnablePin(MOTOR_Z_ENABLE_PIN);
   motorZ.setPinsInverted(false, false, true);
   motorZ.setAcceleration(100);
   //motorZ.setMaxSpeed(100);
   //motorZ.setSpeed(100);
   motorZ.enableOutputs();

   motorA.setEnablePin(MOTOR_Z_ENABLE_PIN);
   motorA.setPinsInverted(false, false, true);
   motorA.setAcceleration(100);
   //motorA.setMaxSpeed(100);
   //motorA.setSpeed(100);
   motorA.enableOutputs();
}

void loop()
{
   motorX.move(3000);
   motorX.run();
   motorY.move(3000);
   motorY.run();
   motorZ.move(3000);
   motorZ.run();
   motorA.move(3000);
   motorA.run();
}


Thank you groundFungus.