// Stepper motor on Wokwi!
/*
Stepper Motor Control - speed control
This program drives a unipolar or bipolar stepper motor.
The motor is attached to digital pins 8 - 11 of the Arduino.
A potentiometer is connected to analog input 0.
The motor will rotate in a clockwise direction. The higher the potentiometer value,
the faster the motor speed. Because setSpeed() sets the delay between steps,
you may notice the motor is less responsive to changes in the sensor value at
low speeds.
Created 30 Nov. 2009
Modified 28 Oct 2010
by Tom Igoe
*/
#include <Stepper.h>
const int stepsPerRevolution = 200; // change this to fit the number of steps per revolution
// initialize the Stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);
long stepCount = 0; // number of steps the motor has taken
int motorSpeed = 0;
long stepInterval = -1;
const long TopRpm = 60; // rev/min
const long RampTime = 2*1000000UL; // us
long accelInterval = RampTime*60/stepsPerRevolution/TopRpm; // us
long TopStepsPerSec = (TopRpm*stepsPerRevolution)/60;
void setup() {
// nothing to do inside the setup
Serial.begin(115200);
myStepper.setSpeed(TopStepsPerSec * 2); // allow faster than expected fo control by stepInterval
Serial.print("TopStepsPerSec:");
Serial.print(TopStepsPerSec);
Serial.print(" accelInterval:");
Serial.print(accelInterval);
Serial.println();
}
void loop() {
// read the sensor value:
int sensorReading = analogRead(A0);
// map it to a range from 0 to 100:
int targetMotorSpeed = map(sensorReading, 0, 1023, 0, TopStepsPerSec);
adjustSpeed(targetMotorSpeed);
stepAsNeeded();
}
void adjustSpeed(int targetStepsPerSec) {
static unsigned long last = 0;
unsigned long now = micros();
const unsigned long interval = accelInterval;
int delta = 0;
if (now - last >= interval) {
last = now;
if (targetStepsPerSec > motorSpeed) {
delta = 1;
} else if (targetStepsPerSec < motorSpeed) {
delta = -1;
}
if (delta != 0) {
motorSpeed += delta;
if (motorSpeed <= 0) {
motorSpeed = 0;
stepInterval = -1;
} else {
stepInterval = 1000000L / motorSpeed;
}
Serial.print(".");
Serial.print(motorSpeed);
}
}
}
int stepAsNeeded(void) {
static unsigned long last = 0;
unsigned long now = micros();
if (stepInterval < 0 ) return;
if (now - last >= stepInterval) {
last = now;
myStepper.step(1);
stepCount++;
}
}