Arduino Motor Shield Rev 3 Microstepping

I've searched the forum as well as the Arduino libraries but I haven't found an answer to this question: Is it possible to microstep a stepper motor using the Arduino Motor Shield Rev 3? If so, is there a library available that already implements this function? Thanks!

Charles

With the MobaTools library you can do halfstep.

What stepper motor are you using? Please post a data sheet.

The L298 based motor driver is not an appropriate driver for modern bipolar stepper motors. The L298 is an ancient and inefficient crappy DC motor driver and worse stepper driver.

Use a modern driver that does coil current control. Like A4988, DRV8825 and many more. Pololu has a good line of stepper drivers.

In the Prootooner V3 shield micto stepping is hard coded by straps on the board if I remember correctly.

After much frustration, I've finally programmed the Rev 3 motor shield to microstep at 16 microsteps per step. The clock drive mechanics calls for one full step every 1.2 seconds, or 75 mS per microstep. I use the TimerOne library to generate an interrupt every 75 mS. The interrupt service routine then writes values from a table to DIRA, DIRB, PWMA, and PWMB.

The control pad has buttons for 8X speed forward and backward, plus 2X speed forward and a Pause button. The speed is changed by dividing the interrupt interval (75 mS) by either 2 or 8. The Pause button disables the stepper drivers and allows manual adjustment of the RA.

Here's the code:

/*
 * Sketch to run a stepper-motor-based telescope clock drive. Uses the Arduino motor shield Rev 3.
 */
 
#include "TimerOne.h"

// Define number of steps per revolution:
const int stepsPerRevolution = 200;

// Give the motor control pins names:
#define pwmA 3
#define pwmB 11
#define brakeA 9
#define brakeB 8
#define dirA 12
#define dirB 13

// Give the control button inputs names:
#define X8slow 0
#define X8fast 1
#define X2fast 4
#define RApause 2

// Other defines:
#define baudRate 9600   //UART baud rate
#define baseRate 75000 // 1.2s/step; 75ms/micro-step
#define mainGearT 60; // Main gear = 60 teeth
#define driverGearT 24; // Driver gear = 24 teeth

// Main gear rate = 10 minutes per revoluion => 600 s/rev
// Driver gear rate = 24/60 * 600 s/rev = 240 s/rev
// Stepper rate = 240/200 = 1.2 s/step
//

// Global variables
int stepTableIndex = 0;
int stepTableIncrement = 1;
long int stepRate = baseRate;
int pauseState = 0;

#define stepTableModulus 64

int stepTable [stepTableModulus][4] = // DIRA, DIRB, ENA, ENB
{
{ 0, 0, 255, 255 }, // step 1
{ 0, 0, 250, 255 },
{ 0, 0, 236, 255 },
{ 0, 0, 212, 255 },
{ 0, 0, 180, 255 },
{ 0, 0, 142, 255 },
{ 0, 0,  98, 255 },
{ 0, 0,  50, 255 },
{ 0, 0,   0, 255 },
{ 1, 0,  50, 255 },
{ 1, 0,  98, 255 },
{ 1, 0, 142, 255 },
{ 1, 0, 180, 255 },
{ 1, 0, 212, 255 },
{ 1, 0, 236, 255 },
{ 1, 0, 250, 255 },
{ 1, 0, 255, 255 }, // step 2
{ 1, 0, 255, 250 },
{ 1, 0, 255, 236 },
{ 1, 0, 255, 212 },
{ 1, 0, 255, 180 },
{ 1, 0, 255, 142 },
{ 1, 0, 255,  98 },
{ 1, 0, 255,  50 },
{ 1, 0, 255,   0 },
{ 1, 1, 255,  50 },
{ 1, 1, 255,  98 },
{ 1, 1, 255, 142 },
{ 1, 1, 255, 180 },
{ 1, 1, 255, 212 },
{ 1, 1, 255, 236 },
{ 1, 1, 255, 250 },
{ 1, 1, 255, 255 }, // step 3
{ 1, 1, 250, 255 },
{ 1, 1, 236, 255 },
{ 1, 1, 212, 255 },
{ 1, 1, 180, 255 },
{ 1, 1, 142, 255 },
{ 1, 1,  98, 255 },
{ 1, 1,  50, 255 },
{ 1, 1,   0, 255 },
{ 0, 1,  50, 255 },
{ 0, 1,  98, 255 },
{ 0, 1, 142, 255 },
{ 0, 1, 180, 255 },
{ 0, 1, 212, 255 },
{ 0, 1, 236, 255 },
{ 0, 1, 250, 255 },
{ 0, 1, 255, 255 }, // step 4
{ 0, 1, 255, 250 },
{ 0, 1, 255, 236 },
{ 0, 1, 255, 212 },
{ 0, 1, 255, 180 },
{ 0, 1, 255, 142 },
{ 0, 1, 255,  98 },
{ 0, 1, 255,  50 },
{ 0, 1, 255,   0 },
{ 0, 0, 255,  50 },
{ 0, 0, 255,  98 },
{ 0, 0, 255, 142 },
{ 0, 0, 255, 180 },
{ 0, 0, 255, 212 },
{ 0, 0, 255, 236 },
{ 0, 0, 255, 250 }
};

void setup() {
  pinMode(pwmA, OUTPUT);
  pinMode(pwmB, OUTPUT);
  pinMode(brakeA, OUTPUT);
  pinMode(brakeB, OUTPUT);
  pinMode(dirA, OUTPUT);
  pinMode(dirB, OUTPUT);

  digitalWrite(dirA,   stepTable[stepTableIndex][0]);
  digitalWrite(dirB,   stepTable[stepTableIndex][1]);
  analogWrite(pwmA,    stepTable[stepTableIndex][2]);
  analogWrite(pwmB,    stepTable[stepTableIndex][3]);


  // Set up the control button inputs
  pinMode(X8slow,  INPUT_PULLUP);
  pinMode(X8fast,  INPUT_PULLUP);
  pinMode(X2fast,  INPUT_PULLUP);
  pinMode(RApause, INPUT_PULLUP);

  Timer1.initialize(baseRate); // 1.2s per step
  Timer1.attachInterrupt(interruptService);
}

void interruptService()
{
  Timer1.initialize(stepRate);
  digitalWrite(dirA,   stepTable[stepTableIndex][0]);
  digitalWrite(dirB,   stepTable[stepTableIndex][1]);
  if (pauseState) //Disable the stepper driver
  {
    digitalWrite(pwmA,LOW);
    digitalWrite(pwmB,LOW);
  }
  else //Write analog values to enables
  {  analogWrite (pwmA,   stepTable[stepTableIndex][2]);
     analogWrite (pwmB,   stepTable[stepTableIndex][3]); 
  }
  stepTableIndex += stepTableIncrement;
  stepTableIndex = (stepTableIndex + stepTableModulus) % stepTableModulus;   
}

void loop() {
  int X8fastState = HIGH;
  int X8slowState = HIGH;
  int X2fastState = HIGH;
  int RApauseState = HIGH;
  
  // Check the state of the pushbuttons:
  X8fastState = !digitalRead(X8fast);
  X8slowState = !digitalRead(X8slow);
  X2fastState = !digitalRead(X2fast);
  RApauseState = !digitalRead(RApause);

  // Adjust step rate and increment based on button states:
  if (X8fastState)         {stepRate = baseRate/8; stepTableIncrement = 1;}
  else if (X8slowState)    {stepRate = baseRate/8; stepTableIncrement = -1;}
  else if (X2fastState)    {stepRate = baseRate/2; stepTableIncrement = 1;}
  else if (RApauseState)   {pauseState = 1; stepTableIncrement = 0;}
  else {stepRate = baseRate; stepTableIncrement = 1; pauseState = 0;}
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.