Stepper Motors

Stepper motors are the third option for generating rotational movement. They produce finely-stepped incremental rotations, typically 1.5º or less per step, which means if you count the number of steps to move, you can determine with reasonable accuracy just how much the output shaft has turned.

This is the type of motor used in almost all 3D printers today.

There are caveats: since steppers do not have position feedback, they may over/undershoot, especially when the load on the stepper is too great, or when inertia on a large flywheel stops it from braking properly. As such use steppers with this in mind, or implement some way to ‘reset’ the position – this is often called ‘homing’.

Speaking further into the foundation of stepper motor control will be beyond the scope of this studio. I suggest using the stepper in our studio as a very simple way of building slow-rotating contraptions that can spin in either direction.

Learn basics about stepper motors here.

For more general information on steppers refer to the Curated Links page.

In this recipe, designed specifically for the Photon, take extra caution with the power supplies. We need 12V to power the stepper circuit – a 8xAA battery pack will do, or better yet, get a wall-wart transformer to supply the 12V from the wall outlet. You NEVER want to connect this 12V into your Photon’s VIN/3V3, you will instantly destroy your Photon.

The same rules apply – check twice before testing your circuit.

In this example we are using a single pushbutton to trigger the stepper motor. The code is kept simple – each time the button is pushed, it calculates a randomised point from which to rotate the stepper position to.

Consider how this can be driven by external data, instead of the button push.

Don’t have buttons? Just two wires touching each other can simulate a button ‘press’, with the right code written for them. This should also give you some ideas on making your own simple ‘button’ sensors!


Libraries Used

(learn how to import them in the Build IDE):


Code

 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
// This #include statement was automatically added by the Particle IDE.
#include <AccelStepper.h>

// how long (ms) between each sensor update? feel free to
// change this value from 5 to 5000; use 10 as a start
// if you are logging via Particle.publish, this must not be anything less than 1000ms!
#define INTERVAL_BETWEEN_SENSE   10

// initialise the timer
Timer dataUpdateTimer(INTERVAL_BETWEEN_SENSE, doDataUpdate);

// Define a stepper and the pins it will use
AccelStepper stepper(AccelStepper::DRIVER, D4, D3);   // EasyDriver connected to D4 (step), D3 (dir)

// code in this setup function runs just once, when Photon is powered up or reset
void setup() {
    Serial.begin(9600);             // Open a connection via the Serial port – useful for debugging
    delay(5000);                    // Common practice to allow board to 'settle' after connecting online

    pinMode(D3, OUTPUT);            // goes to IN1 of DRV8871 controller
    pinMode(D4, OUTPUT);            // goes to IN2 of DRV8871 controller

    // we're also connecting a pushbutton to D0 to 'trigger' a randomised stepper movement
    pinMode(D0, INPUT_PULLDOWN);

    dataUpdateTimer.start();        // start our dataUpdateTimer
}

// code in this loop function runs forever, until you cut power!
void loop() {
    stepper.run();      // we need to run this in loop to 'update' the stepper's position constantly
}

// doDataUpdate runs every interval as set by INTERVAL_BETWEEN_SENSE
void doDataUpdate() {
    int D0State = digitalRead(D0);       // read state of button

    if(D0State==HIGH) {
     stepper.moveTo(rand() % 200);
     stepper.setMaxSpeed((rand() % 200) + 1);
     stepper.setAcceleration((rand() % 200) + 1);
    }

    // form a human-readable output for viewing via the Serial port
    String output = "steps to go:" + String(stepper.distanceToGo());

    // prints this out the Serial port (coolterm) for us humans
    Serial.println(output);

}