Stepper motor with Spark Core

I am working on a project where I need to control a 28BYJ-48 Stepper Motor. I’ve found an arduino library (http://arduino.cc/en/Reference/Stepper) but I am not sure if I can use it on a Spark Core. Is Spark Core compatible with this library? Is there any important isseu I should know?

Thanks,

Alex

After not much work, it seems to compile… Motor Knob example working off of D0, D1, D2, D3 which should work for your unipolar motor:
http://robocraft.ru/files/datasheet/28BYJ-48.pdf

I have not physically tested this, please let us know if it works for you!

Reference circuit for Motor Knob (requires a unipolar motor):
http://arduino.cc/en/Tutorial/MotorKnob (IMPORTANT TO READ… you cannot hook that motor directly to you Digital Outputs)

You should be able to easily paste in the other examples over the Motor Knob example at the bottom of this code. All I did was put the contents of the Stepper.cpp and Stepper.h and MotorKnob.ino all in one file with a few changes to the includes and header guards.

/*
  Stepper.h - - Stepper library for Wiring/Arduino - Version 0.4
  
  Original library     (0.1) by Tom Igoe.
  Two-wire modifications   (0.2) by Sebastian Gassner
  Combination version   (0.3) by Tom Igoe and David Mellis
  Bug fix for four-wire   (0.4) by Tom Igoe, bug fix from Noah Shibley

  Drives a unipolar or bipolar stepper motor using  2 wires or 4 wires

  When wiring multiple stepper motors to a microcontroller,
  you quickly run out of output pins, with each motor requiring 4 connections. 

  By making use of the fact that at any time two of the four motor
  coils are the inverse  of the other two, the number of
  control connections can be reduced from 4 to 2. 

  A slightly modified circuit around a Darlington transistor array or an L293 H-bridge
  connects to only 2 microcontroler pins, inverts the signals received,
  and delivers the 4 (2 plus 2 inverted ones) output signals required
  for driving a stepper motor.

  The sequence of control signals for 4 control wires is as follows:

  Step C0 C1 C2 C3
     1  1  0  1  0
     2  0  1  1  0
     3  0  1  0  1
     4  1  0  0  1

  The sequence of controls signals for 2 control wires is as follows
  (columns C1 and C2 from above):

  Step C0 C1
     1  0  1
     2  1  1
     3  1  0
     4  0  0

  The circuits can be found at 
  http://www.arduino.cc/en/Tutorial/Stepper
*/

// ensure this library description is only included once
//#ifndef Stepper_h
//#define Stepper_h

// library interface description
class Stepper {
  public:
    // constructors:
    Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2);
    Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, int motor_pin_3, int motor_pin_4);

    // speed setter method:
    void setSpeed(long whatSpeed);

    // mover method:
    void step(int number_of_steps);

    int version(void);

  private:
    void stepMotor(int this_step);
    
    int direction;        // Direction of rotation
    int speed;          // Speed in RPMs
    unsigned long step_delay;    // delay between steps, in ms, based on speed
    int number_of_steps;      // total number of steps this motor can take
    int pin_count;        // whether you're driving the motor with 2 or 4 pins
    int step_number;        // which step the motor is on
    
    // motor pin numbers:
    int motor_pin_1;
    int motor_pin_2;
    int motor_pin_3;
    int motor_pin_4;
    
    long last_step_time;      // time stamp in ms of when the last step was taken
};

//#endif



/*
  Stepper.cpp - - Stepper library for Wiring/Arduino - Version 0.4
  
  Original library     (0.1) by Tom Igoe.
  Two-wire modifications   (0.2) by Sebastian Gassner
  Combination version   (0.3) by Tom Igoe and David Mellis
  Bug fix for four-wire   (0.4) by Tom Igoe, bug fix from Noah Shibley  

  Drives a unipolar or bipolar stepper motor using  2 wires or 4 wires

  When wiring multiple stepper motors to a microcontroller,
  you quickly run out of output pins, with each motor requiring 4 connections. 

  By making use of the fact that at any time two of the four motor
  coils are the inverse  of the other two, the number of
  control connections can be reduced from 4 to 2. 

  A slightly modified circuit around a Darlington transistor array or an L293 H-bridge
  connects to only 2 microcontroler pins, inverts the signals received,
  and delivers the 4 (2 plus 2 inverted ones) output signals required
  for driving a stepper motor.

  The sequence of control signals for 4 control wires is as follows:

  Step C0 C1 C2 C3
     1  1  0  1  0
     2  0  1  1  0
     3  0  1  0  1
     4  1  0  0  1

  The sequence of controls signals for 2 control wires is as follows
  (columns C1 and C2 from above):

  Step C0 C1
     1  0  1
     2  1  1
     3  1  0
     4  0  0

  The circuits can be found at 
 
http://www.arduino.cc/en/Tutorial/Stepper
 
 
 */


//#include "Arduino.h"
// https://community.spark.io/t/fix-for-include-arduino-h/953
#define ARDUINO_H
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>

//#include "Stepper.h"

/*
 * two-wire constructor.
 * Sets which wires should control the motor.
 */
Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2)
{
  this->step_number = 0;      // which step the motor is on
  this->speed = 0;        // the motor speed, in revolutions per minute
  this->direction = 0;      // motor direction
  this->last_step_time = 0;    // time stamp in ms of the last step taken
  this->number_of_steps = number_of_steps;    // total number of steps for this motor
  
  // Arduino pins for the motor control connection:
  this->motor_pin_1 = motor_pin_1;
  this->motor_pin_2 = motor_pin_2;

  // setup the pins on the microcontroller:
  pinMode(this->motor_pin_1, OUTPUT);
  pinMode(this->motor_pin_2, OUTPUT);
  
  // When there are only 2 pins, set the other two to 0:
  this->motor_pin_3 = 0;
  this->motor_pin_4 = 0;
  
  // pin_count is used by the stepMotor() method:
  this->pin_count = 2;
}


/*
 *   constructor for four-pin version
 *   Sets which wires should control the motor.
 */

Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, int motor_pin_3, int motor_pin_4)
{
  this->step_number = 0;      // which step the motor is on
  this->speed = 0;        // the motor speed, in revolutions per minute
  this->direction = 0;      // motor direction
  this->last_step_time = 0;    // time stamp in ms of the last step taken
  this->number_of_steps = number_of_steps;    // total number of steps for this motor
  
  // Arduino pins for the motor control connection:
  this->motor_pin_1 = motor_pin_1;
  this->motor_pin_2 = motor_pin_2;
  this->motor_pin_3 = motor_pin_3;
  this->motor_pin_4 = motor_pin_4;

  // setup the pins on the microcontroller:
  pinMode(this->motor_pin_1, OUTPUT);
  pinMode(this->motor_pin_2, OUTPUT);
  pinMode(this->motor_pin_3, OUTPUT);
  pinMode(this->motor_pin_4, OUTPUT);

  // pin_count is used by the stepMotor() method:  
  this->pin_count = 4;  
}

/*
  Sets the speed in revs per minute

*/
void Stepper::setSpeed(long whatSpeed)
{
  this->step_delay = 60L * 1000L / this->number_of_steps / whatSpeed;
}

/*
  Moves the motor steps_to_move steps.  If the number is negative, 
   the motor moves in the reverse direction.
 */
void Stepper::step(int steps_to_move)
{  
  int steps_left = abs(steps_to_move);  // how many steps to take
  
  // determine direction based on whether steps_to_mode is + or -:
  if (steps_to_move > 0) {this->direction = 1;}
  if (steps_to_move < 0) {this->direction = 0;}
    
    
  // decrement the number of steps, moving one step each time:
  while(steps_left > 0) {
  // move only if the appropriate delay has passed:
  if (millis() - this->last_step_time >= this->step_delay) {
      // get the timeStamp of when you stepped:
      this->last_step_time = millis();
      // increment or decrement the step number,
      // depending on direction:
      if (this->direction == 1) {
        this->step_number++;
        if (this->step_number == this->number_of_steps) {
          this->step_number = 0;
        }
      } 
      else { 
        if (this->step_number == 0) {
          this->step_number = this->number_of_steps;
        }
        this->step_number--;
      }
      // decrement the steps left:
      steps_left--;
      // step the motor to step number 0, 1, 2, or 3:
      stepMotor(this->step_number % 4);
    }
  }
}

/*
 * Moves the motor forward or backwards.
 */
void Stepper::stepMotor(int thisStep)
{
  if (this->pin_count == 2) {
    switch (thisStep) {
      case 0: /* 01 */
      digitalWrite(motor_pin_1, LOW);
      digitalWrite(motor_pin_2, HIGH);
      break;
      case 1: /* 11 */
      digitalWrite(motor_pin_1, HIGH);
      digitalWrite(motor_pin_2, HIGH);
      break;
      case 2: /* 10 */
      digitalWrite(motor_pin_1, HIGH);
      digitalWrite(motor_pin_2, LOW);
      break;
      case 3: /* 00 */
      digitalWrite(motor_pin_1, LOW);
      digitalWrite(motor_pin_2, LOW);
      break;
    } 
  }
  if (this->pin_count == 4) {
    switch (thisStep) {
      case 0:    // 1010
      digitalWrite(motor_pin_1, HIGH);
      digitalWrite(motor_pin_2, LOW);
      digitalWrite(motor_pin_3, HIGH);
      digitalWrite(motor_pin_4, LOW);
      break;
      case 1:    // 0110
      digitalWrite(motor_pin_1, LOW);
      digitalWrite(motor_pin_2, HIGH);
      digitalWrite(motor_pin_3, HIGH);
      digitalWrite(motor_pin_4, LOW);
      break;
      case 2:    //0101
      digitalWrite(motor_pin_1, LOW);
      digitalWrite(motor_pin_2, HIGH);
      digitalWrite(motor_pin_3, LOW);
      digitalWrite(motor_pin_4, HIGH);
      break;
      case 3:    //1001
      digitalWrite(motor_pin_1, HIGH);
      digitalWrite(motor_pin_2, LOW);
      digitalWrite(motor_pin_3, LOW);
      digitalWrite(motor_pin_4, HIGH);
      break;
    } 
  }
}

/*
  version() returns the version of the library:
*/
int Stepper::version(void)
{
  return 4;
}

/*
 * MotorKnob
 *
 * A stepper motor follows the turns of a potentiometer
 * (or other sensor) on analog input 0.
 *
 * http://www.arduino.cc/en/Reference/Stepper
 * This example code is in the public domain.
 */

//#include <Stepper.h>

// change this to the number of steps on your motor
#define STEPS 100

// create an instance of the stepper class, specifying
// the number of steps of the motor and the pins it's
// attached to
Stepper stepper(STEPS, D0, D1, D2, D3);

// the previous reading from the analog input
int previous = 0;

void setup()
{
  // set the speed of the motor to 30 RPMs
  stepper.setSpeed(30);
}

void loop()
{
  // get the sensor value
  int val = analogRead(A0);

  // move a number of steps equal to the change in the
  // sensor reading
  stepper.step(val - previous);

  // remember the previous value of the sensor
  previous = val;
}
3 Likes

I happened to try this just today. I too used D0-D3 and it worked.

Very important to power the control board with it’s own 5 volt supply. It appeared to be happy with the 3.3 volt signals from the Core.

2 Likes

Yes! Thanks it worked!

If your motor vibrates but does not turn, it is probably connected with the wrong sequence.
You can try which one works:

Stepper stepper(STEPS,D0,D1,D2,D3);
// Stepper stepper(STEPS,D0,D1,D3,D2);
// Stepper stepper(STEPS,D0,D2,D1,D3);
// Stepper stepper(STEPS,D0,D2,D3,D1);
// Stepper stepper(STEPS,D0,D3,D1,D2);
// Stepper stepper(STEPS,D0,D3,D2,D1);
// Stepper stepper(STEPS,D1,D0,D2,D3);
// Stepper stepper(STEPS,D1,D0,D3,D2);
// Stepper stepper(STEPS,D1,D2,D0,D3);
// Stepper stepper(STEPS,D1,D2,D3,D0);
// Stepper stepper(STEPS,D1,D3,D0,D2);
// Stepper stepper(STEPS,D1,D3,D2,D0);
// Stepper stepper(STEPS,D2,D0,D1,D3);
// Stepper stepper(STEPS,D2,D0,D3,D1);
// Stepper stepper(STEPS,D2,D1,D0,D3);
// Stepper stepper(STEPS,D2,D1,D3,D0);
// Stepper stepper(STEPS,D2,D3,D0,D1);
// Stepper stepper(STEPS,D2,D3,D1,D0);
// Stepper stepper(STEPS,D3,D0,D1,D2);
// Stepper stepper(STEPS,D3,D0,D2,D1);
// Stepper stepper(STEPS,D3,D1,D0,D2);
// Stepper stepper(STEPS,D3,D1,D2,D0);
// Stepper stepper(STEPS,D3,D2,D0,D1);
// Stepper stepper(STEPS,D3,D2,D1,D0);

2 Likes

I’m trying this out.
I hooked up my circuit according to this tutorial.


I’m using D0 - D3, as the arduino 9-12 in that diagram.

So the stepper setup looks like this.
Stepper stepper(STEPS,D3,D2,D1,D0);

Trying the code from this thread, I get nothing. No action at all.

Any ideas?

If you are not getting any humming or little oscillations on the shaft, can you make sure that your motor power supply (which needs to be separate from the :spark: core) is good. That motor comes in 12V and 5V flavors so you should check which one you have and adjust your power supply accordingly. The driver IC should be fine with 3.3V control inputs.

If it is humming or starts to turn a tiny bit and stops, you might have the phases out of order like the thread above.

Thanks @bko
ok. I got it spinning. It’s just very slow.
It’s not stuttering. It’s smooth, but the numbers don’t add to to what the adafruit info says.
They say it can do 25 rpm and that 513 steps is one full revolution.

I defined steps as 513. Set speed to 25rpm and call step(513) once per loop with a delay.

It’s rotating very slooooow.

Could this be the wrong pin setup? If the phases are out, would it spin at all?

HI @kareem613

25 rpm is 2.4 seconds per revolution. Is it slower than that?

You can always experiment with the numbers; the Adafruit site say not to micro-step it but to use single or double steps. Maybe you need to use the rpm of the motor before the 16.032 to 1 gearing, so that would be about 400 rpm.

Normally if you have it hooked up wrong it just doesn’t turn or only turns a tiny bit and stops.

Keep in mind when you call stepper.step(513); it will block for 513 steps… each of which will take (60 * 1000) / 513 / 25 = 4.67ms (aka 5ms).

Essentially if you are calling the number of steps to take that equal your set up full rotation… it should block for 2.4 seconds while it makes a full revolution. Is that what’s happening?

Jack up the RPM like @bko suggests and see what happens.

It takes it closer to 10 seconds to make a full rotation set to 25rpm.
When I set it to 500RPM, it still moves slow but appears to skip. It moves a bit, then stops inconsistent amounts each time.

I put the whole app on pastbin. I’ve tried various combination of speed and step count. It seems like whatever I do, it either goes the same speed or does that skipping thing.

I’ll try the second motor I have as well. Maybe it’s the motor itself.

Seems to be working fine for me. I took an unknown motor that I bought from a surplus store and first got it hooked up on the Arduino. I guessed based on the color of the wires in the connector that they put the coils on opposite sides of the center tap wires in the middle. I counted the number of poles by hand just feeling the cogging of the magnets (I was off by a factor of 2 here but was easily adjusted). Wired it up and it worked great.
Imgur

Then I transferred the wiring to the Spark Core Shield Shield so I didn’t have to worry about a wiring mishap. I just needed to figure out which outputs of the Core were routed to the standard Arduino pinouts. For this I looked at the schematic for the Shield Shield. I really wish this info was on the back of the Shield Shield itself @mohit

Imgur

See it in action!
https://vine.co/u/1038681799087321088

Source code:
https://github.com/technobly/Spark-Stepper

1 Like

Mine definitely doesn’t spin that fast. I’ll take another crack at it tonight and post a vid myself.
I’m guessing this has to come down to the parameters I’m using for my particular motor.

I’m personally a big fan of the A4988 stepper driver from pololu. It’s a lot easier to use too.

Yeah I believe that’s the same stepper driver used on the RAMPS v1.4 board that is used in many 3D printers, including the Zim that I have backed on kickstarter :wink: So it better be good!

@BDub I’m using the RAMPS board currently for my delta 3d printer with those drivers. Its working great; you just have to make sure you setup the current pot properly. They have a tendency to heat up.

Nice. Have you thermal taped some heat sinks to the driver chips?

@BDub, I had to. Got those from amazon: http://www.amazon.com/gp/product/B007XACV8O/ref=oh_details_o01_s02_i00?ie=UTF8&psc=1

Here’s the fastest I can get my motor to spin. Seems way too slow.

This is the same code I posted earlier in this thread. http://pastebin.com/BkHVtZNf

Any ideas? Is this a symptom of not getting the wiring to the motor right?

Looks like its working perfectly to me. If you have this motor from Adafruit:

Your motor is a 32 step motor with a 1:16 gear reduction… so 512 steps per revolution. Adafruit says it’s really 513 though because it’s not exactly 1:16 gear reduction.

Your code is attempting to turn a quarter rotation at 5RPM so it should take roughly 3 seconds (60 seconds / 5 rotations / 4 quarters)

Try setting it to 25RPM. I should be about 5 times faster than it is now, and take 3/5 seconds to make a quarter turn. If that’s still too slow, you probably need a different motor because that one can’t be made to go much faster than this on 5V.

If I set RPM to anything higher than 10 it start skipping. It’s fast enough for my needs. I just wanted to make sure I’m using it correctly. I think I’m good then. Thanks!

I should be able to reverse it with just code right? The stepper documentation says use negative steps. Still moves forward for me. Think there was an issue in the port?