The goal is that when pin 8 is connected to ground, a stepper motor will accelerate up to 4400 steps per second and stay at that speed. The code below will compile, but does not cause the motor to turn. Using stepper.setAcceleration(XXX) also does not work.
What am I missing?
Thank you.
#include <AccelStepper.h>
#define STEP 4
#define DIR 3
#define TYPE 1 // motor interface type is 1 when using a driver chip
AccelStepper stepper = AccelStepper(TYPE, STEP, DIR);
int i;
void setup()
{
pinMode(2, OUTPUT);
pinMode(8, INPUT_PULLUP);
pinMode(13, OUTPUT);
stepper.setMaxSpeed(44000);
}
void controlMotor(int state)
{
digitalWrite(13, state);
}
void loop() {
int state = HIGH;
if (digitalRead(8) == LOW) {
for (int i = 0; i = 4; i++) {
stepper.setSpeed(i * 1100);
stepper.runSpeed();
delay(500);
}
stepper.setSpeed(4400);
stepper.runSpeed();
state = LOW;
controlMotor(state);
}
}
Thank you for the code. It accelerates the motor up to speed, then slows to a near stop and repeats. The motor does not ever stay at a constant speed. The cycle of speeding up and slowing down takes 2 seconds.
Thank you for your help. The code does not cause the motor to rotate. I added a serial monitor as you can see below. The result is the serial monitor displays "2345234523452345" for as long as the switch that grounds pin 8 is "on". The next number is generated every 1/2 second. As soon as the switch is turned off, serial monitor will display the pattern until it reaches 5, then it will stop.
void loop() {
if (digitalRead(8) == LOW) {
controlMotor(HIGH);
while (i < 5)
{
stepper.setSpeed(i * 1100);
stepper.runSpeed();
if (millis() - previousMillis >= 500)
{
previousMillis = millis();
i++;
Serial.print(i);
}
}
stepper.setSpeed(4400);
stepper.runSpeed();
controlMotor(LOW);
}
i = 1;
}
Try to understand how Accelstepper works and look at the class reference.
The methods run() and runSpeed() execute at max one step ( if a step is due ). These methods have to be called as frequently as possible. If no step is due ( reagarding time and speed ) they do nothing.
But you must decide if you want to use run() or runSpeed().
runSpeed() turns the motor with the speed set by setSpeed without any positional limitation, but it does no acceleration. If you want to change the speed, only use setSpeed() and call runSpeed() independently of that as frequently as possible.
run() implements acceleration, but it stops at the target posiiton ( set with moveTo(targetpos) ).
You can set the target position to a very high value ( its a 'long' variable ), so the motor rotates for a very long time.
That's fairly useless. run() tries to accelerate until this speed is reached. But on an AVR it is impossible to reach that speed.
EDIT: I tested using Wokwi and the logic is correct.
One problem you have is that you are using the STATE of the input to control the run state rather than the CHANGE in state of the input. Consider the code below. I could not test it but you should be able to understand what it does:
#include <AccelStepper.h>
#define STEP 4
#define DIR 3
#define TYPE 1 // motor interface type is 1 when using a driver chip
AccelStepper stepper = AccelStepper(TYPE, STEP, DIR);
bool runState = false;
float runSpeed;
void setup()
{
pinMode(2, OUTPUT);
pinMode(8, INPUT_PULLUP);
pinMode(13, OUTPUT);
stepper.setMaxSpeed(44000);
}
void controlMotor(int state)
{
digitalWrite(13, state);
}
void loop()
{
static unsigned long previousMillis = millis();
static int lastInputState = digitalRead(8);
int inputState = digitalRead(8);
// Check to see if input has changed states
if (inputState != lastInputState)
{
delay(10); // debounce
lastInputState = inputState;
if (inputState == LOW)
{
// Input is activated. Setup to control motor.
runState = true;
runSpeed = 1100.0;
previousMillis = millis();
controlMotor(HIGH);
stepper.setSpeed(runSpeed); // Initial motor speed
}
else
{
// Input has been deactivated. Stop motor.
stepper.setSpeed(0.0);
runState = false;
controlMotor(LOW);
}
}
if (runState)
{
// Run state. The motor speed will increase every 500ms until it reaches max and then
// remain there until runtState is false.
if (runSpeed < 4399 && (millis() - previousMillis >= 500))
{
// Run speed has not reached max. Increment run speed.
previousMillis = millis();
runSpeed += 1100.0;
stepper.setSpeed(runSpeed);
}
// Step the motor if it is time
stepper.runSpeed();
}
}