StepperSweep Arduino Sketch

This sketch is used by Exercise: A4988 Stepper Motor Driver.

Full Source Code

The full code is all in one file StepperSweep.ino.

  1// StepperSweep - move a stepper motor at different rates
  2//
  3// Copyright (c) 2016, Garth Zeglin.  All rights reserved. Licensed under the
  4// terms of the BSD 3-clause license as included in LICENSE.
  5//
  6// This program assumes that:
  7//
  8//  1. A A4988 stepper motor driver is connected to pins 2 and 3.
  9//  2. A control potentiometer can vary the voltage on A0.
 10//  3. The serial console on the Arduino IDE is set to 9600 baud communications speed.
 11
 12// ================================================================================
 13// Define constant values and global variables.
 14
 15// Define the pin numbers on which the outputs are generated.
 16#define DIR_PIN 2     // The direction pin controls the direction of stepper motor rotation.
 17#define STEP_PIN 3    // Each pulse on the STEP pin moves the stepper motor one angular unit.
 18#define ENABLE_PIN 4  // Optional control of the driver power.
 19
 20// Alternate definitions for the Protoneer CNC Shield board X axis.
 21// #define DIR_PIN 5
 22// #define STEP_PIN 2
 23// #define ENABLE_PIN 8
 24
 25// ================================================================================
 26// Configure the hardware once after booting up.  This runs once after pressing
 27// reset or powering up the board.
 28void setup(void)
 29{
 30  // Initialize the stepper driver control pins to output drive mode.
 31  pinMode(DIR_PIN, OUTPUT); 
 32  pinMode(STEP_PIN, OUTPUT);
 33  pinMode(ENABLE_PIN, OUTPUT);
 34
 35  // Drive the /ENABLE pin low to keep the motor always energized.
 36  digitalWrite(ENABLE_PIN, LOW);
 37  
 38  // Initialize the serial UART at 9600 bits per second.
 39  Serial.begin(9600);
 40} 
 41/****************************************************************/
 42/// Rotate the stepper motor a specified distance at constant speed.  It does
 43/// not return until the motion is complete, e.g. it 'blocks' for the duration.
 44///
 45/// \param steps angular distance to move; the sign determines the direction,
 46///		 but the precise angle depends upon the driver microstepping
 47///		 configuration and type of motor.
 48///
 49/// \param speed speed in steps/second
 50
 51void rotate_stepper(int steps, float speed)
 52{
 53  // Configure the direction pin on the stepper motor driver based on the sign
 54  // of the displacement.
 55  int dir = (steps > 0)? HIGH:LOW;
 56  digitalWrite(DIR_PIN, dir); 
 57
 58  // Find the positive number of steps pulses to emit.
 59  int pulses = abs(steps);
 60
 61  // Compute a delay time in microseconds controlling the duration of each half
 62  // of the step cycle.
 63  //  microseconds/half-step = (1000000 microseconds/second) * (1 step/2 half-steps) / (steps/second)
 64  unsigned long wait_time = 500000/speed;
 65
 66  // The delayMicroseconds() function cannot wait more than 16.383ms, so the
 67  // total delay is separated into millisecond and microsecond components.  This
 68  // increases the range of speeds this function can handle.
 69  unsigned int msec = wait_time / 1000;
 70  unsigned int usec = wait_time - (1000*msec);
 71
 72  // Print a status message to the console.
 73  Serial.print("Beginning rotation of ");
 74  Serial.print(steps);
 75  Serial.print(" steps with delay interval of ");
 76  Serial.print(msec);
 77  Serial.print(" milliseconds, ");
 78  Serial.print(usec);
 79  Serial.print(" microseconds.\n");
 80  
 81  // Loop for the given number of step cycles.  The driver will change outputs
 82  // on the rising edge of the step signal so short pulses would work fine, but
 83  // this produces a square wave for easier visualization on a scope.
 84  for(int i = 0; i < pulses; i++) {
 85    digitalWrite(STEP_PIN, HIGH);
 86    if (msec > 0) delay(msec);
 87    if (usec > 0) delayMicroseconds(usec);
 88
 89    digitalWrite(STEP_PIN, LOW); 
 90    if (msec > 0) delay(msec);
 91    if (usec > 0) delayMicroseconds(usec);
 92  }
 93}
 94// ================================================================================
 95// Run one iteration of the main event loop.  The Arduino system will call this
 96// function over and over forever.
 97void loop(void)
 98{
 99  // Begin the motion sequence with a few back-and-forth movements at faster and faster speeds.
100  rotate_stepper(  10,   10.0);
101  rotate_stepper( -10,   10.0);
102  rotate_stepper(  20,   20.0);
103  rotate_stepper( -20,   20.0);
104  rotate_stepper(  50,   50.0);
105  rotate_stepper( -50,   50.0);
106  rotate_stepper( 100,  100.0);
107  rotate_stepper(-100,  100.0);
108  rotate_stepper( 100,  200.0);
109  rotate_stepper(-100,  200.0);
110  rotate_stepper( 100,  400.0);
111  rotate_stepper(-100,  400.0);
112
113  // Now demonstrate that the stepper can freely rotate.
114  rotate_stepper(1000, 250.0);
115  rotate_stepper(-1000, 250.0);
116
117  // Now begin a simple back and forth motion with speed controlled by the analog input.
118  while (1) {
119    // Read the current value of the potentiometer input from analog input 0.
120    int an0 = analogRead(0);
121
122    // Map the input to a useful speed range.
123    int speed = map(an0, 0, 1023, 100, 400);
124
125    // Sweep back and forth one cycle.
126    rotate_stepper( 100, speed);
127    rotate_stepper(-100, speed);
128  }
129}
130
131/****************************************************************/