Revised version of the program I wrote for Arduino in my Stepper Speed Test video on YouTube.
int stepPin = 3; //Set to whatever pin will trigger steps. int dirPin = 2; //Set to the pin that tells the stepper driver if it's forward or backward. int enablePin = 4; // unsigned long rpm = 300; //Target max RPM of the stepper for this test. unsigned long stepsPerRevolution = 200; //Enter the number of steps for your motor to make a full revolution. bool forward = true; //Toggle to switch motor direction. unsigned long accelTime = 2; //Second to accelerate the motor up to the max RPM (use 0 to just start the motor at full speed) unsigned long firstStamp; //When the warmup began. unsigned long lastStamp; //Stamp from the previous toggle. unsigned long curStamp; //Stamp from the current iteration. unsigned long rampTime = accelTime * 1000000; //How long to accelerate in microseconds. bool warmup = true; //Track if we've made it through the initial acceleration stage or not. bool pinOn = false; unsigned long toggleTime; void setup() { pinMode(stepPin, OUTPUT); pinMode(dirPin, OUTPUT); pinMode(enablePin, OUTPUT); pinMode(LED_BUILTIN, OUTPUT); digitalWrite(stepPin, pinOn); //Set the step pin low. digitalWrite(dirPin, forward); //Set the direction. digitalWrite(enablePin, LOW); //Pull the enable pin low to turn on the stepper driver. firstStamp = lastStamp = micros(); //Note the start time. //Determine the number of microseconds per toggle of the step pin at the target RPM. toggleTime = 60000000; //Number of micros in one minute toggleTime /= rpm; //divid by number of times per minute to revolve toggleTime /= stepsPerRevolution; //divide by number of steps to complete a full revolution. Now we have the number of micros per step. toggleTime /= 2; //Cut in half so half the time it's on, half off. } void loop() { curStamp = micros(); //Get the timestamp for this loop. unsigned long toggleTarget = toggleTime; if (warmup){ //Still accelerating at the outset, we'll increase the toggle time proportionally. if (curStamp - firstStamp > rampTime) warmup = false; //We've amde it to the end of the speed ramp. else { //Increase the toggle time proportional to how far along the acceleration ramp we are, longer at the start, no increase at the end. unsigned long tempToggle = (rampTime - (curStamp - firstStamp)) * toggleTime / rampTime; //less and less added time to the toggle. toggleTarget += tempToggle; //Add this extra toggle delay to the motor start. } } unsigned long elapsed = curStamp - lastStamp; if (elapsed >= toggleTarget) { //Toggle the step pin. pinOn = !pinOn; digitalWrite(stepPin, pinOn); digitalWrite(LED_BUILTIN, pinOn); //Update the tracking variables. lastStamp += toggleTarget; //Advance the stamp by the amount of time that was meant to have occurred between pins. } }