code for stepper motor driver pololu

Hello: I'm building a program for controlling a stepper motor driver using a Pololu A4988. I need to generate a microsecond delay dependent engine speed (speedRPS), but do not understand why a variable overflowCount = holdTime_us / 65535 used in the following thread http://forum.arduino.cc/index.php?topic = 221017.0.

// A custom delay function used in the run()-method
void holdHalfCylce(double speedRPS) {
long holdTime_us = (long)(1.0 / (double) stepsInFullRound / speedRPS / 2.0 * 1E6);
int overflowCount = holdTime_us / 65535;
for (int i = 0; i < overflowCount; i++) {
delayMicroseconds(65535);
}
delayMicroseconds((unsigned int) holdTime_us);
}

Please, I would like any advice or observations about
Best Regards
Daniel :smiley:

I can't figure what is going on from the snippet you posted. It seems far too complicated for the simple business of a short interval between motor steps.

How much time (in microseconds) do you need to wait between steps?

Have you considered using the AccelStepper library?

The following demo code might help to illustrate the process of using an A4988

// testing a stepper motor with a Pololu A4988 driver board or equivalent
// on an Uno the onboard led will flash with each step
// as posted on Arduino Forum at http://forum.arduino.cc/index.php?topic=208905.0

byte directionPin = 9;
byte stepPin = 8;
int numberOfSteps = 100;
byte ledPin = 13;
int pulseWidthMicros = 20;  // microseconds
int millisbetweenSteps = 25; // milliseconds


void setup() 
{ 

  Serial.begin(9600);
  Serial.println("Starting StepperTest");
  digitalWrite(ledPin, LOW);
  
  delay(2000);

  pinMode(directionPin, OUTPUT);
  pinMode(stepPin, OUTPUT);
  pinMode(ledPin, OUTPUT);
  
 
  digitalWrite(directionPin, HIGH);
  for(int n = 0; n < numberOfSteps; n++) {
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(pulseWidthMicros);
    digitalWrite(stepPin, LOW);
    
    delay(millisbetweenSteps);
    
    digitalWrite(ledPin, !digitalRead(ledPin));
  }
  
  delay(3000);
  

  digitalWrite(directionPin, LOW);
  for(int n = 0; n < numberOfSteps; n++) {
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(pulseWidthMicros);
    digitalWrite(stepPin, LOW);
    
    delay(millisbetweenSteps);
    
    digitalWrite(ledPin, !digitalRead(ledPin));
  }
  
}

void loop() 
{ 

}

...R

Calling delayMicroseconds with large values is totally broken, I think the cut off
point is about 16000 but it does depend on whether a 16MHz or 8MHz board, note.

Suggest you don't use large delays in the first place, but use the blinkWithoutDelay
paradigm...

[ Also for this application a DDS approach is often a winner, not calculated
delays which are cumbersome and not linear in frequency domain ]

MarkT:
[ Also for this application a DDS approach is often a winner, not calculated
delays which are cumbersome and not linear in frequency domain ]

That's an interesting observation. Could you explain what you mean? If you're comparing hard-coded delay() calls in a blocking movement loop versus code that waits for millis() to reach a target value, and if the goal is to achieve the correct total number of steps in a given time interval (i.e. control the average speed) then I would have thought the latter approach would be better.

Direct Digital Synthesis means keeping track of the phase in a variable and updating
it regularly (timer interrupt).

Typically for pulse generation you'd go:

volatile long phase = 0L ;
volatile long frequency ;

void handler()   // probably a timer ISR
{
  long old_ph = phase ;
  phase += frequency ;
  if (phase < old_ph)
  {
    digitalWrite (step_pin, HIGH) ;
    delayMicroseconds(10) ;
    digitalWrite (step_pin, LOW) ;
  }
}

Thus the phase variable encodes a single cycle, so the frequency variable has
to be scaled accordingly. If you clock the handler at f Hz, then a frequency step
represents f / 2^32 Hz