Question on Using the Sparkfun Prodriver Stepper Motor Driver

Currently I am using a DRV8825 stepper motor driver with a Teensy 4.1 which is working well and now am converting over to the Sparkfun Prodriver with the TC78H670FTG and have a couple of questions.

  1. Setting Vref? On the DRV8825 I set have to set vref but I did not see anything in the hook up guide on how to do this. However looking at the datasheet it looks like Current = 1.1 x Vref, so Vref = Current / 1.1. Assuming that for a 1amp per coil stepper that vref should be about 0.91. Measure vref on the board is showing about 0.93 volts which seems a bit high. Measurement is done just 12v applied to the barrel jack. So can I just adjust this with the pot?
  2. While libraries are nice and convenient it hard to learn whats under the hood you might say so I rolled my own. Can I use the board without using your library? Are there any gotcha’s I need to know?
  3. How do you control speed? or moveto position etc

Thanks in advance
Mike

  1. Yep, see here SparkFun ProDriver and Mini Stepper Motor Driver Hookup Guide - SparkFun Learn (scroll WAY down, ~80%)…there’s a Vref pin as well :smiley:

  2. Certainly, though we don’t have much advice…you can fork our library and do whatever :smiley: GitHub - sparkfun/SparkFun_ProDriver_TC78H670FTG: Breakout board for the Toshiba TC78H670FTG: a Clock-in and Serial controlled Bipolar Stepping Motor Driver

  3. Via code…check out the examples (further in the guide above, right side has sections)

@TS-Russell
Sorry for getting back to you but started playing with making the mods and came up with a easy way to do that seems to work. To control the stepper basically just do

 for(int x = 0; x < total_revs; x++) {
      _time = micros();
      digitalWriteFast(myProDriver.settings.mode2Pin, HIGH);
      delayMicroseconds(pulseWidth);
      digitalWriteFast(myProDriver.settings.mode2Pin, LOW);
      delayMicroseconds(pulseWidth);
    }

Since I am using a Teensy 4 (should work with a Teensy micromod as well probably just change pins) I am using the quadencoder library since the stepper I am using has a builtin encoder. If interested here is the whole sketch:

#include <QuadEncoder.h>
#include <SerialCommand.h>

QuadEncoder myEnc(2, 2, 3, 1, 4);

#include "SparkFun_ProDriver_TC78H670FTG_Arduino_Library.h" //Click here to get the library: http://librarymanager/All#SparkFun_ProDriver
PRODRIVER myProDriver; //Create instance of this object

SerialCommand sCmd;        // SerialCommand object
bool update = true;            // update = true to trigger one print


//PPR for my stepper
int ppr = 200;
int mpr = 4;
float revs = 1.0f;
int rpm = 1;

uint8_t dir = 1;
int pulseWidth;

void setSpeed();
void setMicrosteps();
void setDirection();
void setRevs();

uint32_t mCurPosValue;
uint32_t old_position = 0;
uint32_t dt = 0;
uint32_t _time = 0;

void setup() {
  while(!Serial && millis() < 5000){}
  Serial.begin(115200);
  
  sCmd.addCommand( "s", setSpeed );       // rpm followed by new rpm value
  sCmd.addCommand( "M", setMicrosteps );  // mpr followed by new mpr value
  sCmd.addCommand( "d", setDirection );   // dir followed by new direction value
  sCmd.addCommand( "r", setRevs );       // revs followed by new revolutions  value
  sCmd.addCommand( "m", runMove );
  sCmd.addCommand( "z", zeroCounts);
  sCmd.setDefaultHandler( default_fn );    // Handler for command that isn't matched  (says "What?")

  
  Serial.println("Encoder Test:");
  myEnc.setInitConfig();
  myEnc.EncConfig.IndexTrigger = ENABLE;  //enable to  use index counter
  //myEnc.EncConfig.INDEXTriggerMode = RISING_EDGE;
  myEnc.init();
  myEnc.indexCounter = 0;

  myProDriver.settings.standbyPin = 21;
  myProDriver.settings.enablePin = 20;
  myProDriver.settings.mode0Pin = 15;
  myProDriver.settings.mode1Pin = 14;
  myProDriver.settings.mode2Pin = 7;
  myProDriver.settings.mode3Pin = 6;
  myProDriver.settings.errorPin = 5; // (if using hardware int, choose wisely)

  //***** Configure the ProDriver's Settings *****//
  // Note, we must change settings BEFORE calling the .begin() function.
  // For this example, we will try 1/2 step resolution.
  myProDriver.settings.stepResolutionMode = PRODRIVER_STEP_RESOLUTION_1_4;

  myProDriver.begin(); // adjust custom settings before calling this
  myEnc.write(0);

}

void loop()
{
  sCmd.readSerial();
  if (update == true) {
    //Serial.printf( "ppr = %4lu   rpm = %6.1f   frq = %8.1f\n", ppr, rpm, frq );
    myEnc.write(0);
    myEnc.indexCounter = 0;
    update = false;
  }
}

void setSpeed()
{
  char *arg = sCmd.next();
  if (arg == NULL) {
    Serial.println( "No arguments" );
  }
  else {
    int temp = atoi(arg);        // char* to integer
    if (temp > 0) {            // if valid RPM
      rpm = temp;            //   set ppr
      
      //calculate steps per revolution with microstepping
      //rpm = speed;
      int TPR = ppr * mpr;
      
      // Calculates PPS (pulses per second)
      float PPS = (rpm / 60.f) * TPR;
      
      //Calculate pulse width
      pulseWidth = 1000000/PPS;
      
      Serial.printf("PPR: %d, MPR: %d, RPM: %d\n", ppr, mpr, rpm);
      Serial.printf("TPR: %d, PPS: %f, PW(us): %d\n", TPR, PPS, pulseWidth);
    }
  }
  update = true;
}

void setRevs()
{
  char *arg = sCmd.next();
  if (arg == NULL) {
    Serial.println( "No arguments" );
  }
  else {

    float temp = atof(arg);        // char* to float
    if (temp > 0) {            // if valid revolutions
      revs = temp;            //   set revs
    }
  }
  Serial.printf("Revolutions: %f\n", revs);
  update = true;
}

void setDirection()
{
  char *arg = sCmd.next();
  if (arg == NULL) {
    Serial.println( "No arguments" );
  }
  else {
    int temp = atoi(arg);        // char* to integer
    if (temp == 0 || temp == 1) {            // if valid dir
      dir = temp;            //   set direction
      pinMode(myProDriver.settings.mode3Pin, OUTPUT);
      if(dir == 0) {
        digitalWrite(myProDriver.settings.mode3Pin, HIGH);
        Serial.println("Direction CcW set");
      } else if(dir == 1) {
        digitalWrite(myProDriver.settings.mode3Pin, LOW);
         Serial.println("Direction CW set");
      } else {
        digitalWrite(myProDriver.settings.mode3Pin, LOW);
        Serial.println("Direction CW set");
      }
    }
  }
  update = true;
}

void setMicrosteps()
{
  char *arg = sCmd.next();
  if (arg == NULL) {
    Serial.println( "No arguments" );
  }
  else {
    int temp = atoi(arg);        // char* to integer
    mpr = temp;

    Serial.printf("Microsteps set to: %d\n", mpr);
    //MPR = steps;

    if(mpr == 1) {
      myProDriver.changeStepResolution(PRODRIVER_STEP_RESOLUTION_1_1);
    } else if(mpr == 2) {
      myProDriver.changeStepResolution(PRODRIVER_STEP_RESOLUTION_1_2);
    } else if(mpr == 4) {
      myProDriver.changeStepResolution(PRODRIVER_STEP_RESOLUTION_1_4);
    } else if(mpr == 8) {
      myProDriver.changeStepResolution(PRODRIVER_STEP_RESOLUTION_1_8);
    } else if(mpr == 16) {
      myProDriver.changeStepResolution(PRODRIVER_STEP_RESOLUTION_1_16);
    } else if(mpr == 32 ) {
      myProDriver.changeStepResolution(PRODRIVER_STEP_RESOLUTION_1_32);
    } else {
      myProDriver.changeStepResolution(PRODRIVER_STEP_RESOLUTION_1_4);
    }
  }
  update = true;
}
  
void runMove()
{
  char *arg = sCmd.next();
  if (arg == NULL) {
    //Serial.println( "No arguments" );
    int stepsPerRevolution = ppr * mpr;
    int total_revs = revs * stepsPerRevolution;
    Serial.printf("Moving %d steps\n", total_revs);
    myProDriver.enable();

    pinMode(myProDriver.settings.mode2Pin, OUTPUT);
    digitalWriteFast(myProDriver.settings.mode2Pin, LOW);
    delay(10);
    for(int x = 0; x < total_revs; x++) {
      _time = micros();
      digitalWriteFast(myProDriver.settings.mode2Pin, HIGH);
      delayMicroseconds(pulseWidth);
      digitalWriteFast(myProDriver.settings.mode2Pin, LOW);
      delayMicroseconds(pulseWidth);
      getPosition();
    }
    myProDriver.disable();
    myEnc.write(0);
    myEnc.indexCounter = 0;
  }
  update = true;
}

void zeroCounts()
{
  Serial.println("Counts have bee zeroed out...");
  myEnc.write(0);
  myEnc.indexCounter = 0;

  update = true;
}

// This gets set as the default handler, and gets called when no other command matches.
void default_fn( const char *command )
{
  Serial.println( "What?" );
}

void getPosition(){
  mCurPosValue = myEnc.read();
  if(mCurPosValue != old_position){
    Serial.printf("%d, %d, %d\n", micros() - _time, mCurPosValue, myEnc.indexCounter);
    }
  old_position = mCurPosValue;
}

Have to input all basic info first through the serial monitor
r 100 - tells it to turn 100 revolutions
M 4 - tell it you want 1/4 microsteps
s 200 - say to set speed at 200 rpm
m - tells stepper to move with those settings

1 Like