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