const int stepPin = 2;//only works on this pin right now
const int dirPin = 3;
const int actPin = 4;//not used
const float motorAngle = 1.8;
const float stepSize = 0.03125;//full=1, half=0.5, quarter=0.25, etc...
void stepperRotate(float rotation, float rpm);
void setup()
{
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
Serial.begin(9600);
}
void loop()
{
// simple rotation forward then backward:
stepperRotate(1, 100);//rotations, RPM
delay(1000);
stepperRotate(-1, 100);//rotations, RPM
delay(1000);
// acceleration
for (int i = 200; i <= 500; i = i + 10)
{
stepperRotate(1, i); //rotations, RPM
}
//decelerate
for (int i = 500; i >= 200; i = i - 10)
{
stepperRotate(1, i); //rotations, RPM
}
}
void stepperRotate(float rotation, float rpm)
{
if (rotation > 0)
{
digitalWrite(dirPin, HIGH);
}
else {
digitalWrite(dirPin, LOW);
rotation = rotation * -1;
}
// first figure out how many steps in one rotation, so a motor with 1.8deg per step, equals 360/1.8 = 200 steps/rotation
// then if you're doing half step, that will double, so divide by 0.5, gives 400steps per rotation
float stepsPerRotation = (360.00 / motorAngle) / stepSize;
//now we have the steps per rotation, multiply by the rotations for this command to get total steps
float totalSteps = rotation * stepsPerRotation;
//Serial.println(totalSteps); // debug
//tricky part here - what is the ON/OFF time of the step pin to get the desired RPM?
// First, what is the seconds per revolution? then we can figure out seconds per step
// RPM (rotation per minute) needs to be converted to MPR, so 1/RPM, then seconds per rotation is 60seconds/RPM
// that gives us Seconds per Rotation, but how many seconds per step? well, we just divide that by the number of steps per rotation
// so now we're at 60/RPM/stepsPerRotation
// this is seconds, but we're going to use microSeconds, so let's multiply by 1 Million (1E6)
// then, we want a 50% duty cycle, half time ON, half time OFF, so divide this value by 2, then we end up with:
unsigned long stepPeriodmicroSec = ((60.0000 / (rpm * stepsPerRotation)) * 1E6 / 2.0000) - 5;
//what's up with the -5 at the end? well, in the for loop, we have to compensate for the i++ and i<x check, so 5us is subracted to speed it up a little
for (unsigned long i = 0; i < totalSteps; i++) {
PORTD |= (1 << 2);
delayMicroseconds(stepPeriodmicroSec);
PORTD &= ~(1 << 2);
delayMicroseconds(stepPeriodmicroSec);
}
}
#include <Stepper.h>
const double step_mode = .125; // 1: full step, 0.5: half step, 0.125: one-eigth step
const double motor_deg = 1.8; // number of degrees in one step
const double spr = 360/motor_deg/step_mode; // spr: (steps / revolution)
const double wheel_diameter = 3.54331; // radius in inches
const double dpr = PI*wheel_diameter; // dpr: (distance in inches / revolution);
const double rpm1 = 60;
const double rpm2 = 120;
Stepper left_stepper(spr, 2, 3); //stepper(spr, dir, step)
Stepper right_stepper(spr, 9, 8);
unsigned long stepPeriodmicroSec = ((60.0000 / (rpm1 * spr)) * 1E6 / 2.0000) - 5; //used to get RPM
unsigned long stepPeriodmicroSec2 = ((60.0000 / (rpm2 * spr)) * 1E6 / 2.0000) - 5; //used to get RPM
void setup()
{
}
void loop()
{
for(int x=0; x<=3200; x++) //rpm is only set to whichever stepPeriodmicroSec is higher
{
PORTD |= (1 << PD2);
delayMicroseconds(stepPeriodmicroSec);
PORTD &= ~(1 << PD2);
delayMicroseconds(stepPeriodmicroSec);
PORTB |= (1 << PB0);
delayMicroseconds(stepPeriodmicroSec2);
PORTB &= ~(1 << PB0);
delayMicroseconds(stepPeriodmicroSec2);
}
delay(1000);
}
The first code is an example from a video to control only 1 stepper motor. I tried to manipulate (snippet of it in second code) it to run 2 motors with different set rpms. In my for loop, it only runs both at the rpm of whichever is the lower set rpm. Using separate for loops with the integrated Blinkwithoutdelay example runs both at whichever is the higher rpm as seen in the 3rd example
#include <Stepper.h> //used to decrlare stepper objects and .step() function
const double step_mode = .125; // 1: full step, 0.5: half step, 0.125: one-eigth step
const double motor_deg = 1.8; // number of degrees in one step
const double spr = 360/motor_deg/step_mode; // spr: (steps / revolution)
const double wheel_diameter = 3.54331; // radius in inches
const double dpr = PI*wheel_diameter; // dpr: (distance in inches / revolution);
const double rpm1 = 120;
const double rpm2 = 200;
Stepper left_stepper(spr, 2, 3); //stepper(spr, dir, step)
Stepper right_stepper(spr, 9, 8);
unsigned long stepPeriodmicroSec = ((60.0000 / (rpm1 * spr)) * 1E6 / 2.0000) - 5; //used to get RPM
unsigned long stepPeriodmicroSec2 = ((60.0000 / (rpm2 * spr)) * 1E6 / 2.0000) - 5; //used to get RPM
unsigned long previousMillis1 = 0;
unsigned long previousMillis2 = 0;
const long interval_left_stepper = 1; // interval at which to blink (milliseconds)
const long interval_right_stepper = 1; // interval at which to blink (milliseconds)
void setup() {
}
void loop() {
unsigned long currentMillis1 = millis();
unsigned long currentMillis2 = millis();
if (currentMillis - previousMillis >= interval_left_stepper)
{
previousMillis1 = currentMillis1;
PORTD |= (1 << PD2);
delayMicroseconds(stepPeriodmicroSec);
PORTD &= ~(1 << PD2);
delayMicroseconds(stepPeriodmicroSec);
}
if (currentMillis - previousMillis >= interval_right_stepper)
{
previousMillis2 = currentMillis2;
PORTB |= (1 << PB0);
delayMicroseconds(stepPeriodmicroSec2);
PORTB &= ~(1 << PB0);
delayMicroseconds(stepPeriodmicroSec2);
}
}