// stepper_ramping.ino https://wokwi.com/projects/387364837545165825
// built for https://forum.arduino.cc/t/ramp-up-to-speed-for-steppers/1212952
// Hardware copied from https://docs.wokwi.com/parts/wokwi-a4988 example:
// or https://wokwi.com/projects/327823888123691604
// no-code example is in the noCode.txt tab, rename the tabs to experiment with it
// defins pins numbers
const int potmeterPin = A0;
const int stepPin = A2;
const int dirPin = 2;
const int enPin = 8;
// stepper constants
const float accelStepsPerSec2 = (300.0 * 200 / 60 / 2); // Xrpm*200steps/rev/(60s/min)/Ysec ramp
const unsigned long accelInterval = 1000000UL / accelStepsPerSec2;
const long maxStepsPerSec = 300L*200/60; // RPM*steps/secs, 43000 max
const int scale = 1; // slows things down scale:1
// stepper timing variables
int p; // Pot reading
long topSpeed = (300L * 200) / 60; // steps/sec = Rev/min*steps/rev /(sec/min)
unsigned long stepperSpeed = 0; // steps/sec
unsigned long target_speed = 0; // steps/sec
float delay_time = 1e9; // time between steps
unsigned long stepCount = 0;
void setup() {
Serial.begin(115200);
// sets the two pins as Outputs
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
pinMode(enPin, OUTPUT);
digitalWrite(enPin, LOW);
// Set 500Dir to home switch
digitalWrite(dirPin, LOW); //enables te motor to move in a particular direction
}
void loop() {
static int lastP = -1;
unsigned long now = millis();
static unsigned long lastUI = 0;
if (now - lastUI >= 100) { // throttle UI updates
p = analogRead(potmeterPin);
lastUI = now;
if (p != lastP) { // cal
lastP = p;
target_speed = map(p, 0, 1023, 0, maxStepsPerSec); // steps per sec
}
report(); // output stats
}
if (target_speed != stepperSpeed) {
adjustSpeed(target_speed);
}
if(stepAsNeeded(delay_time)) ++stepCount ;
}
void adjustSpeed(unsigned long targetStepsPerSec) {
static unsigned long last = 0;
unsigned long now = micros();
const unsigned long interval = accelInterval;
if (now - last >= interval) {
last = now;
if (targetStepsPerSec > stepperSpeed) {
++stepperSpeed;
} else if (targetStepsPerSec < stepperSpeed) {
--stepperSpeed;
}
if (stepperSpeed > 0) {
delay_time = scale * 1000000UL / stepperSpeed;
}
else {
delay_time = 1e9;
}
}
}
int stepAsNeeded(long stepInterval) {
static unsigned long last = 0;
unsigned long now = micros();
bool retval = false;
if (stepInterval < 0 ) return retval; // turn off with negative
if ((signed long) (now - last) >= stepInterval) {
// last = now;
last += stepInterval;
digitalWrite(stepPin, HIGH);
retval = true;
digitalWrite(stepPin, LOW);
}
return retval;
}
void report(void) {
const int interval = 1000;
static unsigned long last = -interval;
unsigned long now = millis();
if (now - last >= interval) {
last += interval;
Serial.print(" target:");
Serial.print(target_speed*1.0/scale);
Serial.print(" ramped:");
Serial.print(stepperSpeed*1.0/scale);
Serial.print(" us:");
Serial.print(delay_time,0);
// Serial.print(" freq:");
// Serial.print(1000000UL / delay_time,3);
// Serial.print(" StepPhasefreq:");
// Serial.print(1000000UL / delay_time / 4,3);
// Serial.print(" N:");
// Serial.print(stepCount);
// stepCount = 0;
Serial.print(" RPM:");
Serial.print(1e6/delay_time*60/200,3);
Serial.println();
}
}